Compare commits

..

1 Commits

Author SHA1 Message Date
Luke Barnard
3d56247ef3 StatusBarArea height of 50px when typing/calling
Change the height of the StatusBar (and for calls, typing) to 48px such that with the StatusAreaBox_line, they add to 50px.
2017-02-20 15:22:56 +00:00
587 changed files with 18637 additions and 26805 deletions

4
.babelrc Normal file
View File

@@ -0,0 +1,4 @@
{
"presets": ["react", "es2015", "es2016"],
"plugins": ["transform-class-properties", "transform-object-rest-spread", "transform-async-to-generator", "transform-runtime", "add-module-exports"]
}

View File

@@ -1,10 +0,0 @@
# Exclude a bunch of stuff which can make the build context a larger than it needs to be
test/
webapp/
lib/
node_modules/
electron_app/
karma-reports/
.idea/
.tmp/
config.json*

View File

@@ -1,23 +0,0 @@
# Copyright 2017 Aviral Dasgupta
#
# 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.
root = true
[*]
charset=utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

2
.github/FUNDING.yml vendored
View File

@@ -1,2 +0,0 @@
patreon: matrixdotorg
liberapay: matrixdotorg

View File

@@ -1,5 +1,3 @@
<!-- Please report security issues by email to security@matrix.org -->
<!-- This is a bug report template. By following the instructions below and <!-- This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue. the necessary data to fix your issue.
@@ -43,4 +41,4 @@ For the web app:
For the desktop app: For the desktop app:
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc? - **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
- **Version**: 1.x.y <!-- check the user settings panel if unsure --> - **Version**: 0.x.y <!-- check the user settings panel if unsure -->

View File

@@ -1,56 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
<!-- Please report security issues by email to security@matrix.org -->
<!-- This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue.
You can also preview your report before submitting it. You may remove sections
that aren't relevant to your particular case.
Text between <!-- and --> marks will be invisible in the report.
-->
### Description
Describe here the problem that you are experiencing, or the feature you are requesting.
### Steps to reproduce
- For bugs, list the steps
- that reproduce the bug
- using hyphens as bullet points
Describe how what happens differs from what you expected.
<!-- Please send us logs for your bug report. They're very important for bugs
which are hard to reproduce. To do this, create this issue then go to your
account settings and click 'Submit Debug Logs' from the Help & About tab -->
Logs being sent: yes/no
<!-- Include screenshots if possible: you can drag and drop images below. -->
### Version information
<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
- **Platform**: web (in-browser) or desktop?
For the web app:
- **Browser**: Chrome, Safari, Firefox? which version?
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
- **URL**: riot.im/develop / riot.im/app / somewhere else? If a private server, what version of riot-web?
For the desktop app:
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
- **Version**: 1.x.y <!-- check the user settings panel if unsure -->

View File

@@ -1,20 +0,0 @@
---
name: Suggestion or Feature request
about: Suggest an idea for this project
title: ''
labels: suggestion
assignees: ''
---
**Is your suggestion related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,58 +0,0 @@
---
name: User Interface or Usability Bug report
about: Please include screenshots in UI/UX bug reports
title: ''
labels: bug, ui/ux
assignees: ''
---
<!-- A picture's worth a thousand words: PLEASE INCLUDE A SCREENSHOT :P -->
<!-- Please report security issues by email to security@matrix.org -->
<!-- This is a bug report template. By following the instructions below and
filling out the sections with your information, you will help the us to get all
the necessary data to fix your issue.
You can also preview your report before submitting it. You may remove sections
that aren't relevant to your particular case.
Text between <!-- and --> marks will be invisible in the report.
-->
### Description
Describe here the problem that you are experiencing, or the feature you are requesting.
### Steps to reproduce
- For bugs, list the steps
- that reproduce the bug
- using hyphens as bullet points
Describe how what happens differs from what you expected.
<!-- Please send us logs for your bug report. They're very important for bugs
which are hard to reproduce. To do this, create this issue then go to your
account settings and click 'Submit Debug Logs' from the Help & About tab -->
Logs being sent: yes/no
<!-- Include screenshots if possible: you can drag and drop images below. -->
### Version information
<!-- IMPORTANT: please answer the following questions, to help us narrow down the problem -->
- **Platform**: web (in-browser) or desktop?
For the web app:
- **Browser**: Chrome, Safari, Firefox? which version?
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
- **URL**: riot.im/develop / riot.im/app / somewhere else? If a private server, what version of riot-web?
For the desktop app:
- **OS**: Windows, macOS, Ubuntu, Arch Linux, etc?
- **Version**: 1.x.y <!-- check the user settings panel if unsure -->

13
.gitignore vendored
View File

@@ -1,23 +1,14 @@
/build /build
/cert.pem /cert.pem
/dist /dist
/karma-reports
/key.pem /key.pem
/lib /lib
/node_modules /node_modules
/electron_app/node_modules
/electron_app/dist
/electron_app/pub
/packages/ /packages/
/webapp /webapp
/.npmrc /.npmrc
/*.log
package-lock.json
.DS_Store .DS_Store
npm-debug.log
electron/dist electron/dist
electron/pub electron/pub
**/.idea
/config.json
/config.json.*
/config.local*.json
/src/component-index.js
/.tmp

View File

@@ -5,30 +5,10 @@
"setClasses" "setClasses"
], ],
"feature-detects": [ "feature-detects": [
"test/css/animations",
"test/css/displaytable", "test/css/displaytable",
"test/css/filters",
"test/css/flexbox", "test/css/flexbox",
"test/es5/specification",
"test/css/objectfit", "test/css/objectfit",
"test/es5/date",
"test/es5/function",
"test/es5/object",
"test/es5/undefined",
"test/es6/array",
"test/es6/collections",
"test/es6/promises",
"test/es6/string",
"test/svg",
"test/svg/asimg",
"test/svg/filters",
"test/cors",
"test/iframe/sandbox",
"test/json",
"test/network/fetch",
"test/storage/localstorage" "test/storage/localstorage"
] ]
} }

View File

@@ -1,26 +0,0 @@
// Copied from react-sdk
// TODO: Only keep one copy of this for synchronization purposes
module.exports = {
"extends": "stylelint-config-standard",
"plugins": [
"stylelint-scss",
],
"rules": {
"indentation": 4,
"comment-empty-line-before": null,
"declaration-empty-line-before": null,
"length-zero-no-unit": null,
"rule-empty-line-before": null,
"color-hex-length": null,
"max-empty-lines": null,
"number-no-trailing-zeros": null,
"number-leading-zero": null,
"selector-list-comma-newline-after": null,
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"scss/at-rule-no-unknown": [true, {
// https://github.com/vector-im/riot-web/issues/10544
"ignoreAtRules": ["define-mixin"],
}],
}
};

7
.travis.yml Normal file
View File

@@ -0,0 +1,7 @@
language: node_js
node_js:
- 6 # node v6, to match jenkins
install:
- npm install
- (cd node_modules/matrix-js-sdk && npm install)
- (cd node_modules/matrix-react-sdk && npm install)

View File

@@ -10,9 +10,3 @@ include:
* Florent VIOLLEAU (https://github.com/floviolleau) <floviolleau at gmail dot com> * Florent VIOLLEAU (https://github.com/floviolleau) <floviolleau at gmail dot com>
Improve README.md for a better understanding of installation instructions Improve README.md for a better understanding of installation instructions
* Michael Telatynski (https://github.com/t3chguy)
Improved consistency of inverted elements in dark theme across browsers
* Alexandr Korsak (https://github.com/oivoodoo)
Improved multiple file uploading

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
Contributing code to Riot Contributing code to Riot
========================= =========================
Riot follows the same pattern as https://github.com/matrix-org/matrix-js-sdk/blob/master/CONTRIBUTING.rst. Riot follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.rst.

View File

@@ -1,37 +0,0 @@
# Builder
FROM node:10 as builder
# Support custom branches of the react-sdk and js-sdk. This also helps us build
# images of riot-web develop.
ARG USE_CUSTOM_SDKS=false
ARG REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git"
ARG REACT_SDK_BRANCH="master"
ARG JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git"
ARG JS_SDK_BRANCH="master"
RUN apt-get update && apt-get install -y git dos2unix
WORKDIR /src
COPY . /src
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
RUN yarn --network-timeout=100000 install
RUN yarn build
# Copy the config now so that we don't create another layer in the app image
RUN cp /src/config.sample.json /src/webapp/config.json
# Ensure we populate the version file
RUN dos2unix /src/scripts/docker-write-version.sh && bash /src/scripts/docker-write-version.sh
# App
FROM nginx:alpine
COPY --from=builder /src/webapp /app
# Insert wasm type into Nginx mime.types file so they load correctly.
RUN sed -i '3i\ \ \ \ application/wasm wasm\;' /etc/nginx/mime.types
RUN rm -rf /usr/share/nginx/html \
&& ln -s /app /usr/share/nginx/html

439
README.md
View File

@@ -1,62 +1,40 @@
Riot Riot
==== ====
Riot (formerly known as Vector) is a Matrix web client built using the [Matrix Riot (formerly known as Vector) is a Matrix web client built using the Matrix
React SDK](https://github.com/matrix-org/matrix-react-sdk). React SDK (https://github.com/matrix-org/matrix-react-sdk).
Supported Environments
======================
Riot has several tiers of support for different environments:
* Supported
* Definition: Issues **actively triaged**, regressions **block** the release
* Last 2 major versions of Chrome, Firefox, and Safari on desktop OSes
* Latest release of official Riot Desktop app on desktop OSes
* Desktop OSes means macOS, Windows, and Linux versions for desktop devices
that are actively supported by the OS vendor and receive security updates
* Experimental
* Definition: Issues **accepted**, regressions **do not block** the release
* Riot as an installed PWA via current stable version of Chrome, Firefox, and Safari
* Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
* Not supported
* Definition: Issues only affecting unsupported environments are **closed**
* Everything else
For accessing Riot on an Android or iOS device, we currently recommend the
native apps [riot-android](https://github.com/vector-im/riot-android)
and [riot-ios](https://github.com/vector-im/riot-ios).
Getting Started Getting Started
=============== ===============
The easiest way to test Riot is to just use the hosted copy at https://riot.im/app. The easiest way to test Riot is to just use the hosted copy at
The `develop` branch is continuously deployed by Jenkins at https://riot.im/develop https://riot.im/app. The develop branch is continuously deployed by Jenkins at
for those who like living dangerously. https://riot.im/develop for those who like living dangerously.
To host your own copy of Riot, the quickest bet is to use a pre-built To host your own copy of Riot, the quickest bet is to use a pre-built
released version of Riot: released version of Riot:
1. Download the latest version from https://github.com/vector-im/riot-web/releases 1. Download the latest version from https://github.com/vector-im/riot-web/releases
1. Untar the tarball on your web server 1. Untar the tarball on your web server
1. Move (or symlink) the `riot-x.x.x` directory to an appropriate name 1. Move (or symlink) the vector-x.x.x directory to an appropriate name
1. Configure the correct caching headers in your webserver (see below)
1. If desired, copy `config.sample.json` to `config.json` and edit it 1. If desired, copy `config.sample.json` to `config.json` and edit it
as desired. See the [configuration docs](docs/config.md) for details. as desired. See below for details.
1. Enter the URL into your browser and log into Riot! 1. Enter the URL into your browser and log into Riot!
Releases are signed using gpg and the OpenPGP standard, and can be checked against the public key located Releases are signed by PGP, and can be checked against the public key
at https://packages.riot.im/riot-release-key.asc. at https://riot.im/packages/keys/riot-master.asc
Note that for the security of your chats will need to serve Riot Note that Chrome does not allow microphone or webcam access for sites served
over HTTPS. Major browsers also do not allow you to use VoIP/video over http (except localhost), so for working VoIP you will need to serve Riot
chats over HTTP, as WebRTC is only usable over HTTPS. over https.
There are some exceptions like when using localhost, which is
considered a [secure context](https://developer.mozilla.org/docs/Web/Security/Secure_Contexts)
and thus allowed.
To install Riot as a desktop application, see [Running as a desktop ### Installation Steps for Debian Stretch
app](#running-as-a-desktop-app) below. 1. Add the repository to your sources.list using either of the following two options:
- Directly to sources.list: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee -a /etc/apt/sources.list`
- As a separate entry in sources.list.d: `echo "deb https://riot.im/packages/debian/ stretch main" | sudo tee /etc/apt/sources.list.d/riot.list`
2. Add the gpg signing key for the riot repository: `curl -s https://riot.im/packages/debian/repo-key.asc | sudo apt-key add -`
3. Update your package lists: `sudo apt-get update`
4. Install Riot: `sudo apt-get install riot-web`
Important Security Note Important Security Note
======================= =======================
@@ -74,54 +52,83 @@ https://github.com/vector-im/riot-web/issues/1977 for more details.
Building From Source Building From Source
==================== ====================
Riot is a modular webapp built with modern ES6 and uses a Node.js build system. Riot is a modular webapp built with modern ES6 and requires a npm build system
Ensure you have the latest LTS version of Node.js installed. to build.
Using `yarn` instead of `npm` is recommended. Please see the Yarn [install 1. Install or update `node.js` so that your `npm` is at least at version `2.0.0`
guide](https://yarnpkg.com/docs/install/) if you do not have it already. 1. Clone the repo: `git clone https://github.com/vector-im/riot-web.git`
1. Switch to the riot-web directory: `cd riot-web`
1. Install the prerequisites: `npm install`
1. If you are using the `develop` branch of vector-web, you will probably need
to rebuild some of the dependencies, due to
https://github.com/npm/npm/issues/3055:
1. Install or update `node.js` so that your `node` is at least v10.x. ```
1. Install `yarn` if not present already. (cd node_modules/matrix-js-sdk && npm install)
1. Clone the repo: `git clone https://github.com/vector-im/riot-web.git`. (cd node_modules/matrix-react-sdk && npm install)
1. Switch to the riot-web directory: `cd riot-web`. ```
1. Install the prerequisites: `yarn install`.
* If you're using the `develop` branch, then it is recommended to set up a
proper development environment (see [Setting up a dev
environment](#setting-up-a-dev-environment) below). Alternatively, you
can use https://riot.im/develop - the continuous integration release of
the develop branch.
1. Configure the app by copying `config.sample.json` to `config.json` and 1. Configure the app by copying `config.sample.json` to `config.json` and
modifying it. See the [configuration docs](docs/config.md) for details. modifying it (see below for details)
1. `yarn dist` to build a tarball to deploy. Untaring this file will give 1. `npm run dist` to build a tarball to deploy. Untaring this file will give
a version-specific directory containing all the files that need to go on your a version-specific directory containing all the files that need to go on your
web server. web server.
Note that `yarn dist` is not supported on Windows, so Windows users can run `yarn build`, Note that `npm run dist` is not supported on Windows, so Windows users can run `npm
which will build all the necessary files into the `webapp` directory. The version of Riot run build`, which will build all the necessary files into the `webapp`
will not appear in Settings without using the dist script. You can then mount the directory. The version of Riot will not appear in Settings without
`webapp` directory on your webserver to actually serve up the app, which is entirely static content. using the dist script. You can then mount the `webapp` directory on your
webserver to actually serve up the app, which is entirely static content.
config.json
===========
You can configure the app by copying `config.sample.json` to
`config.json` and customising it:
1. `default_hs_url` is the default home server url.
1. `default_is_url` is the default identity server url (this is the server used
for verifying third party identifiers like email addresses). If this is blank,
registering with an email address, adding an email address to your account,
or inviting users via email address will not work. Matrix identity servers are
very simple web services which map third party identifiers (currently only email
addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html
for more details. Currently the only public matrix identity servers are https://matrix.org
and https://vector.im. In future identity servers will be decentralised.
1. `integrations_ui_url`: URL to the web interface for the integrations server.
1. `integrations_rest_url`: URL to the REST interface for the integrations server.
1. `roomDirectory`: config for the public room directory. This section is optional.
1. `roomDirectory.servers`: List of other Home Servers' directories to include in the drop
down list. Optional.
1. `update_base_url` (electron app only): HTTPS URL to a web server to download
updates from. This should be the path to the directory containing `macos`
and `win32` (for update packages, not installer packages).
1. `cross_origin_renderer_url`: URL to a static HTML page hosting code to help display
encrypted file attachments. This MUST be hosted on a completely separate domain to
anything else since it is used to isolate the privileges of file attachments to this
domain. Default: `usercontent.riot.im`. This needs to contain v1.html from
https://github.com/matrix-org/usercontent/blob/master/v1.html
Running as a Desktop app Running as a Desktop app
======================== ========================
Riot can also be run as a desktop app, wrapped in Electron. You can download a Riot can also be run as a desktop app, wrapped in electron. You can download a
pre-built version from https://riot.im/download/desktop/ or, if you prefer, pre-built version from https://riot.im/desktop.html or, if you prefer,
build it yourself. built it yourself.
To build it yourself, follow the instructions below. To run as a desktop app:
1. Follow the instructions in 'Building From Source' above, but run 1. Follow the instructions in 'Building From Source' above
`yarn build` instead of `yarn dist` (since we don't need the tarball). 2. Install electron and run it:
2. Install Electron and run it:
```bash ```
yarn electron npm install electron
node_modules/.bin/electron .
``` ```
To build packages, use `electron-builder`. This is configured to output: To build packages, use electron-builder. This is configured to output:
* `dmg` + `zip` for macOS * dmg + zip for macOS
* `exe` + `nupkg` for Windows * exe + nupkg for Windows
* `deb` for Linux * deb for Linux
But this can be customised by editing the `build` section of package.json But this can be customised by editing the `build` section of package.json
as per https://github.com/electron-userland/electron-builder/wiki/Options as per https://github.com/electron-userland/electron-builder/wiki/Options
@@ -129,111 +136,59 @@ See https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Bu
for dependencies required for building packages for various platforms. for dependencies required for building packages for various platforms.
The only platform that can build packages for all three platforms is macOS: The only platform that can build packages for all three platforms is macOS:
```bash ```
brew install wine --without-x11
brew install mono brew install mono
yarn install brew install gnu-tar
yarn build:electron npm install
npm run build:electron
``` ```
For other packages, use `electron-builder` manually. For example, to build a For other packages, use electron-builder manually. For example, to build a package
package for 64 bit Linux: for 64 bit Linux:
1. Follow the instructions in 'Building From Source' above 1. Follow the instructions in 'Building From Source' above
2. `node_modules/.bin/build -l --x64` 2. `node_modules/.bin/build -l --x64`
All Electron packages go into `electron_app/dist/` All electron packages go into `electron/dist/`
Many thanks to @aviraldg for the initial work on the Electron integration. Many thanks to @aviraldg for the initial work on the electron integration.
Other options for running as a desktop app: Other options for running as a desktop app:
* https://github.com/krisak/vector-electron-desktop
* @asdf:matrix.org points out that you can use nativefier and it just works(tm) * @asdf:matrix.org points out that you can use nativefier and it just works(tm)
```bash ```
yarn global add nativefier sudo npm install nativefier -g
nativefier https://riot.im/app/ nativefier https://riot.im/app/
``` ```
The [configuration docs](docs/config.md#desktop-app-configuration) show how to
override the desktop app's default settings if desired.
Running from Docker
===================
The Docker image can be used to serve riot-web as a web server. The easiest way to use
it is to use the prebuilt image:
```bash
docker run -p 80:80 vectorim/riot-web
```
To supply your own custom `config.json`, map a volume to `/app/config.json`. For example,
if your custom config was located at `/etc/riot-web/config.json` then your Docker command
would be:
```bash
docker run -p 80:80 -v /etc/riot-web/config.json:/app/config.json vectorim/riot-web
```
To build the image yourself:
```bash
git clone https://github.com/vector-im/riot-web.git riot-web
cd riot-web
git checkout master
docker build -t vectorim/riot-web .
```
If you're building a custom branch, or want to use the develop branch, check out the appropriate
riot-web branch and then run:
```bash
docker build -t vectorim/riot-web:develop \
--build-arg USE_CUSTOM_SDKS=true \
--build-arg REACT_SDK_REPO="https://github.com/matrix-org/matrix-react-sdk.git" \
--build-arg REACT_SDK_BRANCH="develop" \
--build-arg JS_SDK_REPO="https://github.com/matrix-org/matrix-js-sdk.git" \
--build-arg JS_SDK_BRANCH="develop" \
.
```
config.json
===========
Riot supports a variety of settings to configure default servers, behaviour, themes, etc.
See the [configuration docs](docs/config.md) for more details.
Labs Features
=============
Some features of Riot may be enabled by flags in the `Labs` section of the settings.
Some of these features are described in [labs.md](https://github.com/vector-im/riot-web/blob/develop/docs/labs.md).
Caching requirements
====================
Riot requires the following URLs not to be cached, when/if you are serving Riot from your own webserver:
```
/config.*.json
/i18n
/home
/sites
/index.html
```
Development Development
=========== ===========
Before attempting to develop on Riot you **must** read the [developer guide Before attempting to develop on Riot you **must** read the developer guide
for `matrix-react-sdk`](https://github.com/matrix-org/matrix-react-sdk), which for `matrix-react-sdk` at https://github.com/matrix-org/matrix-react-sdk, which
also defines the design, architecture and style for Riot too. also defines the design, architecture and style for Riot too.
You should also familiarise yourself with the ["Here be Dragons" guide
](https://docs.google.com/document/d/12jYzvkidrp1h7liEuLIe6BMdU0NUjndUYI971O06ooM)
to the tame & not-so-tame dragons (gotchas) which exist in the codebase.
The idea of Riot is to be a relatively lightweight "skin" of customisations on The idea of Riot is to be a relatively lightweight "skin" of customisations on
top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the top of the underlying `matrix-react-sdk`. `matrix-react-sdk` provides both the
higher and lower level React components useful for building Matrix communication higher and lower level React components useful for building Matrix communication
apps using React. apps using React.
After creating a new component you must run `yarn reskindex` to regenerate After creating a new component you must run `npm run reskindex` to regenerate
the `component-index.js` for the app (used in future for skinning). the `component-index.js` for the app (used in future for skinning)
**However, as of July 2016 this layering abstraction is broken due to rapid
development on Riot forcing `matrix-react-sdk` to move fast at the expense of
maintaining a clear abstraction between the two.** Hacking on Riot inevitably
means hacking equally on `matrix-react-sdk`, and there are bits of
`matrix-react-sdk` behaviour incorrectly residing in the `riot-web` project
(e.g. matrix-react-sdk specific CSS), and a bunch of Riot specific behaviour
in the `matrix-react-sdk` (grep for `vector` / `riot`). This separation problem will be
solved asap once development on Riot (and thus matrix-react-sdk) has
stabilised. Until then, the two projects should basically be considered as a
single unit. In particular, `matrix-react-sdk` issues are currently filed
against `riot-web` in github.
Please note that Riot is intended to run correctly without access to the public Please note that Riot is intended to run correctly without access to the public
internet. So please don't depend on resources (JS libs, CSS, images, fonts) internet. So please don't depend on resources (JS libs, CSS, images, fonts)
@@ -250,152 +205,82 @@ having to manually rebuild each time.
First clone and build `matrix-js-sdk`: First clone and build `matrix-js-sdk`:
``` bash 1. `git clone git@github.com:matrix-org/matrix-js-sdk.git`
git clone https://github.com/matrix-org/matrix-js-sdk.git 1. `pushd matrix-js-sdk`
pushd matrix-js-sdk 1. `git checkout develop`
git checkout develop 1. `npm install`
yarn link 1. `npm install source-map-loader` # because webpack is made of fail (https://github.com/webpack/webpack/issues/1472)
yarn install 1. `popd`
popd
```
Then similarly with `matrix-react-sdk`: Then similarly with `matrix-react-sdk`:
```bash 1. `git clone git@github.com:matrix-org/matrix-react-sdk.git`
git clone https://github.com/matrix-org/matrix-react-sdk.git 1. `pushd matrix-react-sdk`
pushd matrix-react-sdk 1. `git checkout develop`
git checkout develop 1. `npm install`
yarn link 1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
yarn link matrix-js-sdk 1. `popd`
yarn install
popd
```
Finally, build and start Riot itself: Finally, build and start Riot itself:
```bash 1. `git clone git@github.com:vector-im/riot-web.git`
git clone https://github.com/vector-im/riot-web.git 1. `cd riot-web`
cd riot-web 1. `git checkout develop`
git checkout develop 1. `npm install`
yarn link matrix-js-sdk 1. `rm -r node_modules/matrix-js-sdk; ln -s ../../matrix-js-sdk node_modules/`
yarn link matrix-react-sdk 1. `rm -r node_modules/matrix-react-sdk; ln -s ../../matrix-react-sdk node_modules/`
yarn install 1. `npm start`
yarn start 1. Wait a few seconds for the initial build to finish; you should see something like:
```
Wait a few seconds for the initial build to finish; you should see something like: ```
``` Hash: b0af76309dd56d7275c8
Hash: b0af76309dd56d7275c8 Version: webpack 1.12.14
Version: webpack 1.12.14 Time: 14533ms
Time: 14533ms Asset Size Chunks Chunk Names
Asset Size Chunks Chunk Names bundle.js 4.2 MB 0 [emitted] main
bundle.js 4.2 MB 0 [emitted] main bundle.css 91.5 kB 0 [emitted] main
bundle.css 91.5 kB 0 [emitted] main bundle.js.map 5.29 MB 0 [emitted] main
bundle.js.map 5.29 MB 0 [emitted] main bundle.css.map 116 kB 0 [emitted] main
bundle.css.map 116 kB 0 [emitted] main + 1013 hidden modules
+ 1013 hidden modules ```
```
Remember, the command will not terminate since it runs the web server Remember, the command will not terminate since it runs the web server
and rebuilds source files when they change. This development server also and rebuilds source files when they change. This development server also
disables caching, so do NOT use it in production. disables caching, so do NOT use it in production.
1. Open http://127.0.0.1:8080/ in your browser to see your newly built Riot.
Configure the app by copying `config.sample.json` to `config.json` and When you make changes to `matrix-react-sdk` or `matrix-js-sdk`, you will need
modifying it. See the [configuration docs](docs/config.md) for details. to run `npm run build` in the relevant directory. You can do this automatically
by instead running `npm start` in the directory, to start a development builder
Open http://127.0.0.1:8080/ in your browser to see your newly built Riot. which will watch for changes to the files and rebuild automatically.
___
When you make changes to `matrix-react-sdk` or `matrix-js-sdk` they should be
automatically picked up by webpack and built.
If you add or remove any components from the Riot skin, you will need to rebuild If you add or remove any components from the Riot skin, you will need to rebuild
the skin's index by running, `yarn reskindex`. the skin's index by running, `npm run reskindex`.
If any of these steps error with, `file table overflow`, you are probably on a mac If any of these steps error with, `file table overflow`, you are probably on a mac
which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again. which has a very low limit on max open files. Run `ulimit -Sn 1024` and try again.
You'll need to do this in each new terminal you open before building Riot. You'll need to do this in each new terminal you open before building Riot.
Running the tests
-----------------
There are a number of application-level tests in the `tests` directory; these
are designed to run in a browser instance under the control of
[karma](https://karma-runner.github.io). To run them:
* Make sure you have Chrome installed (a recent version, like 59)
* Make sure you have `matrix-js-sdk` and `matrix-react-sdk` installed and
built, as above
* `yarn test`
The above will run the tests under Chrome in a `headless` mode.
You can also tell karma to run the tests in a loop (every time the source
changes), in an instance of Chrome on your desktop, with `yarn
test-multi`. This also gives you the option of running the tests in 'debug'
mode, which is useful for stepping through the tests in the developer tools.
### End-to-End tests
See [matrix-react-sdk](https://github.com/matrix-org/matrix-react-sdk/#end-to-end-tests) how to run the end-to-end tests.
Translations
============
To add a new translation, head to the [translating doc](docs/translating.md).
For a developer guide, see the [translating dev doc](docs/translating-dev.md).
[<img src="https://translate.riot.im/widgets/riot-web/-/multi-auto.svg" alt="translationsstatus" width="340">](https://translate.riot.im/engage/riot-web/?utm_source=widget)
Triaging issues Triaging issues
=============== ===============
Issues will be triaged by the core team using the below set of tags. Issues will be triaged by the core team using the following primary set of tags:
Tags are meant to be used in combination - e.g.: priority:
* P1 critical bug == really urgent stuff that should be next in the bugfixing todo list P1: top priority; typically blocks releases.
* "release blocker" == stuff which is blocking us from cutting the next release. P2: one below that
* P1 feature type:voip == what VoIP features should we be working on next? P3: non-urgent
P4/P5: bluesky some day, who knows.
priority: **compulsory** bug or feature:
bug severity:
* cosmetic - feature works functionally but UI/UX is broken.
* critical - whole app doesn't work
* major - entire feature doesn't work
* minor - partially broken feature (but still usable)
* P1: top priority - i.e. pool of stuff which we should be working on next * release blocker
* P2: still need to fix, but lower than P1
* P3: non-urgent
* P4: interesting idea - bluesky some day
* P5: recorded for posterity/to avoid duplicates. No intention to resolves right now.
bug or feature: **compulsory** * ui/ux (think of this as cosmetic)
* bug * network (specific to network conditions)
* feature * platform (platform specific)
bug severity: **compulsory, if bug**
* critical - whole app doesn't work
* major - entire feature doesn't work
* minor - partially broken feature (but still usable)
* cosmetic - feature works functionally but UI/UX is broken
types
* type:* - refers to a particular part of the app; used to filter bugs
on a given topic - e.g. VOIP, signup, timeline, etc.
additional categories (self-explanatory):
* release blocker
* ui/ux (think of this as cosmetic)
* network (specific to network conditions)
* platform specific
* accessibility
* maintenance
* performance
* i18n
* blocked - whether this issue currently can't be progressed due to outside factors
community engagement
* easy
* hacktoberfest
* bounty? - proposal to be included in a bounty programme
* bounty - included in Status Open Bounty

View File

@@ -1,23 +0,0 @@
module.exports = {
"sourceMaps": true,
"presets": [
["@babel/preset-env", {
"targets": [
"last 2 Chrome versions", "last 2 Firefox versions", "last 2 Safari versions"
],
}],
"@babel/preset-typescript",
"@babel/preset-flow",
"@babel/preset-react"
],
"plugins": [
["@babel/plugin-proposal-decorators", {legacy: true}],
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-flow-comments",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-runtime"
]
};

View File

@@ -1,56 +1,14 @@
{ {
"default_server_config": { "default_hs_url": "https://matrix.org",
"m.homeserver": { "default_is_url": "https://vector.im",
"base_url": "https://matrix-client.matrix.org",
"server_name": "matrix.org"
},
"m.identity_server": {
"base_url": "https://vector.im"
}
},
"disable_custom_urls": false,
"disable_guests": false,
"disable_login_language_selector": false,
"disable_3pid_login": false,
"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",
"integrations_widgets_urls": [ "bug_report_endpoint_url": "https://vector.im/bugs",
"https://scalar.vector.im/_matrix/integrations/v1", "enableLabs": true,
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"integrations_jitsi_widget_url": "https://scalar.vector.im/api/widgets/jitsi.html",
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"defaultCountryCode": "GB",
"showLabsSettings": false,
"features": {
"feature_pinning": "labs",
"feature_custom_status": "labs",
"feature_custom_tags": "labs",
"feature_state_counters": "labs"
},
"default_federate": true,
"default_theme": "light",
"roomDirectory": { "roomDirectory": {
"servers": [ "servers": [
"matrix.org" "matrix.org"
] ]
},
"welcomeUserId": "@riot-bot:matrix.org",
"piwik": {
"url": "https://piwik.riot.im/",
"whitelistedHSUrls": ["https://matrix.org"],
"whitelistedISUrls": ["https://vector.im", "https://matrix.org"],
"siteId": 1
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
},
"settingDefaults": {
"breadcrumbs": true
} }
} }

View File

@@ -1,17 +0,0 @@
{
"name": "Riot",
"description": "A glossy Matrix collaboration client for the web.",
"repository": {
"url": "https://github.com/vector-im/riot-web",
"license": "Apache License 2.0"
},
"bugs": {
"list": "https://github.com/vector-im/riot-web/issues",
"report": "https://github.com/vector-im/riot-web/issues/new/choose"
},
"keywords": [
"chat",
"riot",
"matrix"
]
}

View File

@@ -1,142 +0,0 @@
Configuration
=============
You can configure the app by copying `config.sample.json` to
`config.json` and customising it:
For a good example, see https://riot.im/develop/config.json.
1. `default_server_config` sets the default homeserver and identity server URL for
Riot to use. The object is the same as returned by [https://<server_name>/.well-known/matrix/client](https://matrix.org/docs/spec/client_server/latest.html#get-well-known-matrix-client),
with added support for a `server_name` under the `m.homeserver` section to display
a custom homeserver name. Alternatively, the config can contain a `default_server_name`
instead which is where Riot will go to get that same object, although this option is
deprecated - see the `.well-known` link above for more information on using this option.
Note that the `default_server_name` is used to get a complete server configuration
whereas the `server_name` in the `default_server_config` is for display purposes only.
* *Note*: The URLs can also be individually specified as `default_hs_url` and
`default_is_url`, however these are deprecated. They are maintained for backwards
compatibility with older configurations. `default_is_url` is respected only
if `default_hs_url` is used.
* Riot will fail to load if a mix of `default_server_config`, `default_server_name`, or
`default_hs_url` is specified. When multiple sources are specified, it is unclear
which should take priority and therefore the application cannot continue.
* As of Riot 1.4.0, identity servers are optional. See [Identity servers](#identity-servers) below.
1. `features`: Lookup of optional features that may be `enable`d, `disable`d, or
exposed to the user in the `labs` section of settings. The available
optional experimental features vary from release to release and are [documented](labs.md). The feature flag process is
[documented](feature-flags.md) as well.
1. `showLabsSettings`: Shows the "labs" tab of user settings even when no `features` are enabled
or present. Useful for getting at settings which may be otherwise hidden.
1. `brand`: String to pass to your homeserver when configuring email notifications, to let the
homeserver know what email template to use when talking to you.
1. `branding`: Configures various branding and logo details, such as:
1. `welcomeBackgroundUrl`: An image to use as a wallpaper outside the app
during authentication flows
1. `authHeaderLogoUrl`: An logo image that is shown in the header during
authentication flows
1. `authFooterLinks`: a list of links to show in the authentication page footer:
`[{"text": "Link text", "url": "https://link.target"}, {"text": "Other link", ...}]`
1. `reportEvent`: Configures the dialog for reporting content to the homeserver
admin.
1. `adminMessageMD`: An extra message to show on the reporting dialog to
mention homeserver-specific policies. Accepts Markdown.
1. `integrations_ui_url`: URL to the web interface for the integrations server. The integrations
server is not Riot and normally not your homeserver either. The integration server settings
may be left blank to disable integrations.
1. `integrations_rest_url`: URL to the REST interface for the integrations server.
1. `integrations_widgets_urls`: list of URLs to the REST interface for the widget integrations server.
1. `bug_report_endpoint_url`: endpoint to send bug reports to (must be running a
https://github.com/matrix-org/rageshake server). Bug reports are sent when a user clicks
"Send Logs" within the application. Bug reports can be disabled by leaving the
`bug_report_endpoint_url` out of your config file.
1. `roomDirectory`: config for the public room directory. This section is optional.
1. `roomDirectory.servers`: List of other homeservers' directories to include in the drop
down list. Optional.
1. `default_theme`: name of theme to use by default (e.g. 'light')
1. `update_base_url` (electron app only): HTTPS URL to a web server to download
updates from. This should be the path to the directory containing `macos`
and `win32` (for update packages, not installer packages).
1. `piwik`: Analytics can be disabled by setting `piwik: false` or by leaving the piwik config
option out of your config file. If you want to enable analytics, set `piwik` to be an object
containing the following properties:
1. `url`: The URL of the Piwik instance to use for collecting analytics
1. `whitelistedHSUrls`: a list of HS URLs to not redact from the analytics
1. `whitelistedISUrls`: a list of IS URLs to not redact from the analytics
1. `siteId`: The Piwik Site ID to use when sending analytics to the Piwik server configured above
1. `welcomeUserId`: the user ID of a bot to invite whenever users register that can give them a tour
1. `embeddedPages`: Configures the pages displayed in portions of Riot that
embed static files, such as:
1. `welcomeUrl`: Initial content shown on the outside of the app when not
logged in. Defaults to `welcome.html` supplied with Riot.
1. `homeUrl`: Content shown on the inside of the app when a specific room is
not selected. By default, no home page is configured. If one is set, a
button to access it will be shown in the top left menu.
1. `defaultCountryCode`: The ISO 3166 alpha2 country code to use when showing
country selectors, like the phone number input on the registration page.
Defaults to `GB` if the given code is unknown or not provided.
1. `settingDefaults`: Defaults for settings that support the `config` level,
as an object mapping setting name to value (note that the "theme" setting
is special cased to the `default_theme` in the config file).
1. `disable_custom_urls`: disallow the user to change the
default homeserver when signing up or logging in.
1. `permalinkPrefix`: Used to change the URL that Riot generates permalinks with.
By default, this is "https://matrix.to" to generate matrix.to (spec) permalinks.
Set this to your Riot instance URL if you run an unfederated server (eg:
"https://riot.example.org").
Note that `index.html` also has an og:image meta tag that is set to an image
hosted on riot.im. This is the image used if links to your copy of Riot
appear in some websites like Facebook, and indeed Riot itself. This has to be
static in the HTML and an absolute URL (and HTTP rather than HTTPS), so it's
not possible for this to be an option in config.json. If you'd like to change
it, you can build Riot, but run
`RIOT_OG_IMAGE_URL="http://example.com/logo.png" yarn build`.
Alternatively, you can edit the `og:image` meta tag in `index.html` directly
each time you download a new version of Riot.
Identity servers
================
The identity server is used for inviting other users to a room via third party
identifiers like emails and phone numbers. It is not used to store your password
or account information.
As of Riot 1.4.0, all identity server functions are optional and you are
prompted to agree to terms before data is sent to the identity server.
Riot will check multiple sources when looking for an identity server to use in
the following order of preference:
1. The identity server set in the user's account data
* For a new user, no value is present in their account data. It is only set
if the user visits Settings and manually changes their identity server.
2. The identity server provided by the `.well-known` lookup that occurred at
login
3. The identity server provided by the Riot config file
If none of these sources have an identity server set, then Riot will prompt the
user to set an identity server first when attempting to use features that
require one.
Currently the only two public identity servers are https://vector.im and
https://matrix.org, however in the future identity servers will be
decentralised.
Desktop app configuration
=========================
To run multiple instances of the desktop app for different accounts, you can
launch the executable with the `--profile` argument followed by a unique
identifier, e.g `riot-web --profile Work` for it to run a separate profile and
not interfere with the default one.
Alternatively, a custom location for the profile data can be specified using the
`--profile-dir` flag followed by the desired path.
+ `%APPDATA%\$NAME\config.json` on Windows
+ `$XDG_CONFIG_HOME\$NAME\config.json` or `~/.config/$NAME/config.json` on Linux
+ `~Library/Application Support/$NAME/config.json` on macOS
In the paths above, `$NAME` is typically `Riot`, unless you use `--profile
$PROFILE` in which case it becomes `Riot-$PROFILE`.

View File

@@ -1,112 +0,0 @@
# Feature flags
When developing new features for Riot, we use feature flags to give us more
flexibility and control over when and where those features are enabled.
For example, flags make the following things possible:
* Extended testing of a feature via labs on develop
* Enabling features when ready instead of the first moment the code is released
* Testing a feature with a specific set of users (by enabling only on a specific
Riot instance)
The size of the feature controlled by a feature flag may vary widely: it could
be a large project like reactions or a smaller change to an existing algorithm.
A large project might use several feature flags if it's useful to control the
deployment of different portions independently.
Everyone involved in a feature (engineering, design, product, reviewers) should
think about its deployment plan up front as best as possible so we can have the
right feature flags in place from the start.
## Interaction with spec process
Historically, we have often used feature flags to guard client features that
depend on unstable spec features. Unfortunately, there was never clear agreement
about how long such a flag should live for, when it should be removed, etc.
Under the [new spec
process](https://github.com/matrix-org/matrix-doc/pull/2324), server-side
unstable features can be used by clients and enabled by default as long as
clients commit to doing the associated clean up work once a feature stabilises.
## Starting work on a feature
When starting work on a feature, we should create a matching feature flag:
1. Add a new
[setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.js)
of the form:
```js
"feature_cats": {
isFeature: true,
displayName: _td("Adds cats everywhere"),
supportedLevels: LEVELS_FEATURE,
default: false,
},
```
2. Check whether the feature is enabled as appropriate:
```js
SettingsStore.isFeatureEnabled("feature_cats")
```
3. Add the feature to the [set of labs on develop](https://github.com/vector-im/riot-web/blob/develop/riot.im/develop/config.json):
```json
"features": {
"feature_cats": "labs"
},
```
4. Document the feature in the [labs documentation](https://github.com/vector-im/riot-web/blob/develop/docs/labs.md)
With these steps completed, the feature is disabled by default, but can be
enabled on develop by interested users for testing.
Different features may have different deployment plans for when to enable where.
The following lists a few common options.
## Enabling by default on develop
Set the feature to `enable` in the [develop config](https://github.com/vector-im/riot-web/blob/develop/riot.im/develop/config.json):
```json
"features": {
"feature_cats": "enable"
},
```
## Enabling by default on staging and app
Set the feature to `enable` in the [app
config](https://github.com/vector-im/riot-web/blob/develop/riot.im/app/config.json).
## Feature deployed successfully
Once we're confident that a feature is working well, we should remove the flag:
1. Remove the [setting](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.js)
2. Remove all `isFeatureEnabled` lines that test for the feature's setting
3. Remove the feature from the [labs documentation](https://github.com/vector-im/riot-web/blob/develop/docs/labs.md)
4. Remove feature state from
[develop](https://github.com/vector-im/riot-web/blob/develop/riot.im/develop/config.json)
and [app](https://github.com/vector-im/riot-web/blob/develop/riot.im/app/config.json)
configs
5. Celebrate! 🥳
## Convert to a regular setting (optional)
Sometimes we decide a feature should always be user-controllable as a setting
even after it has been fully deployed. In that case, we would craft a new,
regular setting:
1. Remove the feature flag from
[settings](https://github.com/matrix-org/matrix-react-sdk/blob/develop/src/settings/Settings.js)
and add a regular setting with the appropriate levels for your feature
2. Replace the `isFeatureEnabled` lines with `getValue` or similar calls
according to the [settings
docs](https://github.com/matrix-org/matrix-react-sdk/blob/develop/docs/settings.md)
(checking carefully, as we may want a different mix of code paths when the
feature is always present but gated by a setting)
3. Remove the feature from the [labs documentation](https://github.com/vector-im/riot-web/blob/develop/docs/labs.md)
4. Remove feature state from
[develop](https://github.com/vector-im/riot-web/blob/develop/riot.im/develop/config.json)
and [app](https://github.com/vector-im/riot-web/blob/develop/riot.im/app/config.json)
configs

View File

@@ -1,100 +0,0 @@
# Labs features
Some notes on the features you can enable by going to `Settings->Labs`. Not exhaustive, chat in
[#riot-web:matrix.org](https://matrix.to/#/#riot-web:matrix.org) for more information.
**Be warned! Labs features are not finalised, they may be fragile, they may change, they may be
dropped. Ask in the room if you are unclear about any details here.**
## Message pinning (`feature_pinning`)
Allows you to pin messages in the room. To pin a message, use the 3 dots to the right of the message
and select "Pin".
## Custom status (`feature_custom_status`)
An experimental approach for supporting custom status messages across DMs. To set a status, click on
your avatar next to the message composer.
## Custom tags (`feature_custom_tags`)
An experimental approach for dealing with custom tags. Custom tags will appear in the bottom portion
of the community filter panel.
Setting custom tags is not supported by Riot.
## Render simple counters in room header (`feature_state_counters`)
Allows rendering of labelled counters above the message list.
Once enabled, send a custom state event to a room to set values:
1. In a room, type `/devtools` to bring up the devtools interface
2. Click "Send Custom Event"
3. Toggle from "Event" to "State Event"
4. Set the event type to: `re.jki.counter` and give it a unique key
5. Specify the content in the following format:
```
{
"link": "",
"severity": "normal",
"title": "my counter",
"value": 0
}
```
That's it. Now should see your new counter under the header.
## Multiple integration managers (`feature_many_integration_managers`)
Exposes a way to access all the integration managers known to Riot. This is an implementation of [MSC1957](https://github.com/matrix-org/matrix-doc/pull/1957).
## New ways to ignore people (`feature_mjolnir`)
When enabled, a new settings tab appears for users to be able to manage their ban lists.
This is a different kind of ignoring where the ignored user's messages still get rendered,
but are hidden by default.
Ban lists are rooms within Matrix, proposed as [MSC2313](https://github.com/matrix-org/matrix-doc/pull/2313).
[Mjolnir](https://github.com/matrix-org/mjolnir) is a set of moderation tools which support
ban lists.
## Verifications in DMs (`feature_dm_verification`)
An implementation of [MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241). When enabled, verification might not work with devices which don't support MSC2241.
This also includes a new implementation of the user & member info panel, designed to share more code between showing community members & room members. Built on top of this new panel is also a new UX for verification from the member panel.
## Cross-signing (in development) (`feature_cross_signing`)
Cross-signing ([MSC1756](https://github.com/matrix-org/matrix-doc/pull/1756))
improves the device verification experience by allowing you to verify a user
instead of verifying each of their devices.
This feature is still in development and will be landing in several chunks.
## Event indexing and E2EE search support using Seshat (`feature_event_indexing`)
Adds support for search in E2E encrypted rooms. This enables an event indexer
that downloads, stores, and indexes room messages for E2E encrypted rooms.
The existing search will transparently work for encrypted rooms just like it
does for non-encrypted.
## Bridge info tab (`feature_bridge_state`)
Adds a "Bridge Info" tab to the Room Settings dialog, if a compatible bridge is
present in the room. The Bridge info tab pulls information from the `m.bridge` state event ([MSC2346](https://github.com/matrix-org/matrix-doc/pull/2346)). Since the feature is based upon a MSC, most
bridges are not expected to be compatible, and users should not rely on this
tab as the single source of truth just yet.
## Presence indicator in room list (`feature_presence_in_room_list`)
This adds a presence indicator in the room list next to DM rooms where the other
person is online.
## Show padlocks on invite only rooms (`feature_invite_only_padlocks`)
This adds padlocks to room list tiles and room header for invite only rooms.
This feature flag (unlike most) is enabled by default.

View File

@@ -1,53 +0,0 @@
## Memory leaks
Riot usually emits slow behaviour just before it is about to crash. Getting a
memory snapshot (below) just before that happens is ideal in figuring out what
is going wrong.
Common symptoms are clicking on a room and it feels like the tab froze and scrolling
becoming jumpy/staggered.
If you receive a white screen (electron) or the chrome crash page, it is likely
run out of memory and it is too late for a memory profile. Please do report when
this happens though so we can try and narrow down what might have gone wrong.
## Memory profiles/snapshots
When investigating memory leaks/problems it's usually important to compare snapshots
from different points in the Riot session lifecycle. Most importantly, a snapshot
to establish the baseline or "normal" memory usage is useful. Taking a snapshot
roughly 30-60 minutes after starting Riot is a good time to establish "normal"
memory usage for the app - anything after that is at risk of hiding the memory leak
and anything newer is still in the warmup stages of the app.
**Memory profiles can contain sensitive information.** If you are submitting a memory
profile to us for debugging purposes, please pick the appropriate Riot developer and
send them over an encrypted private message. *Do not share your memory profile in
public channels or with people you do not trust.*
### Taking a memory profile (Firefox)
1. Press CTRL+SHIFT+I (I as in eye).
2. Click the Memory tab.
3. Press the camera icon in the top left of the pane.
4. Wait a bit (coffee is a good option).
5. When the save button appears on the left side of the panel, click it to save the
profile locally.
6. Compress the file (gzip or regular zip) to make the file smaller.
7. Send the compressed file to whoever asked for it (if you trust them).
While the profile is in progress, the tab might be frozen or unresponsive.
### Taking a memory profile (Chrome/Desktop)
1. Press CTRL+SHIFT+I (I as in eye).
2. Click the Memory tab.
3. Select "Heap Snapshot" and the riot.im VM instance (not the indexeddb one).
4. Click "Take Snapshot".
5. Wait a bit (coffee is a good option).
6. When the save button appears on the left side of the panel, click it to save the
profile locally.
7. Compress the file (gzip or regular zip) to make the file smaller.
8. Send the compressed file to whoever asked for it (if you trust them).
While the profile is in progress, the tab might be frozen or unresponsive.

View File

@@ -1,60 +0,0 @@
# Native Node Modules
For some features, the desktop version of Riot can make use of native Node
modules. These allow Riot to integrate with the desktop in ways that a browser
cannot.
While native modules enable powerful new features, they must be complied for
each operating system. For official Riot releases, we will always build these
modules from source to ensure we can trust the compiled output. In the future,
we may offer a pre-compiled path for those who want to use these features in a
custom build of Riot without installing the various build tools required.
Do note that compiling a module for a particular operating system
(Linux/macOS/Windows) will need to be done on that operating system.
Cross-compiling from a host OS for a different target OS may be possible, but
we don't support this flow with Riot dependencies at this time.
At the moment, we need to make some changes to the Riot release process before
we can support native Node modules at release time, so these features are
currently disabled by default until that is resolved. The following sections
explain the manual steps you can use with a custom build of Riot to enable
these features if you'd like to try them out.
## Adding Seshat for search in E2E encrypted rooms
Seshat is a native Node module that adds support for local event indexing and
full text search in E2E encrypted rooms.
Since Seshat is written in Rust, the Rust compiler and related tools need to be
installed before installing Seshat itself. To install Rust please consult the
official Rust [documentation](https://www.rust-lang.org/tools/install).
Seshat also depends on the SQLCipher library to store its data in encrypted form
on disk. You'll need to install it via your OS package manager.
After installing the Rust compiler and SQLCipher, Seshat support can be added
using yarn inside the `electron_app/` directory:
yarn add matrix-seshat
You will have to rebuild the native libraries against electron's version of
of node rather than your system node, using the `electron-build-env` tool.
This is also needed to when pulling in changes to Seshat using `yarn link`.
Again from the `electron_app/` directory:
yarn add electron-build-env
Recompiling Seshat itself can be done like so:
yarn run electron-build-env -- --electron 6.1.1 -- neon build matrix-seshat --release
Please make sure to include all the `--` as well as the `--release` command line
switch at the end. Modify your electron version accordingly depending on the
version that is installed on your system.
After this is done the Electron version of Riot can be run from the main folder
as usual using:
yarn electron

View File

@@ -1,15 +0,0 @@
# Keyboard Shortcuts
The modifier is <kbd>Ctrl</kbd> on Windows & Linux and <kbd>⌘</kbd> on Mac.
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>m</kbd> - toggle markdown
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>d</kbd> - toggle mic mute
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>e</kbd> - toggle video on/off
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>k</kbd> - jump to named room
- <kbd>↑</kbd>/<kbd>↓</kbd> - navigate old messages to edit when the composer is in focus
- <kbd>↑</kbd>/<kbd>↓</kbd> - next/prev room when focus in room list
- <kbd>Alt</kbd>+<kbd>↑</kbd>/<kbd>↓</kbd> - resend previous messages when the composer is in focus
- <kbd>PageUp</kbd>/<kbd>PageDown</kbd> - scroll timeline up/down
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>Home</kbd>/<kbd>End</kbd> - jump to
start/end of the composer when focused, otherwise jump to timeline start/end
- <kbd>Ctrl</kbd>/<kbd>⌘</kbd>+<kbd>`</kbd> - toggle the top left menu

View File

@@ -1,68 +0,0 @@
== Skinning refactor ==
matrix-react-sdk
- base images
- base CSS
- all the components needed to build a workable app (including the top layer)
riot-web: the riot skin
- riot-specific classes (e.g. login header/footer)
- riot-specific themes
- light
- dark
i.e. the only things which should go into riot-web are bits which apply vector-specific skinning
specifically "Stuff that any other brand would not want to use. (e.g. riot logos, links, T&Cs)"
- Questions:
- Electron app? (should probably be a separate repo in its own right? but might as well go here for now)
- index.html & index.js? (should be in matrix-react-sdk, given the SDK is useless without them?)
ideally matrix-react-sdk itself should ship with a default skin which actually works built in.
status skin (can go in the same app for now)
- has status theme
- which inherits from riot light theme
- how do we share graphics between skins?
- shove them into react-sdk, or...
- guess we do ../../vector/img
- this means keeping the skin name in the images (unless /img is a shortcut to the right skin's images)
out of scope:
- making the components more independent, so they can be used in isolation.
- that said, the bits which should probably be used by being embeded into a different app:
- login/reg
- RoomView + RoomSettings
- MessageComposer
- RoomList
- MemberList
- MemberInfo
- Voip UI
- UserSettings
- sharing different js-sdks between the different isolated modules
other changes:
- how do we handle i18n?
- each skin should really be its own i18n project. As long as all the commonality stuff is in matrix-react-sdk this shouldn't be too bad.
- ability to associate components with a given skin
- skins/vector/src <-- components
- skins/vector/css
- skins/vector/img
- skins/vector/fonts
- gather together themes (per skin) into a single place too
- skins/vector/themes/foo/css
- skins/vector/themes/foo/img
- skins/vector/themes/foo/fonts
- ideally riot-web would contain almost nothing but skins/vector directory.
- ability to entirely replace CSS rather than override it for a given theme
- e.g. if we replace `Login.js` with `StatusLogin.js`, then we should similarly be able to replace `_Login.scss` with `_StatusLogin.scss`.
random thoughts;
- should we be able to change the entire skin at runtime (more like wordpress) - to the extent of replacing entire components?
- might pose security issues if a theme can be swapped out to replace MatrixChat or other fundamental functionality at runtime
- if so, perhaps skins & themes should converge...
-----------------
Immediate plan for Status:
* Implement it as a theme for the riot skin
* Ideally move skins to a sensible level (possibly even including src?)

View File

@@ -11,11 +11,11 @@ As of Jan 2017, skins are not fully supported; riot is the only available skin.
To define a theme for Riot: To define a theme for Riot:
1. Pick a name, e.g. `teal`. at time of writing we have `light` and `dark`. 1. Pick a name, e.g. `teal`. at time of writing we have `light` and `dark`.
2. Fork `src/skins/vector/css/themes/dark.scss` to be `teal.scss` 2. Fork `src/skins/vector/css/themes/dark.scss` to be teal.scss
3. Fork `src/skins/vector/css/themes/_base.scss` to be `_teal.scss` 3. Fork `src/skins/vector/css/themes/_base.scss` to be _teal.scss
4. Override variables in `_teal.scss` as desired. You may wish to delete ones 4. Override variables in _teal.scss as desired. You may wish to delete ones
which don't differ from `_base.scss`, to make it clear which are being which don't differ from _base.scss, to make it clear which are being
overridden. If every single colour is being changed (as per `_dark.scss`) overridden. If every single colour is being changed (as per _dark.scss)
then you might as well keep them all. then you might as well keep them all.
5. Add the theme to the list of entrypoints in webpack.config.js 5. Add the theme to the list of entrypoints in webpack.config.js
6. Add the theme to the list of themes in matrix-react-sdk's UserSettings.js 6. Add the theme to the list of themes in matrix-react-sdk's UserSettings.js
@@ -23,58 +23,3 @@ To define a theme for Riot:
In future, the assets for a theme will probably be gathered together into a In future, the assets for a theme will probably be gathered together into a
single directory tree. single directory tree.
Custom Themes
=============
Themes derived from the built in themes may also be defined in settings.
To avoid name collisions, the internal name of a theme is
`custom-${theme.name}`. So if you want to set the custom theme below as the
default theme, you would use `default_theme: "custom-Electric Blue"`.
eg. in config.json:
```
"settingDefaults": {
"custom_themes": [
{
"name": "Electric Blue",
"is_dark": false,
"colors": {
"accent-color": "#3596fc",
"primary-color": "#368bd6",
"warning-color": "#ff4b55",
"sidebar-color": "#27303a",
"roomlist-background-color": "#f3f8fd",
"roomlist-text-color": "#2e2f32",
"roomlist-text-secondary-color": "#61708b",
"roomlist-highlights-color": "#ffffff",
"roomlist-separator-color": "#e3e8f0",
"timeline-background-color": "#ffffff",
"timeline-text-color": "#2e2f32",
"timeline-text-secondary-color": "#61708b",
"timeline-highlights-color": "#f3f8fd"
}
}, {
"name": "Deep Purple",
"is_dark": true,
"colors": {
"accent-color": "#6503b3",
"primary-color": "#368bd6",
"warning-color": "#b30356",
"sidebar-color": "#15171B",
"roomlist-background-color": "#22262E",
"roomlist-text-color": "#A1B2D1",
"roomlist-text-secondary-color": "#EDF3FF",
"roomlist-highlights-color": "#343A46",
"roomlist-separator-color": "#a1b2d1",
"timeline-background-color": "#181b21",
"timeline-text-color": "#EDF3FF",
"timeline-text-secondary-color": "#A1B2D1",
"timeline-highlights-color": "#22262E"
}
}
]
}
```

View File

@@ -1,63 +0,0 @@
# How to translate riot-web (Dev Guide)
## Requirements
- A working [Development Setup](../../#setting-up-a-dev-environment)
- Including up-to-date versions of matrix-react-sdk and matrix-js-sdk
- Latest LTS version of Node.js installed
- Be able to understand English
- Be able to understand the language you want to translate riot-web into
## Translating strings vs. marking strings for translation
Translating strings are done with the `_t()` function found in matrix-react-sdk/lib/languageHandler.js. It is recommended to call this function wherever you introduce a string constant which should be translated. However, translating can not be performed until after the translation system has been initialized. Thus, sometimes translation must be performed at a different location in the source code than where the string is introduced. This breaks some tooling and makes it difficult to find translatable strings. Therefore, there is the alternative `_td()` function which is used to mark strings for translation, without actually performing the translation (which must still be performed separately, and after the translation system has been initialized).
Basically, whenever a translatable string is introduced, you should call either `_t()` immediately OR `_td()` and later `_t()`.
Example:
```
// Module-level constant
const COLORS = {
'#f8481c': _td('reddish orange'), // Can't call _t() here yet
'#fc2647': _td('pinky red') // Use _td() instead so the text is picked up for translation anyway
}
// Function that is called some time after i18n has been loaded
function getColorName(hex) {
return _t(COLORS[hex]); // Perform actual translation here
}
```
## Adding new strings
1. Check if the import ``import { _t } from 'matrix-react-sdk/lib/languageHandler';`` is present. If not add it to the other import statements. Also import `_td` if needed.
1. Add ``_t()`` to your string. (Don't forget curly braces when you assign an expression to JSX attributes in the render method). If the string is introduced at a point before the translation system has not yet been initialized, use `_td()` instead, and call `_t()` at the appropriate time.
1. Run `yarn i18n` to update ``src/i18n/strings/en_EN.json``
1. If you added a string with a plural, you can add other English plural variants to ``src/i18n/strings/en_EN.json`` (remeber to edit the one in the same project as the source file containing your new translation).
## Editing existing strings
1. Edit every occurrence of the string inside `_t()` and `_td()` in the JSX files.
1. Run `yarn i18n` to update `src/i18n/strings/en_EN.json`. (Be sure to run this in the same project as the JSX files you just edited.)
1. Run `yarn prunei18n` to remove the old string from `src/i18n/strings/*.json`.
## Adding variables inside a string.
1. Extend your ``_t()`` call. Instead of ``_t(STRING)`` use ``_t(STRING, {})``
1. Decide how to name it. Please think about if the person who has to translate it can understand what it does. E.g. using the name 'recipient' is bad, because a translator does not know if it is the name of a person, an email address, a user ID, etc. Rather use e.g. recipientEmailAddress.
1. Add it to the array in ``_t`` for example ``_t(STRING, {variable: this.variable})``
1. Add the variable inside the string. The syntax for variables is ``%(variable)s``. Please note the _s_ at the end. The name of the variable has to match the previous used name.
- You can use the special ``count`` variable to choose between multiple versions of the same string, in order to get the correct pluralization. E.g. ``_t('You have %(count)s new messages', { count: 2 })`` would show 'You have 2 new messages', while ``_t('You have %(count)s new messages', { count: 1 })`` would show 'You have one new message' (assuming a singular version of the string has been added to the translation file. See above). Passing in ``count`` is much prefered over having an if-statement choose the correct string to use, because some languages have much more complicated plural rules than english (e.g. they might need a completely different form if there are three things rather than two).
- If you want to translate text that includes e.g. hyperlinks or other HTML you have to also use tag substitution, e.g. ``_t('<a>Click here!</a>', {}, { 'a': (sub) => <a>{sub}</a> })``. If you don't do the tag substitution you will end up showing literally '<a>' rather than making a hyperlink.
- You can also use React components with normal variable substitution if you want to insert HTML markup, e.g. ``_t('Your email address is %(emailAddress)s', { emailAddress: <i>{userEmailAddress}</i> })``.
## Things to know/Style Guides
- Do not use `_t()` inside ``getDefaultProps``: the translations aren't loaded when `getDefaultProps` is called, leading to missing translations. Use `_td()` to indicate that `_t()` will be called on the string later.
- If using translated strings as constants, translated strings can't be in constants loaded at class-load time since the translations won't be loaded. Mark the strings using `_td()` instead and perform the actual translation later.
- If a string is presented in the UI with punctuation like a full stop, include this in the translation strings, since punctuation varies between languages too.
- Avoid "translation in parts", i.e. concatenating translated strings or using translated strings in variable substitutions. Context is important for translations, and translating partial strings this way is simply not always possible.
- Concatenating strings often also introduces an implicit assumption about word order (e.g. that the subject of the sentence comes first), which is incorrect for many languages.
- Translation 'smell test': If you have a string that does not begin with a capital letter (is not the start of a sentence) or it ends with e.g. ':' or a preposition (e.g. 'to') you should recheck that you are not trying to translate a partial sentence.
- If you have multiple strings, that are almost identical, except some part (e.g. a word or two) it is still better to translate the full sentence multiple times. It may seem like inefficient repetion, but unlike programming where you try to minimize repetition, translation is much faster if you have many, full, clear, sentences to work with, rather than fewer, but incomplete sentence fragments.

View File

@@ -1,64 +0,0 @@
# How to translate riot-web
## Requirements
- Web Browser
- Be able to understand English
- Be able to understand the language you want to translate riot-web into
## Step 0: Join #riotweb-translations:matrix.org
1. Come and join https://matrix.to/#/#riotweb-translations:matrix.org
2. Read scrollback and/or ask if anyone else is working on your language, and co-ordinate if needed. In general little-or-no coordination is needed though :)
## Step 1: Preparing your Weblate Profile
1. Head to https://translate.riot.im and register either via Github or email
2. After registering check if you got an email to verify your account and click the link (if there is none head to step 1.4)
3. Log into weblate
4. Head to https://translate.riot.im/accounts/profile/ and select the languages you know and maybe another language you know too.
6. Head to https://translate.riot.im/accounts/profile/#subscriptions and select Riot Web as Project
## How to check if your language already is being translated
Go to https://translate.riot.im/projects/riot-web/ and visit the 2 sub-projects.
If your language is listed go to Step 2a and if not go to Step 2b
## Step 2a: Helping on existing languages.
1. Head to one of the projects listed https://translate.riot.im/projects/riot-web/
2. Click on the ``translate`` button on the right side of your language
3. Fill in the translations in the writeable field. You will see the original English string and the string of your second language above.
Head to the explanations under Steb 2b
## Step 2b: Adding a new language
1. Go to one of the projects listed https://translate.riot.im/projects/riot-web/
2. Click the ``Start new translation`` button at the bottom
3. Select a language
4. Start translating like in 2a.3
5. Repeat these steps for the other projects which are listed at the link of step 2b.1
### What means the green button under the text field?
The green button let you save our translations directly. Please only use it if you are 100% sure about that translation. If you do not know a translation please DO NOT click that button. Use the arrows above the translations field and click to the right.
### What means the yellow button under the text field?
The yellow button has to be used if you are unsure about the translation but you have a rough idea. It adds a new suggestion to the string which can than be reviewed by others.
### What are "%(something)s"?
These things are variables that are expanded when displayed by Riot. They can be room names, usernames or similar. If you find one, you can move to the right place for your language, but not delete it as the variable will be missing if you do.
A special case is `%(urlStart)s` and `%(urlEnd)s` which are used to mark the beginning of a hyperlink (i.e. `<a href="/somewhere">` and `</a>`. You must keep these markers surrounding the equivalent string in your language that needs to be hyperlinked.
### "I want to come back to this string. How?"
You can use inside the translation field "Review needed" checkbox. It will be shown as Strings that need to be reviewed.
### Further reading
The official Weblate doc provides some more in-deepth explanation on how to do translations and talks about do and don'ts. You can find it at: https://docs.weblate.org/en/latest/user/translating.html

BIN
electron/build/icon.icns Normal file

Binary file not shown.

BIN
electron/build/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
electron/img/riot.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
electron/img/riot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

4
electron/riot.im/README Normal file
View File

@@ -0,0 +1,4 @@
This directory contains the config file for the official riot.im distribution
of Riot Desktop. You probably do not want to build with this config unless
you're building the official riot.im distribution, or you'll find your builds
will replace themselves with the riot.im build.

View File

@@ -0,0 +1,73 @@
{
"update_base_url": "https://riot.im/download/desktop/update/",
"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",
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"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

@@ -0,0 +1,247 @@
// @flow
/*
Copyright 2016 Aviral Dasgupta
Copyright 2016 OpenMarket 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.
*/
// Squirrel on windows starts the app with various flags
// as hooks to tell us when we've been installed/uninstalled
// etc.
const check_squirrel_hooks = require('./squirrelhooks');
if (check_squirrel_hooks()) return;
const electron = require('electron');
const url = require('url');
const tray = require('./tray');
const VectorMenu = require('./vectormenu');
let vectorConfig = {};
try {
vectorConfig = require('../../webapp/config.json');
} catch (e) {
// it would be nice to check the error code here and bail if the config
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
// file or invalid json, so node is just very unhelpful.
// Continue with the defaults (ie. an empty config)
}
const PERMITTED_URL_SCHEMES = [
'http:',
'https:',
'mailto:',
];
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
let mainWindow = null;
let appQuitting = false;
function safeOpenURL(target) {
// openExternal passes the target to open/start/xdg-open,
// so put fairly stringent limits on what can be opened
// (for instance, open /bin/sh does indeed open a terminal
// with a shell, albeit with no arguments)
const parsed_url = url.parse(target);
if (PERMITTED_URL_SCHEMES.indexOf(parsed_url.protocol) > -1) {
// explicitly use the URL re-assembled by the url library,
// so we know the url parser has understood all the parts
// of the input string
const new_target = url.format(parsed_url);
electron.shell.openExternal(new_target);
}
}
function onWindowOrNavigate(ev, target) {
// always prevent the default: if something goes wrong,
// we don't want to end up opening it in the electron
// app, as we could end up opening any sort of random
// url in a window that has node scripting access.
ev.preventDefault();
safeOpenURL(target);
}
function onLinkContextMenu(ev, params) {
const popup_menu = new electron.Menu();
popup_menu.append(new electron.MenuItem({
label: params.linkURL,
click() {
safeOpenURL(params.linkURL);
},
}));
popup_menu.popup();
ev.preventDefault();
}
function installUpdate() {
// for some reason, quitAndInstall does not fire the
// before-quit event, so we need to set the flag here.
appQuitting = true;
electron.autoUpdater.quitAndInstall();
}
function pollForUpdates() {
try {
electron.autoUpdater.checkForUpdates();
} catch (e) {
console.log("Couldn't check for update", e);
}
}
function startAutoUpdate(update_base_url) {
if (update_base_url.slice(-1) !== '/') {
update_base_url = update_base_url + '/';
}
try {
// For reasons best known to Squirrel, the way it checks for updates
// is completely different between macOS and windows. On macOS, it
// hits a URL that either gives it a 200 with some json or
// 204 No Content. On windows it takes a base path and looks for
// files under that path.
if (process.platform == 'darwin') {
// include the current version in the URL we hit. Electron doesn't add
// it anywhere (apart from the User-Agent) so it's up to us. We could
// (and previously did) just use the User-Agent, but this doesn't
// rely on NSURLConnection setting the User-Agent to what we expect,
// and also acts as a convenient cache-buster to ensure that when the
// app updates it always gets a fresh value to avoid update-looping.
electron.autoUpdater.setFeedURL(
update_base_url +
'macos/?localVersion=' + encodeURIComponent(electron.app.getVersion())
);
} else if (process.platform == 'win32') {
electron.autoUpdater.setFeedURL(update_base_url + 'win32/' + process.arch + '/');
} else {
// Squirrel / electron only supports auto-update on these two platforms.
// I'm not even going to try to guess which feed style they'd use if they
// implemented it on Linux, or if it would be different again.
console.log("Auto update not supported on this platform");
}
// We check for updates ourselves rather than using 'updater' because we need to
// do it in the main process (and we don't really need to check every 10 minutes:
// every hour should be just fine for a desktop app)
// However, we still let the main window listen for the update events.
// We also wait a short time before checking for updates the first time because
// of squirrel on windows and it taking a small amount of time to release a
// lock file.
setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
} catch (err) {
// will fail if running in debug mode
console.log("Couldn't enable update checking", err);
}
}
// handle uncaught errors otherwise it displays
// stack traces in popup dialogs, which is terrible (which
// it will do any time the auto update poke fails, and there's
// no other way to catch this error).
// Assuming we generally run from the console when developing,
// this is far preferable.
process.on('uncaughtException', function (error) {
console.log("Unhandled exception", error);
});
electron.ipcMain.on('install_update', installUpdate);
electron.app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
const shouldQuit = electron.app.makeSingleInstance((commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (!mainWindow.isVisible()) mainWindow.show();
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
if (shouldQuit) {
electron.app.quit()
}
electron.app.on('ready', () => {
if (vectorConfig.update_base_url) {
console.log("Starting auto update with base URL: " + vectorConfig.update_base_url);
startAutoUpdate(vectorConfig.update_base_url);
} else {
console.log("No update_base_url is defined: auto update is disabled");
}
const icon_path = `${__dirname}/../img/riot.` + (
process.platform == 'win32' ? 'ico' : 'png'
);
mainWindow = new electron.BrowserWindow({
icon: icon_path,
width: 1024, height: 768,
show: false,
autoHideMenuBar: true,
});
mainWindow.loadURL(`file://${__dirname}/../../webapp/index.html`);
electron.Menu.setApplicationMenu(VectorMenu);
// Create trayIcon icon
tray.create(mainWindow, {
icon_path: icon_path,
brand: vectorConfig.brand || 'Riot'
});
mainWindow.once('ready-to-show', () => {
mainWindow.show();
});
mainWindow.on('closed', () => {
mainWindow = null;
});
mainWindow.on('close', (e) => {
if (!appQuitting && (tray.hasTray() || process.platform == 'darwin')) {
// On Mac, closing the window just hides it
// (this is generally how single-window Mac apps
// behave, eg. Mail.app)
e.preventDefault();
mainWindow.hide();
return false;
}
});
mainWindow.webContents.on('new-window', onWindowOrNavigate);
mainWindow.webContents.on('will-navigate', onWindowOrNavigate);
mainWindow.webContents.on('context-menu', function(ev, params) {
if (params.linkURL) {
onLinkContextMenu(ev, params);
}
});
});
electron.app.on('window-all-closed', () => {
electron.app.quit();
});
electron.app.on('activate', () => {
mainWindow.show();
});
electron.app.on('before-quit', () => {
appQuitting = true;
});
// Set the App User Model ID to match what the squirrel
// installer uses for the shortcut icon.
// This makes notifications work on windows 8.1 (and is
// a noop on other platforms).
electron.app.setAppUserModelId('com.squirrel.riot-web.Riot');

View File

@@ -16,30 +16,30 @@ limitations under the License.
const path = require('path'); const path = require('path');
const spawn = require('child_process').spawn; const spawn = require('child_process').spawn;
const {app} = require('electron'); const app = require('electron').app;
function runUpdateExe(args, done) { function run_update_exe(args, done) {
// Invokes Squirrel's Update.exe which will do things for us like create shortcuts // Invokes Squirrel's Update.exe which will do things for us like create shortcuts
// Note that there's an Update.exe in the app-x.x.x directory and one in the parent // Note that there's an Update.exe in the app-x.x.x directory and one in the parent
// directory: we need to run the one in the parent directory, because it discovers // directory: we need to run the one in the parent directory, because it discovers
// information about the app by inspecting the directory it's run from. // information about the app by inspecting the directory it's run from.
const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe'); const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
console.log(`Spawning '${updateExe}' with args '${args}'`); console.log('Spawning `%s` with args `%s`', updateExe, args);
spawn(updateExe, args, { spawn(updateExe, args, {
detached: true, detached: true
}).on('close', done); }).on('close', done);
} };
function checkSquirrelHooks() { function check_squirrel_hooks() {
if (process.platform !== 'win32') return false; if (process.platform != 'win32') return false;
const cmd = process.argv[1]; const cmd = process.argv[1];
const target = path.basename(process.execPath); const target = path.basename(process.execPath);
if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') { if (cmd === '--squirrel-install' || cmd === '--squirrel-updated') {
runUpdateExe(['--createShortcut=' + target + ''], app.quit); run_update_exe(['--createShortcut=' + target + ''], app.quit);
return true; return true;
} else if (cmd === '--squirrel-uninstall') { } else if (cmd === '--squirrel-uninstall') {
runUpdateExe(['--removeShortcut=' + target + ''], app.quit); run_update_exe(['--removeShortcut=' + target + ''], app.quit);
return true; return true;
} else if (cmd === '--squirrel-obsolete') { } else if (cmd === '--squirrel-obsolete') {
app.quit(); app.quit();
@@ -48,4 +48,4 @@ function checkSquirrelHooks() {
return false; return false;
} }
module.exports = checkSquirrelHooks; module.exports = check_squirrel_hooks;

67
electron/src/tray.js Normal file
View File

@@ -0,0 +1,67 @@
/*
Copyright 2017 Karl Glatz <karl@glatz.biz>
Copyright 2017 OpenMarket 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.
*/
const path = require('path');
const electron = require('electron');
const app = electron.app;
const Tray = electron.Tray;
const MenuItem = electron.MenuItem;
let trayIcon = null;
exports.hasTray = function hasTray() {
return (trayIcon !== null);
}
exports.create = function (win, config) {
// no trays on darwin
if (process.platform === 'darwin' || trayIcon) {
return;
}
const toggleWin = function () {
if (win.isVisible() && !win.isMinimized()) {
win.hide();
} else {
if (win.isMinimized()) win.restore();
if (!win.isVisible()) win.show();
win.focus();
}
};
const contextMenu = electron.Menu.buildFromTemplate([
{
label: 'Show/Hide ' + config.brand,
click: toggleWin
},
{
type: 'separator'
},
{
label: 'Quit',
click: function () {
app.quit();
}
}
]);
trayIcon = new Tray(config.icon_path);
trayIcon.setToolTip(config.brand);
trayIcon.setContextMenu(contextMenu);
trayIcon.on('click', toggleWin);
};

197
electron/src/vectormenu.js Normal file
View File

@@ -0,0 +1,197 @@
/*
Copyright 2016 OpenMarket 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.
*/
const electron = require('electron');
// Menu template from http://electron.atom.io/docs/api/menu/, edited
const template = [
{
label: 'Edit',
submenu: [
{
role: 'undo'
},
{
role: 'redo'
},
{
type: 'separator'
},
{
role: 'cut'
},
{
role: 'copy'
},
{
role: 'paste'
},
{
role: 'pasteandmatchstyle'
},
{
role: 'delete'
},
{
role: 'selectall'
}
]
},
{
label: 'View',
submenu: [
{
type: 'separator'
},
{
role: 'resetzoom'
},
{
role: 'zoomin'
},
{
role: 'zoomout'
},
{
type: 'separator'
},
{
role: 'togglefullscreen'
},
{
role: 'toggledevtools'
}
]
},
{
role: 'window',
submenu: [
{
role: 'minimize'
},
{
role: 'close'
}
]
},
{
role: 'help',
submenu: [
{
label: 'riot.im',
click () { electron.shell.openExternal('https://riot.im/') }
}
]
}
];
// macOS has specific menu conventions...
if (process.platform === 'darwin') {
// first macOS menu is the name of the app
const name = electron.app.getName()
template.unshift({
label: name,
submenu: [
{
role: 'about'
},
{
type: 'separator'
},
{
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
role: 'hide'
},
{
role: 'hideothers'
},
{
role: 'unhide'
},
{
type: 'separator'
},
{
role: 'quit'
}
]
})
// Edit menu.
// This has a 'speech' section on macOS
template[1].submenu.push(
{
type: 'separator'
},
{
label: 'Speech',
submenu: [
{
role: 'startspeaking'
},
{
role: 'stopspeaking'
}
]
}
)
// Window menu.
// This also has specific functionality on macOS
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
]
} else {
template.unshift({
label: 'File',
submenu: [
// For some reason, 'about' does not seem to work on windows.
/*{
role: 'about'
},*/
{
role: 'quit'
}
]
});
}
module.exports = electron.Menu.buildFromTemplate(template)

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Entitlements from electron-builder's defaults
(https://github.com/electron-userland/electron-builder/blob/master/packages/app-builder-lib/templates/entitlements.mac.plist)
nb. This does *not* include the app sandbox: at the time of adding this file,
we were using electron-builder 21.2.0 which does not have the sandbox entitlement.
Latest electron-builder does, but it appears to be causing issues:
(https://github.com/electron-userland/electron-builder/issues/4390)
-->
<!-- https://github.com/electron/electron-notarize#prerequisites -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<!-- https://github.com/electron-userland/electron-builder/issues/3940 -->
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<!-- Our own additional entitlements (we need to access the camera and
mic for VoIP calls -->
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
</dict>
</plist>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 702 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -1,15 +0,0 @@
{
"name": "riot-web",
"productName": "Riot",
"main": "src/electron-main.js",
"version": "1.5.13",
"description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.",
"dependencies": {
"auto-launch": "^5.0.1",
"electron-store": "^2.0.0",
"electron-window-state": "^4.1.0",
"minimist": "^1.2.0",
"png-to-ico": "^1.0.2"
}
}

View File

@@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIF0jCCBLqgAwIBAgIRAISYBqZi3VvCUeSfHXF+cbwwDQYJKoZIhvcNAQELBQAw
gZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTcwNQYD
VQQDEy5DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gQ29kZSBTaWduaW5n
IENBMB4XDTE3MDgyMzAwMDAwMFoXDTIwMDgyMjIzNTk1OVowgdgxETAPBgNVBAUT
CDEwODczNjYxMRMwEQYLKwYBBAGCNzwCAQMTAkdCMR0wGwYDVQQPExRQcml2YXRl
IE9yZ2FuaXphdGlvbjELMAkGA1UEBhMCR0IxETAPBgNVBBEMCFdDMVIgNEFHMQ8w
DQYDVQQIDAZMb25kb24xDzANBgNVBAcMBkxvbmRvbjEbMBkGA1UECQwSMjYgUmVk
IExpb24gU3F1YXJlMRcwFQYDVQQKDA5OZXcgVmVjdG9yIEx0ZDEXMBUGA1UEAwwO
TmV3IFZlY3RvciBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7
X0HP3oM/SVr6PboD03ndtYTONZDcJ/GJ3EyYi6UNrcbKjuDHwPktx9hjAhNjcVkG
lmuTEPluPj9DbvjaTrers0cQsAS1vJ0RHjLfA93Flg1ys9Q6OThUMw77FtFPtiJU
z5cSYzfFAhn/4dv7BcgGptn+Mv/8CaTu+RUZJUgoSlRWcT1TREmxkzWotbblqsHO
zjDmUg20tL5/qpt6BSWsNespf5udKQFXMtqkczBcLvBLmql0vurVcQy8BibB+Q89
QKwRzwLgaIa7O8WEssFcW8uJe9s0SNtUy8ehbuoSxpA/DbHFwsiDbNA78vp7HrqM
qY6t6OIgLtDYBFCfe/btAgMBAAGjggHaMIIB1jAfBgNVHSMEGDAWgBTfj/MgDOnK
pgTYW1g3Kj2rRtyDSTAdBgNVHQ4EFgQUH+mDOdRkF3bYDxCWEaGB4lxiCxcwDgYD
VR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMw
EQYJYIZIAYb4QgEBBAQDAgQQMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQYBMCsw
KQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5jb20vQ1BTMFUGA1Ud
HwROMEwwSqBIoEaGRGh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JTQUV4
dGVuZGVkVmFsaWRhdGlvbkNvZGVTaWduaW5nQ0EuY3JsMIGGBggrBgEFBQcBAQR6
MHgwUAYIKwYBBQUHMAKGRGh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JT
QUV4dGVuZGVkVmFsaWRhdGlvbkNvZGVTaWduaW5nQ0EuY3J0MCQGCCsGAQUFBzAB
hhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wJgYDVR0RBB8wHaAbBggrBgEFBQcI
A6APMA0MC0dCLTEwODczNjYxMA0GCSqGSIb3DQEBCwUAA4IBAQBJ2aH4aixh0aiz
4WKlK+LMVLHpQ2POE3FZYNpAW7o1q2YDGEADXdGrygPE9NCGNBXKo0CAemCYNWfX
Ov/jdoiMfeqW3vrZ66oEy8OqbvJSwK1xmomWuYw3wYPWcPVG+YbWYD2CGdQu8jTz
fzAJCpvAuY3Wji3fQjiecAC7JCSB4fBHa0ALJOmiSqKQUUpkXs5kW7O0lPBnHzNF
2tQGltXMSIrq1QfFtcreMyKlwDOxPIh360dv5aHhaeSRDRKxq7uq5ikQF2gjKx4k
ieg2HRbAW6fVPpFr4zRS5umpeZV3i06i11VQQPS/mA/OBEXyaqzx4mr6B7U6ptrp
jMqiUv2w
-----END CERTIFICATE-----

View File

@@ -1,6 +0,0 @@
This directory contains the config file for the official riot.im distribution
of Riot Desktop.
You probably do not want to build with this config unless you're building the
official riot.im distribution, or you'll find your builds will replace
themselves with the riot.im build.

View File

@@ -1,40 +0,0 @@
{
"update_base_url": "https://packages.riot.im/desktop/update/",
"default_server_name": "matrix.org",
"brand": "Riot",
"integrations_ui_url": "https://scalar.vector.im/",
"integrations_rest_url": "https://scalar.vector.im/api",
"integrations_widgets_urls": [
"https://scalar.vector.im/_matrix/integrations/v1",
"https://scalar.vector.im/api",
"https://scalar-staging.vector.im/_matrix/integrations/v1",
"https://scalar-staging.vector.im/api",
"https://scalar-staging.riot.im/scalar/api"
],
"hosting_signup_link": "https://modular.im/?utm_source=riot-web&utm_medium=web",
"bug_report_endpoint_url": "https://riot.im/bugreports/submit",
"welcomeUserId": "@riot-bot:matrix.org",
"roomDirectory": {
"servers": [
"matrix.org"
]
},
"piwik": {
"url": "https://piwik.riot.im/",
"siteId": 1,
"policyUrl": "https://matrix.org/legal/riot-im-cookie-policy"
},
"phasedRollOut": {
"feature_lazyloading": {
"offset": 1539684000000,
"period": 604800000
}
},
"features": {
"feature_lazyloading": "enable"
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
"https://matrix-client.matrix.org": false
}
}

View File

@@ -1 +0,0 @@
export OSSLSIGNCODE_SIGNARGS='-pkcs11module /Library/Frameworks/eToken.framework/Versions/Current/libeToken.dylib -pkcs11engine /usr/local/lib/engines/engine_pkcs11.so -certs electron_app/riot.im/New_Vector_Ltd.pem -key 0a3271cbc1ec0fd8afb37f6bbe0cd65ba08d3b4d -t http://timestamp.comodoca.com -verbose'

View File

@@ -1,641 +0,0 @@
/*
Copyright 2016 Aviral Dasgupta
Copyright 2016 OpenMarket Ltd
Copyright 2018, 2019 New Vector Ltd
Copyright 2017, 2019 Michael Telatynski <7t3chguy@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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.
*/
// Squirrel on windows starts the app with various flags
// as hooks to tell us when we've been installed/uninstalled
// etc.
const checkSquirrelHooks = require('./squirrelhooks');
if (checkSquirrelHooks()) return;
const argv = require('minimist')(process.argv, {
alias: {help: "h"},
});
const {app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol} = require('electron');
const AutoLaunch = require('auto-launch');
const path = require('path');
const tray = require('./tray');
const vectorMenu = require('./vectormenu');
const webContentsHandler = require('./webcontents-handler');
const updater = require('./updater');
const protocolInit = require('./protocol');
const windowStateKeeper = require('electron-window-state');
const Store = require('electron-store');
const fs = require('fs');
const afs = fs.promises;
let Seshat = null;
try {
Seshat = require('matrix-seshat');
} catch (e) {
if (e.code === "MODULE_NOT_FOUND") {
console.log("Seshat isn't installed, event indexing is disabled.");
} else {
console.warn("Seshat unexpected error:", e);
}
}
if (argv["help"]) {
console.log("Options:");
console.log(" --profile-dir {path}: Path to where to store the profile.");
console.log(" --profile {name}: Name of alternate profile to use, allows for running multiple accounts.");
console.log(" --devtools: Install and use react-devtools and react-perf.");
console.log(" --no-update: Disable automatic updating.");
console.log(" --hidden: Start the application hidden in the system tray.");
console.log(" --help: Displays this help message.");
console.log("And more such as --proxy, see:" +
"https://electronjs.org/docs/api/chrome-command-line-switches#supported-chrome-command-line-switches");
app.exit();
}
if (argv['profile-dir']) {
app.setPath('userData', argv['profile-dir']);
} else if (argv['profile']) {
app.setPath('userData', `${app.getPath('userData')}-${argv['profile']}`);
}
let vectorConfig = {};
try {
vectorConfig = require('../../webapp/config.json');
} catch (e) {
// it would be nice to check the error code here and bail if the config
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
// file or invalid json, so node is just very unhelpful.
// Continue with the defaults (ie. an empty config)
}
try {
// Load local config and use it to override values from the one baked with the build
const localConfig = require(path.join(app.getPath('userData'), 'config.json'));
// If the local config has a homeserver defined, don't use the homeserver from the build
// config. This is to avoid a problem where Riot thinks there are multiple homeservers
// defined, and panics as a result.
const homeserverProps = ['default_is_url', 'default_hs_url', 'default_server_name', 'default_server_config'];
if (Object.keys(localConfig).find(k => homeserverProps.includes(k))) {
// Rip out all the homeserver options from the vector config
vectorConfig = Object.keys(vectorConfig)
.filter(k => !homeserverProps.includes(k))
.reduce((obj, key) => {obj[key] = vectorConfig[key]; return obj;}, {});
}
vectorConfig = Object.assign(vectorConfig, localConfig);
} catch (e) {
// Could not load local config, this is expected in most cases.
}
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
const store = new Store({ name: "electron-config" });
let eventIndex = null;
let mainWindow = null;
global.appQuitting = false;
// It's important to call `path.join` so we don't end up with the packaged asar in the final path.
const iconFile = `riot.${process.platform === 'win32' ? 'ico' : 'png'}`;
const iconPath = path.join(__dirname, "..", "..", "img", iconFile);
const trayConfig = {
icon_path: iconPath,
brand: vectorConfig.brand || 'Riot',
};
// handle uncaught errors otherwise it displays
// stack traces in popup dialogs, which is terrible (which
// it will do any time the auto update poke fails, and there's
// no other way to catch this error).
// Assuming we generally run from the console when developing,
// this is far preferable.
process.on('uncaughtException', function(error) {
console.log('Unhandled exception', error);
});
let focusHandlerAttached = false;
ipcMain.on('setBadgeCount', function(ev, count) {
app.setBadgeCount(count);
if (count === 0 && mainWindow) {
mainWindow.flashFrame(false);
}
});
ipcMain.on('loudNotification', function() {
if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused() && !focusHandlerAttached) {
mainWindow.flashFrame(true);
mainWindow.once('focus', () => {
mainWindow.flashFrame(false);
focusHandlerAttached = false;
});
focusHandlerAttached = true;
}
});
let powerSaveBlockerId = null;
ipcMain.on('app_onAction', function(ev, payload) {
switch (payload.action) {
case 'call_state':
if (powerSaveBlockerId !== null && powerSaveBlocker.isStarted(powerSaveBlockerId)) {
if (payload.state === 'ended') {
powerSaveBlocker.stop(powerSaveBlockerId);
powerSaveBlockerId = null;
}
} else {
if (powerSaveBlockerId === null && payload.state === 'connected') {
powerSaveBlockerId = powerSaveBlocker.start('prevent-display-sleep');
}
}
break;
}
});
autoUpdater.on('update-downloaded', (ev, releaseNotes, releaseName, releaseDate, updateURL) => {
if (!mainWindow) return;
// forward to renderer
mainWindow.webContents.send('update-downloaded', {
releaseNotes,
releaseName,
releaseDate,
updateURL,
});
});
ipcMain.on('ipcCall', async function(ev, payload) {
if (!mainWindow) return;
const args = payload.args || [];
let ret;
switch (payload.name) {
case 'getUpdateFeedUrl':
ret = autoUpdater.getFeedURL();
break;
case 'getAutoLaunchEnabled':
ret = await launcher.isEnabled();
break;
case 'setAutoLaunchEnabled':
if (args[0]) {
launcher.enable();
} else {
launcher.disable();
}
break;
case 'getMinimizeToTrayEnabled':
ret = tray.hasTray();
break;
case 'setMinimizeToTrayEnabled':
if (args[0]) {
// Create trayIcon icon
tray.create(trayConfig);
} else {
tray.destroy();
}
store.set('minimizeToTray', args[0]);
break;
case 'getAutoHideMenuBarEnabled':
ret = global.mainWindow.isMenuBarAutoHide();
break;
case 'setAutoHideMenuBarEnabled':
store.set('autoHideMenuBar', args[0]);
global.mainWindow.setAutoHideMenuBar(args[0]);
global.mainWindow.setMenuBarVisibility(!args[0]);
break;
case 'getAppVersion':
ret = app.getVersion();
break;
case 'focusWindow':
if (mainWindow.isMinimized()) {
mainWindow.restore();
} else if (!mainWindow.isVisible()) {
mainWindow.show();
} else {
mainWindow.focus();
}
break;
case 'getConfig':
ret = vectorConfig;
break;
default:
mainWindow.webContents.send('ipcReply', {
id: payload.id,
error: "Unknown IPC Call: " + payload.name,
});
return;
}
mainWindow.webContents.send('ipcReply', {
id: payload.id,
reply: ret,
});
});
ipcMain.on('seshat', async function(ev, payload) {
if (!mainWindow) return;
const sendError = (id, e) => {
const error = {
message: e.message
}
mainWindow.webContents.send('seshatReply', {
id:id,
error: error
});
}
const args = payload.args || [];
let ret;
switch (payload.name) {
case 'supportsEventIndexing':
if (Seshat === null) ret = false;
else ret = true;
break;
case 'initEventIndex':
if (eventIndex === null) {
try {
await afs.mkdir(eventStorePath, {recursive: true});
eventIndex = new Seshat(eventStorePath, {passphrase: "DEFAULT_PASSPHRASE"});
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'closeEventIndex':
eventIndex = null;
break;
case 'deleteEventIndex':
const deleteFolderRecursive = async(p) => {
for (let entry of await afs.readdir(p)) {
const curPath = path.join(p, entry);
await afs.unlink(curPath);
}
}
try {
await deleteFolderRecursive(eventStorePath);
} catch (e) {
}
break;
case 'isEventIndexEmpty':
if (eventIndex === null) ret = true;
else ret = await eventIndex.isEmpty();
break;
case 'addEventToIndex':
try {
eventIndex.addEvent(args[0], args[1]);
} catch (e) {
sendError(payload.id, e);
return;
}
break;
case 'commitLiveEvents':
try {
ret = await eventIndex.commit();
} catch (e) {
sendError(payload.id, e);
return;
}
break;
case 'searchEventIndex':
try {
ret = await eventIndex.search(args[0]);
} catch (e) {
sendError(payload.id, e);
return;
}
break;
case 'addHistoricEvents':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.addHistoricEvents(
args[0], args[1], args[2]);
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'getStats':
if (eventIndex === null) ret = 0;
else {
try {
ret = await eventIndex.getStats();
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'removeCrawlerCheckpoint':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.removeCrawlerCheckpoint(args[0]);
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'addCrawlerCheckpoint':
if (eventIndex === null) ret = false;
else {
try {
ret = await eventIndex.addCrawlerCheckpoint(args[0]);
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'loadFileEvents':
if (eventIndex === null) ret = [];
else {
try {
ret = await eventIndex.loadFileEvents(args[0]);
} catch (e) {
sendError(payload.id, e);
return;
}
}
break;
case 'loadCheckpoints':
if (eventIndex === null) ret = [];
else {
try {
ret = await eventIndex.loadCheckpoints();
} catch (e) {
ret = [];
}
}
break;
default:
mainWindow.webContents.send('seshatReply', {
id: payload.id,
error: "Unknown IPC Call: " + payload.name,
});
return;
}
mainWindow.webContents.send('seshatReply', {
id: payload.id,
reply: ret,
});
});
app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');
const gotLock = app.requestSingleInstanceLock();
if (!gotLock) {
console.log('Other instance detected: exiting');
app.exit();
}
// do this after we know we are the primary instance of the app
protocolInit();
const launcher = new AutoLaunch({
name: vectorConfig.brand || 'Riot',
isHidden: true,
mac: {
useLaunchAgent: true,
},
});
// Register the scheme the app is served from as 'standard'
// which allows things like relative URLs and IndexedDB to
// work.
// Also mark it as secure (ie. accessing resources from this
// protocol and HTTPS won't trigger mixed content warnings).
protocol.registerSchemesAsPrivileged([{
scheme: 'vector',
privileges: {
standard: true,
secure: true,
supportFetchAPI: true,
},
}]);
app.on('ready', () => {
if (argv['devtools']) {
try {
const { default: installExt, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
installExt(REACT_DEVELOPER_TOOLS)
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log('An error occurred: ', err));
installExt(REACT_PERF)
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log('An error occurred: ', err));
} catch (e) {
console.log(e);
}
}
protocol.registerFileProtocol('vector', (request, callback) => {
if (request.method !== 'GET') {
callback({error: -322}); // METHOD_NOT_SUPPORTED from chromium/src/net/base/net_error_list.h
return null;
}
const parsedUrl = new URL(request.url);
if (parsedUrl.protocol !== 'vector:') {
callback({error: -302}); // UNKNOWN_URL_SCHEME
return;
}
if (parsedUrl.host !== 'vector') {
callback({error: -105}); // NAME_NOT_RESOLVED
return;
}
const target = parsedUrl.pathname.split('/');
// path starts with a '/'
if (target[0] !== '') {
callback({error: -6}); // FILE_NOT_FOUND
return;
}
if (target[target.length - 1] == '') {
target[target.length - 1] = 'index.html';
}
let baseDir;
// first part of the path determines where we serve from
if (target[1] === 'webapp') {
baseDir = __dirname + "/../../webapp";
} else {
callback({error: -6}); // FILE_NOT_FOUND
return;
}
// Normalise the base dir and the target path separately, then make sure
// the target path isn't trying to back out beyond its root
baseDir = path.normalize(baseDir);
const relTarget = path.normalize(path.join(...target.slice(2)));
if (relTarget.startsWith('..')) {
callback({error: -6}); // FILE_NOT_FOUND
return;
}
const absTarget = path.join(baseDir, relTarget);
callback({
path: absTarget,
});
}, (error) => {
if (error) console.error('Failed to register protocol');
});
if (argv['no-update']) {
console.log('Auto update disabled via command line flag "--no-update"');
} else if (vectorConfig['update_base_url']) {
console.log(`Starting auto update with base URL: ${vectorConfig['update_base_url']}`);
updater.start(vectorConfig['update_base_url']);
} else {
console.log('No update_base_url is defined: auto update is disabled');
}
// Load the previous window state with fallback to defaults
const mainWindowState = windowStateKeeper({
defaultWidth: 1024,
defaultHeight: 768,
});
const preloadScript = path.normalize(`${__dirname}/preload.js`);
mainWindow = global.mainWindow = new BrowserWindow({
icon: iconPath,
show: false,
autoHideMenuBar: store.get('autoHideMenuBar', true),
x: mainWindowState.x,
y: mainWindowState.y,
width: mainWindowState.width,
height: mainWindowState.height,
webPreferences: {
preload: preloadScript,
nodeIntegration: false,
sandbox: true,
enableRemoteModule: false,
// We don't use this: it's useful for the preload script to
// share a context with the main page so we can give select
// objects to the main page. The sandbox option isolates the
// main page from the background script.
contextIsolation: false,
webgl: false,
},
});
mainWindow.loadURL('vector://vector/webapp/');
Menu.setApplicationMenu(vectorMenu);
// Create trayIcon icon
if (store.get('minimizeToTray', true)) tray.create(trayConfig);
mainWindow.once('ready-to-show', () => {
mainWindowState.manage(mainWindow);
if (!argv['hidden']) {
mainWindow.show();
} else {
// hide here explicitly because window manage above sometimes shows it
mainWindow.hide();
}
});
mainWindow.on('closed', () => {
mainWindow = global.mainWindow = null;
});
mainWindow.on('close', (e) => {
// If we are not quitting and have a tray icon then minimize to tray
if (!global.appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
// On Mac, closing the window just hides it
// (this is generally how single-window Mac apps
// behave, eg. Mail.app)
e.preventDefault();
mainWindow.hide();
return false;
}
});
if (process.platform === 'win32') {
// Handle forward/backward mouse buttons in Windows
mainWindow.on('app-command', (e, cmd) => {
if (cmd === 'browser-backward' && mainWindow.webContents.canGoBack()) {
mainWindow.webContents.goBack();
} else if (cmd === 'browser-forward' && mainWindow.webContents.canGoForward()) {
mainWindow.webContents.goForward();
}
});
}
webContentsHandler(mainWindow.webContents);
});
app.on('window-all-closed', () => {
app.quit();
});
app.on('activate', () => {
mainWindow.show();
});
app.on('before-quit', () => {
global.appQuitting = true;
if (mainWindow) {
mainWindow.webContents.send('before-quit');
}
});
app.on('second-instance', (ev, commandLine, workingDirectory) => {
// If other instance launched with --hidden then skip showing window
if (commandLine.includes('--hidden')) return;
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (!mainWindow.isVisible()) mainWindow.show();
if (mainWindow.isMinimized()) mainWindow.restore();
mainWindow.focus();
}
});
// Set the App User Model ID to match what the squirrel
// installer uses for the shortcut icon.
// This makes notifications work on windows 8.1 (and is
// a noop on other platforms).
app.setAppUserModelId('com.squirrel.riot-web.Riot');

View File

@@ -1,53 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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.
*/
const {app} = require('electron');
const processUrl = (url) => {
if (!global.mainWindow) return;
console.log("Handling link: ", url);
global.mainWindow.loadURL(url.replace("riot://", "vector://"));
};
module.exports = () => {
// get all args except `hidden` as it'd mean the app would not get focused
// XXX: passing args to protocol handlers only works on Windows,
// so unpackaged deep-linking and --profile passing won't work on Mac/Linux
const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
if (app.isPackaged) {
app.setAsDefaultProtocolClient('riot', process.execPath, args);
} else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
// special handler for running without being packaged, e.g `electron .` by passing our app path to electron
app.setAsDefaultProtocolClient('riot', process.execPath, [app.getAppPath(), ...args]);
}
if (process.platform === 'darwin') {
// Protocol handler for macos
app.on('open-url', function(ev, url) {
ev.preventDefault();
processUrl(url);
});
} else {
// Protocol handler for win32/Linux
app.on('second-instance', (ev, commandLine) => {
const url = commandLine[commandLine.length - 1];
if (!url.startsWith("riot://")) return;
processUrl(url);
});
}
};

View File

@@ -1,106 +0,0 @@
/*
Copyright 2017 Karl Glatz <karl@glatz.biz>
Copyright 2017 OpenMarket 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.
*/
const {app, Tray, Menu, nativeImage} = require('electron');
const pngToIco = require('png-to-ico');
const path = require('path');
const fs = require('fs');
let trayIcon = null;
exports.hasTray = function hasTray() {
return (trayIcon !== null);
};
exports.destroy = function() {
if (trayIcon) {
trayIcon.destroy();
trayIcon = null;
}
};
exports.create = function(config) {
// no trays on darwin
if (process.platform === 'darwin' || trayIcon) return;
const toggleWin = function() {
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
global.mainWindow.hide();
} else {
if (global.mainWindow.isMinimized()) global.mainWindow.restore();
if (!global.mainWindow.isVisible()) global.mainWindow.show();
global.mainWindow.focus();
}
};
const contextMenu = Menu.buildFromTemplate([
{
label: `Show/Hide ${config.brand}`,
click: toggleWin,
},
{ type: 'separator' },
{
label: 'Quit',
click: function() {
app.quit();
},
},
]);
const defaultIcon = nativeImage.createFromPath(config.icon_path);
trayIcon = new Tray(defaultIcon);
trayIcon.setToolTip(config.brand);
trayIcon.setContextMenu(contextMenu);
trayIcon.on('click', toggleWin);
let lastFavicon = null;
global.mainWindow.webContents.on('page-favicon-updated', async function(ev, favicons) {
if (!favicons || favicons.length <= 0 || !favicons[0].startsWith('data:')) {
if (lastFavicon !== null) {
global.mainWindow.setIcon(defaultIcon);
trayIcon.setImage(defaultIcon);
lastFavicon = null;
}
return;
}
// No need to change, shortcut
if (favicons[0] === lastFavicon) return;
lastFavicon = favicons[0];
let newFavicon = nativeImage.createFromDataURL(favicons[0]);
// Windows likes ico's too much.
if (process.platform === 'win32') {
try {
const icoPath = path.join(app.getPath('temp'), 'win32_riot_icon.ico');
fs.writeFileSync(icoPath, await pngToIco(newFavicon.toPNG()));
newFavicon = nativeImage.createFromPath(icoPath);
} catch (e) {
console.error("Failed to make win32 ico", e);
}
}
trayIcon.setImage(newFavicon);
global.mainWindow.setIcon(newFavicon);
});
global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
trayIcon.setToolTip(title);
});
};

View File

@@ -1,84 +0,0 @@
const { app, autoUpdater, ipcMain } = require('electron');
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
function installUpdate() {
// for some reason, quitAndInstall does not fire the
// before-quit event, so we need to set the flag here.
global.appQuitting = true;
autoUpdater.quitAndInstall();
}
function pollForUpdates() {
try {
autoUpdater.checkForUpdates();
} catch (e) {
console.log('Couldn\'t check for update', e);
}
}
module.exports = {};
module.exports.start = function startAutoUpdate(updateBaseUrl) {
if (updateBaseUrl.slice(-1) !== '/') {
updateBaseUrl = updateBaseUrl + '/';
}
try {
let url;
// For reasons best known to Squirrel, the way it checks for updates
// is completely different between macOS and windows. On macOS, it
// hits a URL that either gives it a 200 with some json or
// 204 No Content. On windows it takes a base path and looks for
// files under that path.
if (process.platform === 'darwin') {
// include the current version in the URL we hit. Electron doesn't add
// it anywhere (apart from the User-Agent) so it's up to us. We could
// (and previously did) just use the User-Agent, but this doesn't
// rely on NSURLConnection setting the User-Agent to what we expect,
// and also acts as a convenient cache-buster to ensure that when the
// app updates it always gets a fresh value to avoid update-looping.
url = `${updateBaseUrl}macos/?localVersion=${encodeURIComponent(app.getVersion())}`;
} else if (process.platform === 'win32') {
url = `${updateBaseUrl}win32/${process.arch}/`;
} else {
// Squirrel / electron only supports auto-update on these two platforms.
// I'm not even going to try to guess which feed style they'd use if they
// implemented it on Linux, or if it would be different again.
console.log('Auto update not supported on this platform');
}
if (url) {
autoUpdater.setFeedURL(url);
// We check for updates ourselves rather than using 'updater' because we need to
// do it in the main process (and we don't really need to check every 10 minutes:
// every hour should be just fine for a desktop app)
// However, we still let the main window listen for the update events.
// We also wait a short time before checking for updates the first time because
// of squirrel on windows and it taking a small amount of time to release a
// lock file.
setTimeout(pollForUpdates, INITIAL_UPDATE_DELAY_MS);
setInterval(pollForUpdates, UPDATE_POLL_INTERVAL_MS);
}
} catch (err) {
// will fail if running in debug mode
console.log('Couldn\'t enable update checking', err);
}
}
ipcMain.on('install_update', installUpdate);
ipcMain.on('check_updates', pollForUpdates);
function ipcChannelSendUpdateStatus(status) {
if (global.mainWindow) {
global.mainWindow.webContents.send('check_updates', status);
}
}
autoUpdater.on('update-available', function() {
ipcChannelSendUpdateStatus(true);
}).on('update-not-available', function() {
ipcChannelSendUpdateStatus(false);
}).on('error', function(error) {
ipcChannelSendUpdateStatus(error.message);
});

View File

@@ -1,139 +0,0 @@
/*
Copyright 2016 OpenMarket 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.
*/
const {app, shell, Menu} = require('electron');
// Menu template from http://electron.atom.io/docs/api/menu/, edited
const template = [
{
label: '&Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
{ role: 'pasteandmatchstyle' },
{ role: 'delete' },
{ role: 'selectall' },
],
},
{
label: '&View',
submenu: [
{ type: 'separator' },
{ role: 'resetzoom' },
{ role: 'zoomin', accelerator: 'CommandOrControl+=' },
{ role: 'zoomout' },
{ type: 'separator' },
{ role: 'togglefullscreen' },
{ role: 'toggledevtools' },
],
},
{
label: '&Window',
role: 'window',
submenu: [
{ role: 'minimize' },
{ role: 'close' },
],
},
{
label: '&Help',
role: 'help',
submenu: [
{
label: 'Riot Help',
click() { shell.openExternal('https://about.riot.im/help'); },
},
],
},
];
// macOS has specific menu conventions...
if (process.platform === 'darwin') {
// first macOS menu is the name of the app
const name = app.getName();
template.unshift({
label: name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{
role: 'services',
submenu: [],
},
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' },
],
});
// Edit menu.
// This has a 'speech' section on macOS
template[1].submenu.push(
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startspeaking' },
{ role: 'stopspeaking' },
],
});
// Window menu.
// This also has specific functionality on macOS
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close',
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize',
},
{
label: 'Zoom',
role: 'zoom',
},
{
type: 'separator',
},
{
label: 'Bring All to Front',
role: 'front',
},
];
} else {
template.unshift({
label: '&File',
submenu: [
// For some reason, 'about' does not seem to work on windows.
/*{
role: 'about'
},*/
{ role: 'quit' },
],
});
}
module.exports = Menu.buildFromTemplate(template);

View File

@@ -1,191 +0,0 @@
const {clipboard, nativeImage, Menu, MenuItem, shell, dialog} = require('electron');
const url = require('url');
const fs = require('fs');
const request = require('request');
const MAILTO_PREFIX = "mailto:";
const PERMITTED_URL_SCHEMES = [
'http:',
'https:',
MAILTO_PREFIX,
];
function safeOpenURL(target) {
// openExternal passes the target to open/start/xdg-open,
// so put fairly stringent limits on what can be opened
// (for instance, open /bin/sh does indeed open a terminal
// with a shell, albeit with no arguments)
const parsedUrl = url.parse(target);
if (PERMITTED_URL_SCHEMES.indexOf(parsedUrl.protocol) > -1) {
// explicitly use the URL re-assembled by the url library,
// so we know the url parser has understood all the parts
// of the input string
const newTarget = url.format(parsedUrl);
shell.openExternal(newTarget);
}
}
function onWindowOrNavigate(ev, target) {
// always prevent the default: if something goes wrong,
// we don't want to end up opening it in the electron
// app, as we could end up opening any sort of random
// url in a window that has node scripting access.
ev.preventDefault();
safeOpenURL(target);
}
function onLinkContextMenu(ev, params) {
let url = params.linkURL || params.srcURL;
if (url.startsWith('vector://vector/webapp')) {
url = "https://riot.im/app/" + url.substring(23);
}
const popupMenu = new Menu();
// No point trying to open blob: URLs in an external browser: it ain't gonna work.
if (!url.startsWith('blob:')) {
popupMenu.append(new MenuItem({
label: url,
click() {
safeOpenURL(url);
},
}));
}
let addSaveAs = false;
if (params.mediaType && params.mediaType === 'image' && !url.startsWith('file://')) {
popupMenu.append(new MenuItem({
label: '&Copy image',
click() {
if (url.startsWith('data:')) {
clipboard.writeImage(nativeImage.createFromDataURL(url));
} else {
ev.sender.copyImageAt(params.x, params.y);
}
},
}));
// We want the link to be ordered below the copy stuff, but don't want to duplicate
// the `if` statement, so use a flag.
addSaveAs = true;
}
// No point offering to copy a blob: URL either
if (!url.startsWith('blob:')) {
// Special-case e-mail URLs to strip the `mailto:` like modern browsers do
if (url.startsWith(MAILTO_PREFIX)) {
popupMenu.append(new MenuItem({
label: 'Copy email &address',
click() {
clipboard.writeText(url.substr(MAILTO_PREFIX.length));
},
}));
} else {
popupMenu.append(new MenuItem({
label: 'Copy link &address',
click() {
clipboard.writeText(url);
},
}));
}
}
if (addSaveAs) {
popupMenu.append(new MenuItem({
label: 'Sa&ve image as...',
click() {
const targetFileName = params.titleText || "image.png";
const filePath = dialog.showSaveDialog({
defaultPath: targetFileName,
});
if (!filePath) return; // user cancelled dialog
try {
if (url.startsWith("data:")) {
fs.writeFileSync(filePath, nativeImage.createFromDataURL(url));
} else {
request.get(url).pipe(fs.createWriteStream(filePath));
}
} catch (err) {
console.error(err);
dialog.showMessageBox({
type: "error",
title: "Failed to save image",
message: "The image failed to save",
});
}
},
}));
}
// popup() requires an options object even for no options
popupMenu.popup({});
ev.preventDefault();
}
function _CutCopyPasteSelectContextMenus(params) {
return [{
role: 'cut',
label: 'Cu&t',
enabled: params.editFlags.canCut,
}, {
role: 'copy',
label: '&Copy',
enabled: params.editFlags.canCopy,
}, {
role: 'paste',
label: '&Paste',
enabled: params.editFlags.canPaste,
}, {
role: 'pasteandmatchstyle',
enabled: params.editFlags.canPaste,
}, {
role: 'selectall',
label: "Select &All",
enabled: params.editFlags.canSelectAll,
}];
}
function onSelectedContextMenu(ev, params) {
const items = _CutCopyPasteSelectContextMenus(params);
const popupMenu = Menu.buildFromTemplate(items);
// popup() requires an options object even for no options
popupMenu.popup({});
ev.preventDefault();
}
function onEditableContextMenu(ev, params) {
const items = [
{ role: 'undo' },
{ role: 'redo', enabled: params.editFlags.canRedo },
{ type: 'separator' },
].concat(_CutCopyPasteSelectContextMenus(params));
const popupMenu = Menu.buildFromTemplate(items);
// popup() requires an options object even for no options
popupMenu.popup({});
ev.preventDefault();
}
module.exports = (webContents) => {
webContents.on('new-window', onWindowOrNavigate);
webContents.on('will-navigate', (ev, target) => {
if (target.startsWith("vector://")) return;
return onWindowOrNavigate(ev, target);
});
webContents.on('context-menu', function(ev, params) {
if (params.linkURL || params.srcURL) {
onLinkContextMenu(ev, params);
} else if (params.selectionText) {
onSelectedContextMenu(ev, params);
} else if (params.isEditable) {
onEditableContextMenu(ev, params);
}
});
};

View File

@@ -1,837 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@^9.4.0":
version "9.6.45"
resolved "https://registry.yarnpkg.com/@types/node/-/node-9.6.45.tgz#a9e5cfd026a3abaaf17e3c0318a470da9f2f178e"
integrity sha512-9scD7xI1kpIoMs3gVFMOWsWDyRIQ1AOZwe56i1CQPE6N/P4POYkn9UtW5F66t8C2AIoPtVfOFycQ2r11t3pcyg==
ajv@^6.5.5:
version "6.10.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==
dependencies:
fast-deep-equal "^2.0.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
applescript@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317"
integrity sha1-u4evVoytA0pOSMS9r2Bno6JwExc=
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
auto-launch@^5.0.1:
version "5.0.5"
resolved "https://registry.yarnpkg.com/auto-launch/-/auto-launch-5.0.5.tgz#d14bd002b1ef642f85e991a6195ff5300c8ad3c0"
integrity sha512-ppdF4mihhYzMYLuCcx9H/c5TUOCev8uM7en53zWVQhyYAJrurd2bFZx3qQVeJKF2jrc7rsPRNN5cD+i23l6PdA==
dependencies:
applescript "^1.0.0"
mkdirp "^0.5.1"
path-is-absolute "^1.0.0"
untildify "^3.0.2"
winreg "1.2.4"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.8.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
bignumber.js@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8"
integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=
bmp-js@0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a"
integrity sha1-ZBE+nHzxICs3btYHvzBibr5XsYo=
buffer-equal@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b"
integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
dependencies:
delayed-stream "~1.0.0"
conf@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/conf/-/conf-2.2.0.tgz#ee282efafc1450b61e205372041ad7d866802d9a"
integrity sha512-93Kz74FOMo6aWRVpAZsonOdl2I57jKtHrNmxhumehFQw4X8Sk37SohNY11PG7Q8Okta+UnrVaI006WLeyp8/XA==
dependencies:
dot-prop "^4.1.0"
env-paths "^1.0.0"
make-dir "^1.0.0"
pkg-up "^2.0.0"
write-file-atomic "^2.3.0"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
define-properties@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
dependencies:
object-keys "^1.0.12"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
dom-walk@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=
dot-prop@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==
dependencies:
is-obj "^1.0.0"
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
electron-store@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/electron-store/-/electron-store-2.0.0.tgz#1035cca2a95409d1f54c7466606345852450d64a"
integrity sha512-1WCFYHsYvZBqDsoaS0Relnz0rd81ZkBAI0Fgx7Nq2UWU77rSNs1qxm4S6uH7TCZ0bV3LQpJFk7id/is/ZgoOPA==
dependencies:
conf "^2.0.0"
electron-window-state@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/electron-window-state/-/electron-window-state-4.1.1.tgz#6b34fdc31b38514dfec8b7c8f7b5d4addb67632d"
integrity sha1-azT9wxs4UU3+yLfI97XUrdtnYy0=
dependencies:
deep-equal "^1.0.1"
jsonfile "^2.2.3"
mkdirp "^0.5.1"
env-paths@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
es-abstract@^1.5.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==
dependencies:
es-to-primitive "^1.2.0"
function-bind "^1.1.1"
has "^1.0.3"
is-callable "^1.1.4"
is-regex "^1.0.4"
object-keys "^1.0.12"
es-to-primitive@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
dependencies:
is-callable "^1.1.4"
is-date-object "^1.0.1"
is-symbol "^1.0.2"
es6-promise@^3.0.2:
version "3.3.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613"
integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=
exif-parser@^0.1.9:
version "0.1.12"
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-deep-equal@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
file-type@^3.1.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9"
integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek=
find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
dependencies:
locate-path "^2.0.0"
for-each@^0.3.3:
version "0.3.3"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==
dependencies:
is-callable "^1.1.3"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
function-bind@^1.0.2, function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
global@~4.3.0:
version "4.3.2"
resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f"
integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=
dependencies:
min-document "^2.19.0"
process "~0.5.1"
graceful-fs@^4.1.11, graceful-fs@^4.1.6:
version "4.1.15"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.1.0:
version "5.1.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
dependencies:
ajv "^6.5.5"
har-schema "^2.0.0"
has-symbols@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
has@^1.0.1, has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
ip-regex@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd"
integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=
is-callable@^1.1.3, is-callable@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
is-date-object@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=
is-function@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
integrity sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=
is-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f"
integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8=
is-regex@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
dependencies:
has "^1.0.1"
is-symbol@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==
dependencies:
has-symbols "^1.0.0"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
jimp@^0.2.28:
version "0.2.28"
resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2"
integrity sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=
dependencies:
bignumber.js "^2.1.0"
bmp-js "0.0.3"
es6-promise "^3.0.2"
exif-parser "^0.1.9"
file-type "^3.1.0"
jpeg-js "^0.2.0"
load-bmfont "^1.2.3"
mime "^1.3.4"
mkdirp "0.5.1"
pixelmatch "^4.0.0"
pngjs "^3.0.0"
read-chunk "^1.0.1"
request "^2.65.0"
stream-to-buffer "^0.1.0"
tinycolor2 "^1.1.2"
url-regex "^3.0.0"
jpeg-js@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482"
integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII=
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
jsonfile@^2.2.3:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
optionalDependencies:
graceful-fs "^4.1.6"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
load-bmfont@^1.2.3:
version "1.4.0"
resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b"
integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==
dependencies:
buffer-equal "0.0.1"
mime "^1.3.4"
parse-bmfont-ascii "^1.0.3"
parse-bmfont-binary "^1.0.5"
parse-bmfont-xml "^1.1.4"
phin "^2.9.1"
xhr "^2.0.1"
xtend "^4.0.0"
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
dependencies:
p-locate "^2.0.0"
path-exists "^3.0.0"
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==
dependencies:
pify "^3.0.0"
mime-db@~1.38.0:
version "1.38.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.38.0.tgz#1a2aab16da9eb167b49c6e4df2d9c68d63d8e2ad"
integrity sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.22"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.22.tgz#fe6b355a190926ab7698c9a0556a11199b2199bd"
integrity sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==
dependencies:
mime-db "~1.38.0"
mime@^1.3.4:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
dependencies:
dom-walk "^0.1.0"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
mkdirp@0.5.1, mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-keys@^1.0.12:
version "1.1.0"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.0.tgz#11bd22348dd2e096a045ab06f6c85bcc340fa032"
integrity sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==
p-limit@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8"
integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
dependencies:
p-try "^1.0.0"
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
dependencies:
p-limit "^1.1.0"
p-try@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
parse-bmfont-ascii@^1.0.3:
version "1.0.6"
resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285"
integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=
parse-bmfont-binary@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006"
integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=
parse-bmfont-xml@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389"
integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==
dependencies:
xml-parse-from-string "^1.0.0"
xml2js "^0.4.5"
parse-headers@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.2.tgz#9545e8a4c1ae5eaea7d24992bca890281ed26e34"
integrity sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==
dependencies:
for-each "^0.3.3"
string.prototype.trim "^1.1.2"
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
phin@^2.9.1:
version "2.9.3"
resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c"
integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
pixelmatch@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854"
integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=
dependencies:
pngjs "^3.0.0"
pkg-up@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
integrity sha1-yBmscoBZpGHKscOImivjxJoATX8=
dependencies:
find-up "^2.1.0"
png-to-ico@^1.0.2:
version "1.0.7"
resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-1.0.7.tgz#9346b5f4d6fd7e94cb08fd49eeb585f501c3e5f2"
integrity sha512-heHiZjPFhVgLiuSG4C4wwKN9YPGLpPJvOfXRyI+cEJf0vPutjJ4XDaeI2f/hzTFs+2juihDw3pP8R5JtTuQTGg==
dependencies:
"@types/node" "^9.4.0"
jimp "^0.2.28"
minimist "^1.2.0"
pngjs@^3.0.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
process@~0.5.1:
version "0.5.2"
resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf"
integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=
psl@^1.1.24:
version "1.1.31"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.31.tgz#e9aa86d0101b5b105cbe93ac6b784cd547276184"
integrity sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
punycode@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
read-chunk@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194"
integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=
request@^2.65.0:
version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.0"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.4.3"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
sax@>=0.6.0:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
stream-to-buffer@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9"
integrity sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=
dependencies:
stream-to "~0.2.0"
stream-to@~0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d"
integrity sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0=
string.prototype.trim@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=
dependencies:
define-properties "^1.1.2"
es-abstract "^1.5.0"
function-bind "^1.0.2"
tinycolor2@^1.1.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
tough-cookie@~2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
dependencies:
psl "^1.1.24"
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
untildify@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9"
integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
dependencies:
punycode "^2.1.0"
url-regex@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724"
integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=
dependencies:
ip-regex "^1.0.1"
uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
winreg@1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
integrity sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=
write-file-atomic@^2.3.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.2.tgz#a7181706dfba17855d221140a9c06e15fcdd87b9"
integrity sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==
dependencies:
graceful-fs "^4.1.11"
imurmurhash "^0.1.4"
signal-exit "^3.0.2"
xhr@^2.0.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"
integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==
dependencies:
global "~4.3.0"
is-function "^1.0.1"
parse-headers "^2.0.0"
xtend "^4.0.0"
xml-parse-from-string@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28"
integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
xml2js@^0.4.5:
version "0.4.19"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==
dependencies:
sax ">=0.6.0"
xmlbuilder "~9.0.1"
xmlbuilder@~9.0.1:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=
xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68=

147
karma.conf.js Normal file
View File

@@ -0,0 +1,147 @@
// karma.conf.js - the config file for karma, which runs our tests.
var path = require('path');
var webpack = require('webpack');
var webpack_config = require('./webpack.config');
/*
* We use webpack to build our tests. It's a pain to have to wait for webpack
* to build everything; however it's the easiest way to load our dependencies
* from node_modules.
*
* If you run karma in multi-run mode (with `npm run test-multi`), it will watch
* the tests for changes, and webpack will rebuild using a cache. This is much quicker
* than a clean rebuild.
*/
// the name of the test file. By default, a special file which runs all tests.
var testFile = process.env.KARMA_TEST_FILE || 'test/all-tests.js';
process.env.PHANTOMJS_BIN = 'node_modules/.bin/phantomjs';
process.env.Q_DEBUG = 1;
/* the webpack config is based on the real one, to (a) try to simulate the
* deployed environment as closely as possible, and (b) to avoid a shedload of
* cut-and-paste.
*/
// find out if we're shipping olm, and where it is, if so.
const olm_entry = webpack_config.entry['olm'];
// remove the default entries - karma provides its own (via the 'files' and
// 'preprocessors' config below)
delete webpack_config['entry'];
// add ./test as a search path for js
webpack_config.module.loaders.unshift({
test: /\.js$/, loader: "babel",
include: [path.resolve('./src'), path.resolve('./test')],
});
// disable parsing for sinon, because it
// tries to do voodoo with 'require' which upsets
// webpack (https://github.com/webpack/webpack/issues/304)
webpack_config.module.noParse.push(/sinon\/pkg\/sinon\.js$/);
// ?
webpack_config.resolve.alias['sinon'] = 'sinon/pkg/sinon.js';
webpack_config.resolve.root = [
path.resolve('./src'),
path.resolve('./test'),
];
webpack_config.devtool = 'inline-source-map';
module.exports = function (config) {
const myconfig = {
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha'],
// list of files / patterns to load in the browser
files: [
'node_modules/babel-polyfill/browser.js',
testFile,
// make the images available via our httpd. They will be avaliable
// below http://localhost:[PORT]/base/. See also `proxies` which
// defines alternative URLs for them.
//
// This isn't required by any of the tests, but it stops karma
// logging warnings when it serves a 404 for them.
{
pattern: 'src/skins/vector/img/*',
watched: false, included: false, served: true, nocache: false,
},
],
proxies: {
// redirect img links to the karma server. See above.
"/img/": "/base/src/skins/vector/img/",
},
// preprocess matching files before serving them to the browser
// available preprocessors:
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'{src,test}/**/*.js': ['webpack'],
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'junit'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR ||
// config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file
// changes
autoWatch: true,
// start these browsers
// available browser launchers:
// https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'Chrome',
//'PhantomJS',
],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
// singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
junitReporter: {
outputDir: 'karma-reports',
},
webpack: webpack_config,
webpackMiddleware: {
stats: {
// don't fill the console up with a mahoosive list of modules
chunks: false,
},
},
};
// include the olm loader if we have it.
if (olm_entry) {
myconfig.files.unshift(olm_entry);
}
config.set(myconfig);
};

View File

@@ -1,226 +1,167 @@
{ {
"name": "riot-web", "name": "riot-web",
"productName": "Riot", "productName": "Riot",
"main": "electron_app/src/electron-main.js", "main": "electron/src/electron-main.js",
"version": "1.5.13", "version": "0.9.7",
"description": "A feature-rich client for Matrix.org", "description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.", "author": "Vector Creations Ltd.",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/vector-im/riot-web" "url": "https://github.com/vector-im/riot-web"
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"files": [ "files": [
"lib",
"res",
"src",
"webpack.config.js",
"scripts",
"docs",
"release.sh",
"deploy",
"CHANGELOG.md",
"CONTRIBUTING.rst",
"LICENSE",
"README.md",
"AUTHORS.rst", "AUTHORS.rst",
"package.json", "CONTRIBUTING.rst",
"contribute.json" "deploy",
"docs",
"karma.conf.js",
"lib",
"release.sh",
"scripts",
"src",
"test",
"webpack.config.js"
], ],
"style": "bundle.css", "style": "bundle.css",
"matrix-react-parent": "matrix-react-sdk",
"scripts": { "scripts": {
"i18n": "matrix-gen-i18n",
"prunei18n": "matrix-prune-i18n",
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && yarn i18n && node scripts/compare-file.js src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
"reskindex": "reskindex -h src/header", "reskindex": "reskindex -h src/header",
"reskindex:watch": "reskindex -h src/header -w",
"reskindex:watch-react": "node scripts/yarn-sub.js matrix-react-sdk reskindex:watch",
"clean": "rimraf lib webapp electron_app/dist",
"build": "yarn clean && yarn build:genfiles && yarn build:compile && yarn build:types && yarn build:bundle",
"build:res": "node scripts/copy-res.js", "build:res": "node scripts/copy-res.js",
"build:genfiles": "yarn reskindex && yarn build:res",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js", "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
"build:compile": "babel -d lib --verbose --extensions \".ts,.js\" src", "build:compile": "babel --source-maps -d lib src",
"build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail --mode production", "build:bundle": "NODE_ENV=production webpack -p --progress",
"build:electron": "yarn build && yarn install:electron && electron-builder -wml --ia32 --x64", "build:bundle:dev": "webpack --optimize-occurence-order --progress",
"build:electron:linux": "yarn build && electron-builder -l --x64", "build:electron": "npm run clean && npm run build && build -wml --ia32 --x64",
"build:electron:macos": "yarn build && electron-builder -m --x64", "build": "node scripts/babelcheck.js && npm run build:res && npm run build:bundle",
"build:electron:windows": "yarn build && electron-builder -w --ia32 --x64", "build:dev": "node scripts/babelcheck.js && npm run build:res && npm run build:bundle:dev",
"build:types": "tsc --emitDeclarationOnly",
"install:electron": "electron-builder install-app-deps",
"dist": "scripts/package.sh", "dist": "scripts/package.sh",
"start": "concurrently --kill-others-on-fail --prefix \"{time} [{name}]\" -n reskindex,reskindex-react,res,riot-js \"yarn reskindex:watch\" \"yarn reskindex:watch-react\" \"yarn start:res\" \"yarn start:js\"",
"start:res": "node scripts/copy-res.js -w", "start:res": "node scripts/copy-res.js -w",
"start:js": "webpack-dev-server --host=0.0.0.0 --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js -w --progress --mode development", "start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-file=bundles/_dev_/[name].js -w --progress",
"electron": "yarn build && yarn install:electron && electron .", "start:js:prod": "NODE_ENV=production webpack-dev-server -w --progress",
"lint": "yarn lint:types && yarn lint:ts && yarn lint:js && yarn lint:style", "start": "node scripts/babelcheck.js && parallelshell \"npm run start:res\" \"npm run start:js\"",
"lint:js": "eslint src", "start:prod": "parallelshell \"npm run start:res\" \"npm run start:js:prod\"",
"lint:ts": "echo 'We don't actually have a typescript linter at this layer because tslint is being removed from our stack. Presumably your TS is fine.'", "lint": "eslint src/",
"lint:types": "tsc --noEmit", "lintall": "eslint src/ test/",
"lint:style": "stylelint 'res/css/**/*.scss'", "clean": "rimraf lib webapp electron/dist",
"test": "jest" "prepublish": "npm run build:compile",
"test": "karma start --single-run=true --autoWatch=false --browsers PhantomJS --colors=false",
"test-multi": "karma start"
}, },
"dependencies": { "dependencies": {
"babel-polyfill": "^6.5.0",
"babel-runtime": "^6.11.6",
"browser-request": "^0.3.3", "browser-request": "^0.3.3",
"classnames": "^2.1.2",
"draft-js": "^0.8.1",
"extract-text-webpack-plugin": "^0.9.1",
"favico.js": "^0.3.10", "favico.js": "^0.3.10",
"gemini-scrollbar": "github:matrix-org/gemini-scrollbar#91e1e566", "filesize": "^3.1.2",
"gfm.css": "^1.1.2", "flux": "~2.0.3",
"highlight.js": "^9.13.1", "gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
"matrix-js-sdk": "5.1.1", "gfm.css": "^1.1.1",
"matrix-react-sdk": "2.2.3", "highlight.js": "^9.0.0",
"olm": "https://packages.matrix.org/npm/olm/olm-3.1.4.tgz", "linkifyjs": "^2.1.3",
"postcss-easings": "^2.0.0", "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
"prop-types": "^15.7.2", "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
"react": "^16.9.0", "modernizr": "^3.1.0",
"react-dom": "^16.9.0", "q": "^1.4.1",
"sanitize-html": "^1.19.1", "react": "^15.4.0",
"ua-parser-js": "^0.7.19", "react-dnd": "^2.1.4",
"react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.4.0",
"react-gemini-scrollbar": "matrix-org/react-gemini-scrollbar#5e97aef",
"sanitize-html": "^1.11.1",
"ua-parser-js": "^0.7.10",
"url": "^0.11.0" "url": "^0.11.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.7.5", "autoprefixer": "^6.6.0",
"@babel/core": "^7.7.5", "babel-cli": "^6.5.2",
"@babel/plugin-proposal-class-properties": "^7.7.4", "babel-core": "^6.14.0",
"@babel/plugin-proposal-decorators": "^7.7.4", "babel-eslint": "^6.1.0",
"@babel/plugin-proposal-export-default-from": "^7.7.4", "babel-loader": "^6.2.5",
"@babel/plugin-proposal-numeric-separator": "^7.7.4", "babel-plugin-add-module-exports": "^0.2.1",
"@babel/plugin-proposal-object-rest-spread": "^7.7.4", "babel-plugin-transform-async-to-generator": "^6.16.0",
"@babel/plugin-syntax-dynamic-import": "^7.7.4", "babel-plugin-transform-class-properties": "^6.16.0",
"@babel/plugin-transform-flow-comments": "^7.7.4", "babel-plugin-transform-object-rest-spread": "^6.16.0",
"@babel/plugin-transform-runtime": "^7.7.6", "babel-plugin-transform-runtime": "^6.15.0",
"@babel/preset-env": "^7.7.6", "babel-preset-es2015": "^6.16.0",
"@babel/preset-flow": "^7.7.4", "babel-preset-es2016": "^6.16.0",
"@babel/preset-react": "^7.7.4", "babel-preset-es2017": "^6.16.0",
"@babel/preset-typescript": "^7.7.4", "babel-preset-react": "^6.16.0",
"@babel/register": "^7.7.4", "babel-preset-stage-2": "^6.17.0",
"@babel/runtime": "^7.7.6", "chokidar": "^1.6.1",
"@types/react": "^16.9.17",
"@types/react-dom": "^16.9.4",
"autoprefixer": "^9.7.3",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.6",
"canvas": "^2.6.1",
"chokidar": "^3.3.1",
"concurrently": "^4.0.1",
"cpx": "^1.3.2", "cpx": "^1.3.2",
"cross-env": "^6.0.3", "css-raw-loader": "^0.1.1",
"css-loader": "^3.3.2", "electron-builder": "^11.2.4",
"electron-builder": "^22.3.2", "electron-builder-squirrel-windows": "^11.2.1",
"electron-builder-squirrel-windows": "^22.3.2", "emojione": "^2.2.3",
"electron-devtools-installer": "^2.2.4", "eslint": "^3.14.0",
"electron-notarize": "^0.2.0",
"eslint": "^5.8.0",
"eslint-config-google": "^0.7.1", "eslint-config-google": "^0.7.1",
"eslint-plugin-babel": "^4.1.2", "eslint-plugin-flowtype": "^2.30.0",
"eslint-plugin-flowtype": "^2.50.3", "eslint-plugin-react": "^6.9.0",
"eslint-plugin-jest": "^23.0.4", "expect": "^1.16.0",
"eslint-plugin-react": "^7.11.1",
"eslint-plugin-react-hooks": "^2.2.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"fake-indexeddb": "^3.0.0",
"file-loader": "^5.0.2",
"fs-extra": "^0.30.0", "fs-extra": "^0.30.0",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^2.24.0",
"jest": "^24.9.0",
"jest-environment-jsdom-fourteen": "^1.0.1",
"json-loader": "^0.5.3", "json-loader": "^0.5.3",
"loader-utils": "^1.2.3", "karma": "^0.13.22",
"matrix-mock-request": "^1.2.3", "karma-chrome-launcher": "^0.2.3",
"matrix-react-test-utils": "^0.2.2", "karma-cli": "^0.1.2",
"mini-css-extract-plugin": "^0.8.0", "karma-junit-reporter": "^0.4.1",
"karma-mocha": "^0.2.2",
"karma-phantomjs-launcher": "^1.0.0",
"karma-webpack": "^1.7.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"modernizr": "^3.6.0", "mocha": "^2.4.5",
"optimize-css-assets-webpack-plugin": "^5.0.3", "parallelshell": "^1.2.0",
"phantomjs-prebuilt": "^2.1.7",
"postcss-extend": "^1.0.5", "postcss-extend": "^1.0.5",
"postcss-import": "^12.0.1", "postcss-import": "^9.0.0",
"postcss-loader": "^3.0.0", "postcss-loader": "^1.2.2",
"postcss-mixins": "^6.2.3", "postcss-mixins": "^5.4.1",
"postcss-nested": "^4.2.1", "postcss-nested": "^1.0.0",
"postcss-preset-env": "^6.7.0", "postcss-scss": "^0.4.0",
"postcss-scss": "^2.0.0", "postcss-simple-vars": "^3.0.0",
"postcss-simple-vars": "^5.0.2",
"postcss-strip-inline-comments": "^0.1.5", "postcss-strip-inline-comments": "^0.1.5",
"react-addons-perf": "^15.4.0",
"react-addons-test-utils": "^15.4.0",
"rimraf": "^2.4.3", "rimraf": "^2.4.3",
"shell-escape": "^0.2.0", "source-map-loader": "^0.1.5",
"stylelint": "^12.0.1", "webpack": "^1.12.14",
"terser-webpack-plugin": "^2.3.0", "webpack-dev-server": "^1.16.2"
"typescript": "^3.7.3", },
"webpack": "^4.41.2", "optionalDependencies": {
"webpack-cli": "^3.3.10", "olm": "https://matrix.org/packages/npm/olm/olm-2.2.1.tgz"
"webpack-dev-server": "^3.9.0"
}, },
"build": { "build": {
"appId": "im.riot.app", "appId": "im.riot.app",
"electronVersion": "7.1.12", "category": "Network",
"electronVersion": "1.4.14",
"//asar=false": "https://github.com/electron-userland/electron-builder/issues/675",
"asar": false,
"dereference": true,
"//files": "We bundle everything, so we only need to include webapp/",
"files": [ "files": [
"node_modules/**", "electron/src/**",
"src/**" "electron/img/**",
], "webapp/**",
"extraResources": [ "package.json"
{
"from": "electron_app/img",
"to": "img"
},
"webapp/**/*"
], ],
"linux": { "linux": {
"target": "deb", "target": "deb",
"category": "Network;InstantMessaging;Chat",
"maintainer": "support@riot.im", "maintainer": "support@riot.im",
"desktop": { "desktop": {
"StartupWMClass": "riot" "StartupWMClass": "riot-web"
} }
}, },
"mac": {
"category": "public.app-category.social-networking",
"darkModeSupport": true
},
"win": { "win": {
"target": { "target": "squirrel"
"target": "squirrel" }
},
"sign": "scripts/electron_winSign"
},
"directories": {
"buildResources": "electron_app/build",
"output": "electron_app/dist",
"app": "electron_app"
},
"afterSign": "scripts/electron_afterSign.js",
"protocols": [
{
"name": "riot",
"schemes": [
"riot"
]
}
]
}, },
"jest": { "directories": {
"modulePathIgnorePatterns": [ "buildResources": "electron/build",
"<rootDir>/electron_app" "output": "electron/dist"
],
"testEnvironment": "jest-environment-jsdom-fourteen",
"testMatch": [
"<rootDir>/test/**/*-test.js"
],
"setupFilesAfterEnv": [
"<rootDir>/node_modules/matrix-react-sdk/test/setupTests.js"
],
"moduleNameMapper": {
"\\.(gif|png|svg|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",
"\\$webapp/i18n/languages.json": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/languages.json",
"^browser-request$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/browser-request.js",
"^react$": "<rootDir>/node_modules/react",
"^react-dom$": "<rootDir>/node_modules/react-dom",
"^matrix-js-sdk$": "<rootDir>/node_modules/matrix-js-sdk/src",
"^matrix-react-sdk$": "<rootDir>/node_modules/matrix-react-sdk/src"
},
"transformIgnorePatterns": [
"/node_modules/(?!matrix-js-sdk).+$",
"/node_modules/(?!matrix-react-sdk).+$"
]
} }
} }

13
postcss.config.js Normal file
View File

@@ -0,0 +1,13 @@
module.exports = {
plugins: [
require("postcss-import")(),
require("autoprefixer")(),
require("postcss-simple-vars")(),
require("postcss-extend")(),
require("postcss-nested")(),
require("postcss-mixins")(),
require("postcss-strip-inline-comments")(),
],
"parser": "postcss-scss",
"local-plugins": true,
};

View File

@@ -1,78 +1,12 @@
#!/bin/bash #!/bin/sh
# #
# Script to perform a release of riot-web. # Script to perform a release of vector-web.
# #
# Requires github-changelog-generator; to install, do # Requires github-changelog-generator; to install, do
# pip install git+https://github.com/matrix-org/github-changelog-generator.git # pip install git+https://github.com/matrix-org/github-changelog-generator.git
set -e set -e
orig_args=$@
# chomp any args starting with '-' as these need to go
# through to the release script and otherwise we'll get
# confused about what the version arg is.
while [[ "$1" == -* ]]; do
shift
done
cd `dirname $0` cd `dirname $0`
for i in matrix-js-sdk matrix-react-sdk exec ./node_modules/matrix-js-sdk/release.sh -z "$@"
do
echo "Checking version of $i..."
depver=`cat package.json | jq -r .dependencies[\"$i\"]`
latestver=`yarn info -s $i dist-tags.next`
if [ "$depver" != "$latestver" ]
then
echo "The latest version of $i is $latestver but package.json depends on $depver."
echo -n "Type 'u' to auto-upgrade, 'c' to continue anyway, or 'a' to abort:"
read resp
if [ "$resp" != "u" ] && [ "$resp" != "c" ]
then
echo "Aborting."
exit 1
fi
if [ "$resp" == "u" ]
then
echo "Upgrading $i to $latestver..."
yarn add -E $i@$latestver
git add -u
# The `-e` flag opens the editor and gives you a chance to check
# the upgrade for correctness.
git commit -m "Upgrade $i to $latestver" -e
fi
fi
done
release="${1#v}"
tag="v${release}"
prerelease=0
# We check if this build is a prerelease by looking to
# see if the version has a hyphen in it. Crude,
# but semver doesn't support postreleases so anything
# with a hyphen is a prerelease.
echo $release | grep -q '-' && prerelease=1
# bump Electron's package.json first
echo "electron yarn version"
cd electron_app
yarn version --no-git-tag-version --new-version "$release"
git commit package.json -m "$tag"
cd ..
./node_modules/matrix-js-sdk/release.sh -u vector-im -z "$orig_args"
if [ $prerelease -eq 0 ]
then
# For a release, reset SDK deps back to the `develop` branch.
for i in matrix-js-sdk matrix-react-sdk
do
echo "Resetting $i to develop branch..."
yarn add github:matrix-org/$i#develop
git add -u
git commit -m "Reset $i back to develop branch"
done
git push origin develop
fi

View File

@@ -1 +1 @@
signing_id: releases@riot.im signing_id: packages@riot.im

View File

@@ -1,56 +0,0 @@
{
"name": "Riot - open team collaboration",
"short_name": "Riot",
"display": "standalone",
"theme_color": "#76CFA6",
"start_url": "index.html",
"icons": [
{
"src": "vector-icons/android-chrome-36x36.png",
"sizes": "36x36",
"type": "image\/png",
"density": "0.75"
},
{
"src": "vector-icons/android-chrome-48x48.png",
"sizes": "48x48",
"type": "image\/png",
"density": "1.0"
},
{
"src": "vector-icons/android-chrome-72x72.png",
"sizes": "72x72",
"type": "image\/png",
"density": "1.5"
},
{
"src": "vector-icons/android-chrome-96x96.png",
"sizes": "96x96",
"type": "image\/png",
"density": "2.0"
},
{
"src": "vector-icons/android-chrome-144x144.png",
"sizes": "144x144",
"type": "image\/png",
"density": "3.0"
},
{
"src": "vector-icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image\/png",
"density": "4.0"
}
],
"related_applications": [
{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=im.vector.alpha",
"id": "im.vector.alpha"
},
{
"platform": "itunes",
"url": "https://itunes.apple.com/gb/app/riot-open-source-team-collaboration-via-matrix/id1083446067"
}
]
}

BIN
res/media/busy.mp3 Normal file

Binary file not shown.

BIN
res/media/busy.ogg Normal file

Binary file not shown.

BIN
res/media/callend.mp3 Normal file

Binary file not shown.

BIN
res/media/callend.ogg Normal file

Binary file not shown.

BIN
res/media/message.mp3 Normal file

Binary file not shown.

BIN
res/media/message.ogg Normal file

Binary file not shown.

BIN
res/media/ring.mp3 Normal file

Binary file not shown.

BIN
res/media/ring.ogg Normal file

Binary file not shown.

BIN
res/media/ringback.mp3 Normal file

Binary file not shown.

BIN
res/media/ringback.ogg Normal file

Binary file not shown.

View File

@@ -1 +0,0 @@
self.addEventListener('fetch',() => {});

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

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