mirror of
https://github.com/element-hq/element-desktop.git
synced 2026-01-01 12:09:24 -05:00
Compare commits
22 Commits
t3chguy/ty
...
v1.11.17
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
723ea9d5ff | ||
|
|
b1b15e1e7b | ||
|
|
1142160222 | ||
|
|
c280560c2c | ||
|
|
19f04d4362 | ||
|
|
2f48519dce | ||
|
|
6508e171db | ||
|
|
333361fc02 | ||
|
|
9d08c84331 | ||
|
|
0b67e84574 | ||
|
|
23fac479fe | ||
|
|
56370de568 | ||
|
|
9bdb1fadd4 | ||
|
|
86a386449f | ||
|
|
b52787a49e | ||
|
|
8c91ead163 | ||
|
|
9d6008519e | ||
|
|
d3fbf1366b | ||
|
|
f4bf425148 | ||
|
|
19351d766d | ||
|
|
7c87fff295 | ||
|
|
f5fa0ae7be |
10
.github/workflows/build_linux.yaml
vendored
10
.github/workflows/build_linux.yaml
vendored
@@ -1,3 +1,6 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
@@ -16,19 +19,21 @@ jobs:
|
||||
name: webapp
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: ${{ hashFiles('./yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('hakDependencies.json', 'electronVersion') }}
|
||||
path: |
|
||||
./.hak
|
||||
|
||||
- name: Install Rust
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
|
||||
- name: Install libsqlcipher-dev
|
||||
if: inputs.sqlcipher == 'system'
|
||||
if: steps.cache.outputs.cache-hit != 'true' && inputs.sqlcipher == 'system'
|
||||
run: sudo apt-get install -y libsqlcipher-dev
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
@@ -40,6 +45,7 @@ jobs:
|
||||
run: "yarn install --pure-lockfile"
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: "yarn build:native"
|
||||
env:
|
||||
SQLCIPHER_STATIC: ${{ inputs.sqlcipher == 'static' && '1' || '' }}
|
||||
|
||||
8
.github/workflows/build_macos.yaml
vendored
8
.github/workflows/build_macos.yaml
vendored
@@ -1,3 +1,6 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
on:
|
||||
workflow_call:
|
||||
jobs:
|
||||
@@ -11,13 +14,15 @@ jobs:
|
||||
name: webapp
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: ${{ hashFiles('./yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('hakDependencies.json', 'electronVersion') }}
|
||||
path: |
|
||||
./.hak
|
||||
|
||||
- name: Install Rust
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
@@ -32,6 +37,7 @@ jobs:
|
||||
run: "yarn install --pure-lockfile"
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: "yarn build:native:universal"
|
||||
|
||||
- name: Build App
|
||||
|
||||
8
.github/workflows/build_prepare.yaml
vendored
8
.github/workflows/build_prepare.yaml
vendored
@@ -26,6 +26,12 @@ jobs:
|
||||
- name: Fetch Element Web
|
||||
run: yarn run fetch --noverify -d ${{ inputs.config }} ${{ inputs.version }}
|
||||
|
||||
# We split this out to save the build_* scripts having to do it to make use of `hashFiles` in the cache action
|
||||
- name: Generate cache hash files
|
||||
run: |
|
||||
yarn run --silent electron --version > electronVersion
|
||||
cat package.json | jq -c .hakDependencies > hakDependencies.json
|
||||
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: webapp
|
||||
@@ -33,3 +39,5 @@ jobs:
|
||||
path: |
|
||||
webapp.asar
|
||||
package.json
|
||||
electronVersion
|
||||
hakDependencies.json
|
||||
|
||||
8
.github/workflows/build_windows.yaml
vendored
8
.github/workflows/build_windows.yaml
vendored
@@ -1,3 +1,6 @@
|
||||
# This workflow relies on actions/cache to store the hak dependency artifacts as they take a long time to build
|
||||
# Due to this extra care must be taken to only ever run all build_* scripts against the same branch to ensure
|
||||
# the correct cache scoping, and additional care must be taken to not run untrusted actions on the develop branch.
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
@@ -32,9 +35,10 @@ jobs:
|
||||
name: webapp
|
||||
|
||||
- name: Cache .hak
|
||||
id: cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key: ${{ runner.os }}-${{ hashFiles('./yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('hakDependencies.json', 'electronVersion') }}
|
||||
path: |
|
||||
./.hak
|
||||
|
||||
@@ -58,6 +62,7 @@ jobs:
|
||||
echo "C:/Program Files/NASM" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||
|
||||
- name: Install Rust
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
@@ -72,6 +77,7 @@ jobs:
|
||||
run: "yarn install --pure-lockfile"
|
||||
|
||||
- name: Build Natives
|
||||
if: steps.cache.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
refreshenv
|
||||
yarn build:native --target ${{ steps.config.outputs.target }}
|
||||
|
||||
4
.github/workflows/static_analysis.yaml
vendored
4
.github/workflows/static_analysis.yaml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ node_modules/
|
||||
.vscode/
|
||||
/test_artifacts/
|
||||
/coverage/
|
||||
yarn-error.log
|
||||
|
||||
68
CHANGELOG.md
68
CHANGELOG.md
@@ -1,3 +1,71 @@
|
||||
Changes in [1.11.17](https://github.com/vector-im/element-desktop/releases/tag/v1.11.17) (2022-12-21)
|
||||
=====================================================================================================
|
||||
|
||||
## 🚨 BREAKING CHANGES
|
||||
* This allows the update server to be entirely static, such as a CDN or object store, as defined at https ([\#461](https://github.com/vector-im/element-desktop/pull/461)).
|
||||
|
||||
## ✨ Features
|
||||
* Enable threads by default ([\#9736](https://github.com/matrix-org/matrix-react-sdk/pull/9736)). Fixes vector-im/element-web#19270 vector-im/element-web#21910 and vector-im/element-web#23946.
|
||||
* Add inline code formatting to rich text editor ([\#9720](https://github.com/matrix-org/matrix-react-sdk/pull/9720)).
|
||||
* Add emoji handling for plain text mode of the new rich text editor ([\#9727](https://github.com/matrix-org/matrix-react-sdk/pull/9727)).
|
||||
* Overlay virtual room call events into main timeline ([\#9626](https://github.com/matrix-org/matrix-react-sdk/pull/9626)). Fixes vector-im/element-web#22929.
|
||||
* Adds a new section under "Room Settings" > "Roles & Permissions" which adds the possibility to multiselect users from this room and grant them more permissions. ([\#9596](https://github.com/matrix-org/matrix-react-sdk/pull/9596)). Contributed by @GoodGuyMarco.
|
||||
* Add emoji handling for rich text mode ([\#9661](https://github.com/matrix-org/matrix-react-sdk/pull/9661)).
|
||||
* Add setting to hide bold notifications ([\#9705](https://github.com/matrix-org/matrix-react-sdk/pull/9705)).
|
||||
* Further password reset flow enhancements ([\#9662](https://github.com/matrix-org/matrix-react-sdk/pull/9662)).
|
||||
* Snooze the bulk unverified sessions reminder on dismiss ([\#9706](https://github.com/matrix-org/matrix-react-sdk/pull/9706)).
|
||||
* Honor advanced audio processing settings when recording voice messages ([\#9610](https://github.com/matrix-org/matrix-react-sdk/pull/9610)). Contributed by @MrAnno.
|
||||
* Improve the visual balance of bubble layout ([\#9704](https://github.com/matrix-org/matrix-react-sdk/pull/9704)).
|
||||
* Add config setting to disable bulk unverified sessions nag ([\#9657](https://github.com/matrix-org/matrix-react-sdk/pull/9657)).
|
||||
* Only display bulk unverified sessions nag when current sessions is verified ([\#9656](https://github.com/matrix-org/matrix-react-sdk/pull/9656)).
|
||||
* Separate labs and betas more clearly ([\#8969](https://github.com/matrix-org/matrix-react-sdk/pull/8969)). Fixes vector-im/element-web#22706.
|
||||
* Show user an error if we fail to create a DM for verification. ([\#9624](https://github.com/matrix-org/matrix-react-sdk/pull/9624)).
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
* Prevent unnecessary m.direct updates ([\#9805](https://github.com/matrix-org/matrix-react-sdk/pull/9805)). Fixes vector-im/element-web#24059.
|
||||
* Fix checkForPreJoinUISI for thread roots ([\#9803](https://github.com/matrix-org/matrix-react-sdk/pull/9803)). Fixes vector-im/element-web#24054.
|
||||
* Load RTE components only when RTE labs is enabled ([\#9804](https://github.com/matrix-org/matrix-react-sdk/pull/9804)).
|
||||
* Fix issue where thread panel did not update correctly ([\#9746](https://github.com/matrix-org/matrix-react-sdk/pull/9746)). Fixes vector-im/element-web#23971.
|
||||
* Remove async call to get virtual room from room load ([\#9743](https://github.com/matrix-org/matrix-react-sdk/pull/9743)). Fixes vector-im/element-web#23968.
|
||||
* Check each thread for unread messages. ([\#9723](https://github.com/matrix-org/matrix-react-sdk/pull/9723)).
|
||||
* Device manage - handle sessions that don't support encryption ([\#9717](https://github.com/matrix-org/matrix-react-sdk/pull/9717)). Fixes vector-im/element-web#23722.
|
||||
* Fix hover state for formatting buttons (Rich text editor) (fix vector-im/element-web/issues/23832) ([\#9715](https://github.com/matrix-org/matrix-react-sdk/pull/9715)).
|
||||
* Don't allow group calls to be unterminated ([\#9710](https://github.com/matrix-org/matrix-react-sdk/pull/9710)).
|
||||
* Fix replies to emotes not showing as inline ([\#9707](https://github.com/matrix-org/matrix-react-sdk/pull/9707)). Fixes vector-im/element-web#23903.
|
||||
* Update copy of 'Change layout' button to match Element Call ([\#9703](https://github.com/matrix-org/matrix-react-sdk/pull/9703)).
|
||||
* Fix call splitbrains when switching between rooms ([\#9692](https://github.com/matrix-org/matrix-react-sdk/pull/9692)).
|
||||
* bugfix: fix an issue where the Notifier would incorrectly fire for non-timeline events ([\#9664](https://github.com/matrix-org/matrix-react-sdk/pull/9664)). Fixes vector-im/element-web#17263.
|
||||
* Fix power selector being wrongly disabled for admins themselves ([\#9681](https://github.com/matrix-org/matrix-react-sdk/pull/9681)). Fixes vector-im/element-web#23882.
|
||||
* Show day counts in call durations ([\#9641](https://github.com/matrix-org/matrix-react-sdk/pull/9641)).
|
||||
|
||||
Changes in [1.11.16](https://github.com/vector-im/element-desktop/releases/tag/v1.11.16) (2022-12-06)
|
||||
=====================================================================================================
|
||||
|
||||
## ✨ Features
|
||||
* Update to Electron 21 ([\#458](https://github.com/vector-im/element-desktop/pull/458)). Fixes vector-im/element-web#23783.
|
||||
* Further improve replies ([\#6396](https://github.com/matrix-org/matrix-react-sdk/pull/6396)). Fixes vector-im/element-web#19074, vector-im/element-web#18194 vector-im/element-web#18027 and vector-im/element-web#19179.
|
||||
* Enable users to join group calls from multiple devices ([\#9625](https://github.com/matrix-org/matrix-react-sdk/pull/9625)).
|
||||
* fix(visual): make cursor a pointer for summaries ([\#9419](https://github.com/matrix-org/matrix-react-sdk/pull/9419)). Contributed by @r00ster91.
|
||||
* Add placeholder for rich text editor ([\#9613](https://github.com/matrix-org/matrix-react-sdk/pull/9613)).
|
||||
* Consolidate public room search experience ([\#9605](https://github.com/matrix-org/matrix-react-sdk/pull/9605)). Fixes vector-im/element-web#22846.
|
||||
* New password reset flow ([\#9581](https://github.com/matrix-org/matrix-react-sdk/pull/9581)). Fixes vector-im/element-web#23131.
|
||||
* Device manager - add tooltip to device details toggle ([\#9594](https://github.com/matrix-org/matrix-react-sdk/pull/9594)).
|
||||
* sliding sync: add lazy-loading member support ([\#9530](https://github.com/matrix-org/matrix-react-sdk/pull/9530)).
|
||||
* Limit formatting bar offset to top of composer ([\#9365](https://github.com/matrix-org/matrix-react-sdk/pull/9365)). Fixes vector-im/element-web#12359. Contributed by @owi92.
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
* Fix issues around up arrow event edit shortcut ([\#9645](https://github.com/matrix-org/matrix-react-sdk/pull/9645)). Fixes vector-im/element-web#18497 and vector-im/element-web#18964.
|
||||
* Fix search not being cleared when clicking on a result ([\#9635](https://github.com/matrix-org/matrix-react-sdk/pull/9635)). Fixes vector-im/element-web#23845.
|
||||
* Fix screensharing in 1:1 calls ([\#9612](https://github.com/matrix-org/matrix-react-sdk/pull/9612)). Fixes vector-im/element-web#23808.
|
||||
* Fix the background color flashing when joining a call ([\#9640](https://github.com/matrix-org/matrix-react-sdk/pull/9640)).
|
||||
* Fix the size of the 'Private space' icon ([\#9638](https://github.com/matrix-org/matrix-react-sdk/pull/9638)).
|
||||
* Fix reply editing in rich text editor (https ([\#9615](https://github.com/matrix-org/matrix-react-sdk/pull/9615)).
|
||||
* Fix thread list jumping back down while scrolling ([\#9606](https://github.com/matrix-org/matrix-react-sdk/pull/9606)). Fixes vector-im/element-web#23727.
|
||||
* Fix regression with TimelinePanel props updates not taking effect ([\#9608](https://github.com/matrix-org/matrix-react-sdk/pull/9608)). Fixes vector-im/element-web#23794.
|
||||
* Fix form tooltip positioning ([\#9598](https://github.com/matrix-org/matrix-react-sdk/pull/9598)). Fixes vector-im/element-web#22861.
|
||||
* Extract Search handling from RoomView into its own Component ([\#9574](https://github.com/matrix-org/matrix-react-sdk/pull/9574)). Fixes vector-im/element-web#498.
|
||||
* Fix call splitbrains when switching between rooms ([\#9692](https://github.com/matrix-org/matrix-react-sdk/pull/9692)).
|
||||
|
||||
Changes in [1.11.15](https://github.com/vector-im/element-desktop/releases/tag/v1.11.15) (2022-11-22)
|
||||
=====================================================================================================
|
||||
|
||||
|
||||
16
docs/updates.md
Normal file
16
docs/updates.md
Normal file
@@ -0,0 +1,16 @@
|
||||
The Desktop app is capable of self-updating on macOS and Windows.
|
||||
The update server base url is configurable as `update_base_url` in config.json and can be served by a static file host,
|
||||
CDN or object storage.
|
||||
|
||||
Currently all packaging & deployment is handled by https://github.com/vector-im/element-builder/
|
||||
|
||||
# Windows
|
||||
|
||||
On Windows the update mechanism used is [Squirrel.Windows](https://github.com/Squirrel/Squirrel.Windows)
|
||||
and can be served by any compatible Squirrel server, such as https://github.com/Tiliq/squirrel-server
|
||||
|
||||
# macOS
|
||||
|
||||
On macOS the update mechanism used is [Squirrel.Mac](https://github.com/Squirrel/Squirrel.Mac)
|
||||
using the newer JSON format as documented [here](https://github.com/Squirrel/Squirrel.Mac#update-file-json-format).
|
||||
|
||||
@@ -4,7 +4,7 @@ Vendor: support@element.io
|
||||
Architecture: amd64
|
||||
Maintainer: support@element.io
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0, libasound2, libgbm1
|
||||
Recommends: libappindicator3-1, libsqlcipher0
|
||||
Recommends: libsqlcipher0
|
||||
Section: net
|
||||
Priority: extra
|
||||
Homepage: https://element.io/
|
||||
|
||||
@@ -4,7 +4,7 @@ Vendor: support@element.io
|
||||
Architecture: amd64
|
||||
Maintainer: support@element.io
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0, libasound2, libgbm1
|
||||
Recommends: libappindicator3-1, libsqlcipher0
|
||||
Recommends: libsqlcipher0
|
||||
Replaces: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
|
||||
Breaks: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
|
||||
Section: net
|
||||
|
||||
@@ -32,7 +32,7 @@ export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promi
|
||||
await buildMatrixSeshat(hakEnv, moduleInfo);
|
||||
}
|
||||
|
||||
async function buildOpenSslWin(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
async function buildOpenSslWin(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
const version = moduleInfo.cfg.dependencies.openssl;
|
||||
const openSslDir = path.join(moduleInfo.moduleTargetDotHakDir, `openssl-${version}`);
|
||||
|
||||
@@ -134,7 +134,7 @@ async function buildOpenSslWin(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
});
|
||||
}
|
||||
|
||||
async function buildSqlCipherWin(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
async function buildSqlCipherWin(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
const version = moduleInfo.cfg.dependencies.sqlcipher;
|
||||
const sqlCipherDir = path.join(moduleInfo.moduleTargetDotHakDir, `sqlcipher-${version}`);
|
||||
const buildDir = path.join(sqlCipherDir, 'bld');
|
||||
@@ -171,7 +171,7 @@ async function buildSqlCipherWin(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
);
|
||||
}
|
||||
|
||||
async function buildSqlCipherUnix(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
async function buildSqlCipherUnix(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
const version = moduleInfo.cfg.dependencies.sqlcipher;
|
||||
const sqlCipherDir = path.join(moduleInfo.moduleTargetDotHakDir, `sqlcipher-${version}`);
|
||||
|
||||
@@ -268,7 +268,7 @@ async function buildSqlCipherUnix(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
});
|
||||
}
|
||||
|
||||
async function buildMatrixSeshat(hakEnv: HakEnv, moduleInfo: DependencyInfo) {
|
||||
async function buildMatrixSeshat(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
// seshat now uses n-api so we shouldn't need to specify a node version to
|
||||
// build against, but it does seems to still need something in here, so leaving
|
||||
// it for now: we should confirm how much of this it still actually needs.
|
||||
|
||||
@@ -18,12 +18,20 @@ import path from 'path';
|
||||
import childProcess from 'child_process';
|
||||
import fs from 'fs';
|
||||
import fsProm from 'fs/promises';
|
||||
import needle from 'needle';
|
||||
import tar from 'tar';
|
||||
import fetch from 'node-fetch';
|
||||
import { promises as stream } from "stream";
|
||||
|
||||
import HakEnv from '../../scripts/hak/hakEnv';
|
||||
import { DependencyInfo } from '../../scripts/hak/dep';
|
||||
|
||||
async function download(url: string, filename: string): Promise<void> {
|
||||
const resp = await fetch(url);
|
||||
if (!resp.ok) throw new Error(`unexpected response ${resp.statusText}`);
|
||||
if (!resp.body) throw new Error(`unexpected response has no body ${resp.statusText}`);
|
||||
await stream.pipeline(resp.body, fs.createWriteStream(filename));
|
||||
}
|
||||
|
||||
export default async function(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
if (hakEnv.wantsStaticSqlCipher()) {
|
||||
await getSqlCipher(hakEnv, moduleInfo);
|
||||
@@ -57,11 +65,7 @@ async function getSqlCipher(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise
|
||||
haveSqlcipherTar = false;
|
||||
}
|
||||
if (!haveSqlcipherTar) {
|
||||
const bob = needle('get', `https://github.com/sqlcipher/sqlcipher/archive/v${version}.tar.gz`, {
|
||||
follow: 10,
|
||||
output: sqlCipherTarball,
|
||||
});
|
||||
await bob;
|
||||
await download(`https://github.com/sqlcipher/sqlcipher/archive/v${version}.tar.gz`, sqlCipherTarball);
|
||||
}
|
||||
|
||||
// Extract the tarball to per-target directories, then we avoid cross-contaiminating archs
|
||||
@@ -118,10 +122,7 @@ async function getOpenSsl(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<v
|
||||
haveOpenSslTar = false;
|
||||
}
|
||||
if (!haveOpenSslTar) {
|
||||
await needle('get', `https://www.openssl.org/source/openssl-${version}.tar.gz`, {
|
||||
follow: 10,
|
||||
output: openSslTarball,
|
||||
});
|
||||
await download(`https://www.openssl.org/source/openssl-${version}.tar.gz`, openSslTarball);
|
||||
}
|
||||
|
||||
console.log("extracting " + openSslTarball + " in " + moduleInfo.moduleTargetDotHakDir);
|
||||
|
||||
29
package.json
29
package.json
@@ -2,7 +2,7 @@
|
||||
"name": "element-desktop",
|
||||
"productName": "Element",
|
||||
"main": "lib/electron-main.js",
|
||||
"version": "1.11.15",
|
||||
"version": "1.11.17",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Element",
|
||||
"repository": {
|
||||
@@ -16,13 +16,13 @@
|
||||
"prunei18n": "matrix-prune-i18n",
|
||||
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && matrix-gen-i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
|
||||
"mkdirs": "mkdirp packages deploys",
|
||||
"fetch": "yarn run mkdirs && node scripts/fetch-package.js",
|
||||
"fetch": "yarn run mkdirs && ts-node scripts/fetch-package.ts",
|
||||
"asar-webapp": "asar p webapp webapp.asar",
|
||||
"start": "yarn run build:ts && yarn run build:res && electron .",
|
||||
"lint": "yarn lint:types && yarn lint:js",
|
||||
"lint:js": "eslint --max-warnings 0 src scripts hak",
|
||||
"lint:js-fix": "eslint --fix src scripts hak",
|
||||
"lint:types": "tsc --noEmit && tsc -p scripts/hak/tsconfig.json --noEmit && tsc -p hak/tsconfig.json --noEmit",
|
||||
"lint:types": "tsc --noEmit && tsc -p scripts/tsconfig.json --noEmit && tsc -p hak/tsconfig.json --noEmit",
|
||||
"build:native": "yarn run hak",
|
||||
"build:native:universal": "yarn run hak --target x86_64-apple-darwin fetchandbuild && yarn run hak --target aarch64-apple-darwin fetchandbuild && yarn run hak --target x86_64-apple-darwin --target aarch64-apple-darwin copyandlink",
|
||||
"build:32": "yarn run build:ts && yarn run build:res && electron-builder --ia32",
|
||||
@@ -30,7 +30,7 @@
|
||||
"build:universal": "yarn run build:ts && yarn run build:res && electron-builder --universal",
|
||||
"build": "yarn run build:ts && yarn run build:res && electron-builder",
|
||||
"build:ts": "tsc",
|
||||
"build:res": "node scripts/copy-res.js",
|
||||
"build:res": "ts-node scripts/copy-res.ts",
|
||||
"docker:setup": "docker build -t element-desktop-dockerbuild dockerbuild",
|
||||
"docker:build:native": "scripts/in-docker.sh yarn run hak",
|
||||
"docker:build": "scripts/in-docker.sh yarn run build",
|
||||
@@ -54,6 +54,7 @@
|
||||
"@babel/core": "^7.18.10",
|
||||
"@babel/preset-env": "^7.18.10",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
"@electron/asar": "^3.2.0",
|
||||
"@electron/notarize": "^1.2.3",
|
||||
"@types/auto-launch": "^5.0.1",
|
||||
"@types/counterpart": "^0.18.1",
|
||||
@@ -61,48 +62,48 @@
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/minimist": "^1.2.1",
|
||||
"@types/mkdirp": "^1.0.2",
|
||||
"@types/node": "16.18.4",
|
||||
"@types/pacote": "^11.1.1",
|
||||
"@types/rimraf": "^3.0.2",
|
||||
"@types/tar": "^6.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
||||
"@typescript-eslint/parser": "^5.42.0",
|
||||
"allchange": "^1.0.6",
|
||||
"app-builder-lib": "^22.14.10",
|
||||
"asar": "^2.0.1",
|
||||
"babel-jest": "^29.0.0",
|
||||
"chokidar": "^3.5.2",
|
||||
"detect-libc": "^1.0.3",
|
||||
"electron": "^21",
|
||||
"electron": "^22.0.0",
|
||||
"electron-builder": "^23.6.0",
|
||||
"electron-builder-squirrel-windows": "^23.6.0",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-matrix-org": "^0.7.0",
|
||||
"eslint-plugin-matrix-org": "^0.8.0",
|
||||
"eslint-plugin-unicorn": "^45.0.0",
|
||||
"expect-playwright": "^0.8.0",
|
||||
"find-npm-prefix": "^1.0.2",
|
||||
"fs-extra": "^10.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"fs-extra": "^11.0.0",
|
||||
"glob": "^8.0.0",
|
||||
"jest": "^29.0.0",
|
||||
"matrix-web-i18n": "^1.3.0",
|
||||
"mkdirp": "^1.0.3",
|
||||
"needle": "^2.5.0",
|
||||
"node-pre-gyp": "^0.15.0",
|
||||
"pacote": "^11.3.5",
|
||||
"node-pre-gyp": "^0.17.0",
|
||||
"pacote": "^15.0.0",
|
||||
"playwright": "^1.25.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"tar": "^6.1.2",
|
||||
"ts-jest": "^29.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "4.5.5"
|
||||
"typescript": "4.9.3"
|
||||
},
|
||||
"hakDependencies": {
|
||||
"matrix-seshat": "^2.3.3",
|
||||
"keytar": "^7.9.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "16.11.38"
|
||||
"@types/node": "16.18.4"
|
||||
},
|
||||
"build": {
|
||||
"appId": "im.riot.app",
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S npx ts-node
|
||||
|
||||
// copies resources into the lib directory.
|
||||
|
||||
const parseArgs = require('minimist');
|
||||
const chokidar = require('chokidar');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
import parseArgs from "minimist";
|
||||
import * as chokidar from "chokidar";
|
||||
import * as path from "path";
|
||||
import * as fs from "fs";
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {});
|
||||
|
||||
const watch = argv.w;
|
||||
const verbose = argv.v;
|
||||
|
||||
function errCheck(err) {
|
||||
function errCheck(err?: Error): void {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
@@ -25,15 +25,14 @@ const INCLUDE_LANGS = fs.readdirSync(I18N_BASE_PATH).filter(fn => fn.endsWith(".
|
||||
// Ensure lib, lib/i18n and lib/i18n/strings all exist
|
||||
fs.mkdirSync('lib/i18n/strings', { recursive: true });
|
||||
|
||||
function genLangFile(file, dest) {
|
||||
let translations = {};
|
||||
type Translations = Record<string, Record<string, string> | string>;
|
||||
|
||||
function genLangFile(file: string, dest: string): void {
|
||||
const inTrs: Record<string, string> = {};
|
||||
[file].forEach(function(f) {
|
||||
if (fs.existsSync(f)) {
|
||||
try {
|
||||
Object.assign(
|
||||
translations,
|
||||
JSON.parse(fs.readFileSync(f).toString()),
|
||||
);
|
||||
Object.assign(inTrs, JSON.parse(fs.readFileSync(f).toString()));
|
||||
} catch (e) {
|
||||
console.error("Failed: " + f, e);
|
||||
throw e;
|
||||
@@ -41,8 +40,7 @@ function genLangFile(file, dest) {
|
||||
}
|
||||
});
|
||||
|
||||
translations = weblateToCounterpart(translations);
|
||||
|
||||
const translations = weblateToCounterpart(inTrs);
|
||||
const json = JSON.stringify(translations, null, 4);
|
||||
const filename = path.basename(file);
|
||||
|
||||
@@ -66,8 +64,8 @@ function genLangFile(file, dest) {
|
||||
* "other": "%(count)s badgers"
|
||||
* }
|
||||
*/
|
||||
function weblateToCounterpart(inTrs) {
|
||||
const outTrs = {};
|
||||
function weblateToCounterpart(inTrs: Record<string, string>): Translations {
|
||||
const outTrs: Translations = {};
|
||||
|
||||
for (const key of Object.keys(inTrs)) {
|
||||
const keyParts = key.split('|', 2);
|
||||
@@ -96,12 +94,12 @@ function weblateToCounterpart(inTrs) {
|
||||
watch the input files for a given language,
|
||||
regenerate the file, and regenerating languages.json with the new filename
|
||||
*/
|
||||
function watchLanguage(file, dest) {
|
||||
function watchLanguage(file: string, dest: string): void {
|
||||
// XXX: Use a debounce because for some reason if we read the language
|
||||
// file immediately after the FS event is received, the file contents
|
||||
// appears empty. Possibly https://github.com/nodejs/node/issues/6112
|
||||
let makeLangDebouncer;
|
||||
const makeLang = () => {
|
||||
let makeLangDebouncer: NodeJS.Timeout | undefined;
|
||||
const makeLang = (): void => {
|
||||
if (makeLangDebouncer) {
|
||||
clearTimeout(makeLangDebouncer);
|
||||
}
|
||||
@@ -118,7 +116,7 @@ function watchLanguage(file, dest) {
|
||||
|
||||
// language resources
|
||||
const I18N_DEST = "lib/i18n/strings/";
|
||||
INCLUDE_LANGS.forEach((file) => {
|
||||
INCLUDE_LANGS.forEach((file): void => {
|
||||
genLangFile(I18N_BASE_PATH + file, I18N_DEST);
|
||||
}, {});
|
||||
|
||||
@@ -1,42 +1,40 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S npx ts-node --resolveJsonModule
|
||||
|
||||
const process = require('process');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const fsPromises = require('fs').promises;
|
||||
const childProcess = require('child_process');
|
||||
const tar = require('tar');
|
||||
const asar = require('asar');
|
||||
const needle = require('needle');
|
||||
import * as path from "path";
|
||||
import { createWriteStream, promises as fs } from "fs";
|
||||
import * as childProcess from "child_process";
|
||||
import tar from "tar";
|
||||
import * as asar from "asar";
|
||||
import fetch from "node-fetch";
|
||||
import { promises as stream } from "stream";
|
||||
|
||||
const riotDesktopPackageJson = require('../package.json');
|
||||
const { setPackageVersion } = require('./set-version.js');
|
||||
import riotDesktopPackageJson from "../package.json";
|
||||
import { setPackageVersion } from "./set-version";
|
||||
|
||||
const PUB_KEY_URL = "https://packages.riot.im/element-release-key.asc";
|
||||
const PACKAGE_URL_PREFIX = "https://github.com/vector-im/element-web/releases/download/";
|
||||
const DEVELOP_TGZ_URL = "https://develop.element.io/develop.tar.gz";
|
||||
const ASAR_PATH = 'webapp.asar';
|
||||
|
||||
async function downloadToFile(url, filename) {
|
||||
async function downloadToFile(url: string, filename: string): Promise<void> {
|
||||
console.log("Downloading " + url + "...");
|
||||
|
||||
try {
|
||||
await needle('get', url, null,
|
||||
{
|
||||
follow_max: 5,
|
||||
output: filename,
|
||||
},
|
||||
);
|
||||
const resp = await fetch(url);
|
||||
if (!resp.ok) throw new Error(`unexpected response ${resp.statusText}`);
|
||||
if (!resp.body) throw new Error(`unexpected response has no body ${resp.statusText}`);
|
||||
await stream.pipeline(resp.body, createWriteStream(filename));
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
try {
|
||||
await fsPromises.unlink(filename);
|
||||
await fs.unlink(filename);
|
||||
} catch (_) {}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyFile(filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
async function verifyFile(filename: string): Promise<void> {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
childProcess.execFile('gpg', ['--verify', filename + '.asc', filename], (error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
@@ -47,15 +45,15 @@ async function verifyFile(filename) {
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
async function main(): Promise<number | undefined> {
|
||||
let verify = true;
|
||||
let importkey = false;
|
||||
let pkgDir = 'packages';
|
||||
let deployDir = 'deploys';
|
||||
let cfgDir;
|
||||
let targetVersion;
|
||||
let filename;
|
||||
let url;
|
||||
let cfgDir: string | undefined;
|
||||
let targetVersion: string | undefined;
|
||||
let filename: string | undefined;
|
||||
let url: string | undefined;
|
||||
let setVersion = false;
|
||||
|
||||
while (process.argv.length > 2) {
|
||||
@@ -104,7 +102,7 @@ async function main() {
|
||||
url = PACKAGE_URL_PREFIX + targetVersion + '/' + filename;
|
||||
}
|
||||
|
||||
const haveGpg = await new Promise((resolve) => {
|
||||
const haveGpg = await new Promise<boolean>((resolve) => {
|
||||
childProcess.execFile('gpg', ['--version'], (error) => {
|
||||
resolve(!error);
|
||||
});
|
||||
@@ -116,7 +114,7 @@ async function main() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => {
|
||||
await new Promise<boolean>((resolve) => {
|
||||
const gpgProc = childProcess.execFile('gpg', ['--import'], (error) => {
|
||||
if (error) {
|
||||
console.log("Failed to import key", error);
|
||||
@@ -125,7 +123,9 @@ async function main() {
|
||||
}
|
||||
resolve(!error);
|
||||
});
|
||||
needle.get(PUB_KEY_URL).pipe(gpgProc.stdin);
|
||||
fetch(PUB_KEY_URL).then(resp => {
|
||||
stream.pipeline(resp.body, gpgProc.stdin!);
|
||||
});
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ async function main() {
|
||||
if (!haveDeploy) {
|
||||
const outPath = path.join(pkgDir, filename);
|
||||
try {
|
||||
await fsPromises.stat(outPath);
|
||||
await fs.stat(outPath);
|
||||
console.log("Already have " + filename + ": not redownloading");
|
||||
} catch (e) {
|
||||
try {
|
||||
@@ -167,7 +167,7 @@ async function main() {
|
||||
|
||||
if (verify) {
|
||||
try {
|
||||
await fsPromises.stat(outPath+'.asc');
|
||||
await fs.stat(outPath+'.asc');
|
||||
console.log("Already have " + filename + ".asc: not redownloading");
|
||||
} catch (e) {
|
||||
try {
|
||||
@@ -202,9 +202,9 @@ async function main() {
|
||||
}
|
||||
|
||||
try {
|
||||
await fsPromises.stat(ASAR_PATH);
|
||||
await fs.stat(ASAR_PATH);
|
||||
console.log(ASAR_PATH + " already present: removing");
|
||||
await fsPromises.unlink(ASAR_PATH);
|
||||
await fs.unlink(ASAR_PATH);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ async function main() {
|
||||
const configJsonSource = path.join(cfgDir, 'config.json');
|
||||
const configJsonDest = path.join(expectedDeployDir, 'config.json');
|
||||
console.log(configJsonSource + ' -> ' + configJsonDest);
|
||||
await fsPromises.copyFile(configJsonSource, configJsonDest);
|
||||
await fs.copyFile(configJsonSource, configJsonDest);
|
||||
} else {
|
||||
console.log("Skipping config file");
|
||||
}
|
||||
@@ -221,7 +221,7 @@ async function main() {
|
||||
await asar.createPackage(expectedDeployDir, ASAR_PATH);
|
||||
|
||||
if (setVersion) {
|
||||
const semVer = fs.readFileSync(path.join(expectedDeployDir, "version"), "utf-8").trim();
|
||||
const semVer = (await fs.readFile(path.join(expectedDeployDir, "version"), "utf-8")).trim();
|
||||
console.log("Updating version to " + semVer);
|
||||
await setPackageVersion(semVer);
|
||||
}
|
||||
@@ -29,7 +29,7 @@ const client = new S3Client({
|
||||
},
|
||||
});
|
||||
|
||||
const templateLayout = (content: string) => `
|
||||
const templateLayout = (content: string): string => `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -80,7 +80,7 @@ const templateLayout = (content: string) => `
|
||||
*
|
||||
* @return Formatted string.
|
||||
*/
|
||||
function humanFileSize(bytes: number, si = false, dp = 1) {
|
||||
function humanFileSize(bytes: number, si = false, dp = 1): string {
|
||||
const thresh = si ? 1000 : 1024;
|
||||
|
||||
if (Math.abs(bytes) < thresh) {
|
||||
|
||||
@@ -22,7 +22,7 @@ import HakEnv from './hakEnv';
|
||||
|
||||
export default async function clean(hakEnv: HakEnv, moduleInfo: DependencyInfo): Promise<void> {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
rimraf(moduleInfo.moduleDotHakDir, (err: Error) => {
|
||||
rimraf(moduleInfo.moduleDotHakDir, (err?: Error | null) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
@@ -32,7 +32,7 @@ export default async function clean(hakEnv: HakEnv, moduleInfo: DependencyInfo):
|
||||
});
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
rimraf(path.join(hakEnv.dotHakDir, 'links', moduleInfo.name), (err: Error) => {
|
||||
rimraf(path.join(hakEnv.dotHakDir, 'links', moduleInfo.name), (err?: Error | null) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
@@ -42,7 +42,7 @@ export default async function clean(hakEnv: HakEnv, moduleInfo: DependencyInfo):
|
||||
});
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
rimraf(path.join(hakEnv.projectRoot, 'node_modules', moduleInfo.name), (err: Error) => {
|
||||
rimraf(path.join(hakEnv.projectRoot, 'node_modules', moduleInfo.name), (err?: Error | null) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
|
||||
19
scripts/hak/find-npm-prefix.d.ts
vendored
Normal file
19
scripts/hak/find-npm-prefix.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2022 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
declare module "find-npm-prefix" {
|
||||
export default function findPrefix(dir: string): Promise<string>;
|
||||
}
|
||||
@@ -37,33 +37,27 @@ async function getRuntimeVersion(projectRoot: string): Promise<string> {
|
||||
|
||||
export default class HakEnv {
|
||||
public readonly target: Target;
|
||||
public runtime: string;
|
||||
public runtimeVersion: string;
|
||||
public runtime?: string;
|
||||
public runtimeVersion?: string;
|
||||
public dotHakDir: string;
|
||||
|
||||
constructor(public readonly projectRoot: string, targetId: TargetId | null) {
|
||||
if (targetId) {
|
||||
this.target = TARGETS[targetId];
|
||||
} else {
|
||||
this.target = getHost();
|
||||
}
|
||||
public constructor(public readonly projectRoot: string, targetId: TargetId | null) {
|
||||
const target = targetId ? TARGETS[targetId] : getHost();
|
||||
|
||||
if (!this.target) {
|
||||
if (!target) {
|
||||
throw new Error(`Unknown target ${targetId}!`);
|
||||
}
|
||||
this.target = target;
|
||||
this.dotHakDir = path.join(this.projectRoot, '.hak');
|
||||
}
|
||||
|
||||
public async init() {
|
||||
public async init(): Promise<void> {
|
||||
this.runtime = await getRuntime(this.projectRoot);
|
||||
this.runtimeVersion = await getRuntimeVersion(this.projectRoot);
|
||||
}
|
||||
|
||||
public getRuntimeAbi(): string {
|
||||
return nodePreGypVersioning.get_runtime_abi(
|
||||
this.runtime,
|
||||
this.runtimeVersion,
|
||||
);
|
||||
return nodePreGypVersioning.get_runtime_abi(this.runtime!, this.runtimeVersion!);
|
||||
}
|
||||
|
||||
// {node_abi}-{platform}-{arch}
|
||||
@@ -95,7 +89,7 @@ export default class HakEnv {
|
||||
return isHostId(this.target.id);
|
||||
}
|
||||
|
||||
public makeGypEnv(): Record<string, string> {
|
||||
public makeGypEnv(): Record<string, string | undefined> {
|
||||
return Object.assign({}, process.env, {
|
||||
npm_config_arch: this.target.arch,
|
||||
npm_config_target_arch: this.target.arch,
|
||||
@@ -107,10 +101,6 @@ export default class HakEnv {
|
||||
});
|
||||
}
|
||||
|
||||
public getNodeModuleBin(name: string): string {
|
||||
return path.join(this.projectRoot, 'node_modules', '.bin', name);
|
||||
}
|
||||
|
||||
public wantsStaticSqlCipherUnix(): boolean {
|
||||
return this.isMac() || process.env.SQLCIPHER_STATIC == '1';
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ const MODULECOMMANDS = [
|
||||
|
||||
// Shortcuts for multiple commands at once (useful for building universal binaries
|
||||
// because you can run the fetch/fetchDeps/build for each arch and then copy/link once)
|
||||
const METACOMMANDS = {
|
||||
const METACOMMANDS: Record<string, string[]> = {
|
||||
'fetchandbuild': ['check', 'fetch', 'fetchDeps', 'build'],
|
||||
'copyandlink': ['copy', 'link'],
|
||||
};
|
||||
@@ -51,7 +51,7 @@ const HAKSCRIPTS = [
|
||||
'build',
|
||||
];
|
||||
|
||||
async function main() {
|
||||
async function main(): Promise<void> {
|
||||
const prefix = await findNpmPrefix(process.cwd());
|
||||
let packageJson;
|
||||
try {
|
||||
|
||||
20
scripts/hak/node-pre-gyp.d.ts
vendored
Normal file
20
scripts/hak/node-pre-gyp.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2022 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
declare module "node-pre-gyp/lib/util/versioning" {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export function get_runtime_abi(runtime: string, version: string): string;
|
||||
}
|
||||
@@ -1,29 +1,28 @@
|
||||
#!/usr/bin/env node
|
||||
#!/usr/bin/env -S npx ts-node
|
||||
|
||||
/*
|
||||
* Checks for the presence of a webapp, inspects its version and sets the
|
||||
* version metadata of the package to match.
|
||||
*/
|
||||
|
||||
const fs = require('fs').promises;
|
||||
const asar = require('asar');
|
||||
const childProcess = require('child_process');
|
||||
import { promises as fs } from "fs";
|
||||
import * as asar from "asar";
|
||||
import * as childProcess from "child_process";
|
||||
|
||||
async function versionFromAsar() {
|
||||
export async function versionFromAsar(): Promise<string> {
|
||||
try {
|
||||
await fs.stat('webapp.asar');
|
||||
} catch (e) {
|
||||
console.log("No 'webapp.asar' found. Run 'yarn run fetch'");
|
||||
return 1;
|
||||
throw new Error("No 'webapp.asar' found. Run 'yarn run fetch'");
|
||||
}
|
||||
|
||||
return asar.extractFile('webapp.asar', 'version').toString().trim();
|
||||
}
|
||||
|
||||
async function setPackageVersion(ver) {
|
||||
export async function setPackageVersion(ver: string): Promise<void> {
|
||||
// set version in package.json: electron-builder will use this to populate
|
||||
// all the various version fields
|
||||
await new Promise((resolve, reject) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
childProcess.execFile(process.platform === 'win32' ? 'yarn.cmd' : 'yarn', [
|
||||
'version',
|
||||
'-s',
|
||||
@@ -40,16 +39,20 @@ async function setPackageVersion(ver) {
|
||||
});
|
||||
}
|
||||
|
||||
async function main(args) {
|
||||
async function main(args: string[]): Promise<number> {
|
||||
let version = args[0];
|
||||
|
||||
if (version === undefined) version = await versionFromAsar();
|
||||
|
||||
await setPackageVersion(version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main(process.argv.slice(2)).then((ret) => process.exit(ret));
|
||||
main(process.argv.slice(2)).then((ret) => {
|
||||
process.exit(ret);
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { versionFromAsar, setPackageVersion };
|
||||
@@ -1,12 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"target": "es2017",
|
||||
"module": "commonjs",
|
||||
"sourceMap": false,
|
||||
"strict": true,
|
||||
"lib": [
|
||||
"es2019",
|
||||
"dom"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
6
src/@types/matrix-seshat.d.ts
vendored
6
src/@types/matrix-seshat.d.ts
vendored
@@ -86,7 +86,7 @@ declare module "matrix-seshat" {
|
||||
}
|
||||
|
||||
export class Seshat {
|
||||
constructor(path: string, config?: IConfig);
|
||||
public constructor(path: string, config?: IConfig);
|
||||
public addEvent(matrixEvent: IMatrixEvent, profile?: IMatrixProfile): void;
|
||||
public deleteEvent(eventId: string): Promise<boolean>;
|
||||
public commit(force?: boolean): Promise<number>;
|
||||
@@ -132,7 +132,7 @@ declare module "matrix-seshat" {
|
||||
}
|
||||
|
||||
export class SeshatRecovery {
|
||||
constructor(path: string, config?: IConfig);
|
||||
public constructor(path: string, config?: IConfig);
|
||||
public info(): IRecoveryInfo;
|
||||
public getUserVersion(): Promise<number>;
|
||||
public shutdown(): Promise<void>;
|
||||
@@ -140,6 +140,6 @@ declare module "matrix-seshat" {
|
||||
}
|
||||
|
||||
export class ReindexError extends Error {
|
||||
constructor(message?: string);
|
||||
public constructor(message?: string);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,9 +238,9 @@ global.store = new Store({ name: "electron-config" });
|
||||
global.appQuitting = false;
|
||||
|
||||
const exitShortcuts: Array<(input: Input, platform: string) => boolean> = [
|
||||
(input, platform) => platform !== 'darwin' && input.alt && input.key.toUpperCase() === 'F4',
|
||||
(input, platform) => platform !== 'darwin' && input.control && input.key.toUpperCase() === 'Q',
|
||||
(input, platform) => platform === 'darwin' && input.meta && input.key.toUpperCase() === 'Q',
|
||||
(input, platform): boolean => platform !== 'darwin' && input.alt && input.key.toUpperCase() === 'F4',
|
||||
(input, platform): boolean => platform !== 'darwin' && input.control && input.key.toUpperCase() === 'Q',
|
||||
(input, platform): boolean => platform === 'darwin' && input.meta && input.key.toUpperCase() === 'Q',
|
||||
];
|
||||
|
||||
const warnBeforeExit = (event: Event, input: Input): void => {
|
||||
@@ -502,8 +502,8 @@ app.on('ready', async () => {
|
||||
global.appLocalization = new AppLocalization({
|
||||
store: global.store,
|
||||
components: [
|
||||
() => tray.initApplicationMenu(),
|
||||
() => Menu.setApplicationMenu(buildMenuTemplate()),
|
||||
(): void => tray.initApplicationMenu(),
|
||||
(): void => Menu.setApplicationMenu(buildMenuTemplate()),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -32,5 +32,7 @@
|
||||
"Are you sure you want to quit?": "Er du sikker på at du vil slutte?",
|
||||
"Cancel": "Avbryt",
|
||||
"Services": "Tjenester",
|
||||
"Hide Others": "Skjul Andre"
|
||||
"Hide Others": "Skjul Andre",
|
||||
"Bring All to Front": "Flytt Alt Frem",
|
||||
"Toggle Full Screen": "Veksle Fullskjerm"
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ export class AppLocalization {
|
||||
private readonly store: TypedStore;
|
||||
private readonly localizedComponents?: Set<Component>;
|
||||
|
||||
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
||||
public constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
|
||||
counterpart.registerTranslations(FALLBACK_LOCALE, this.fetchTranslationJson("en_EN"));
|
||||
counterpart.setFallbackLocale(FALLBACK_LOCALE);
|
||||
counterpart.setSeparator('|');
|
||||
|
||||
@@ -81,7 +81,7 @@ ipcMain.on('seshat', async function(_ev: IpcMainEvent, payload): Promise<void> {
|
||||
// We do this here to ensure we get the path after --profile has been resolved
|
||||
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
|
||||
|
||||
const sendError = (id: string, e: Error) => {
|
||||
const sendError = (id: string, e: Error): void => {
|
||||
const error = {
|
||||
message: e.message,
|
||||
};
|
||||
|
||||
@@ -110,7 +110,7 @@ export function initApplicationMenu(): void {
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: _t('Quit'),
|
||||
click: function() {
|
||||
click: function(): void {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { app, autoUpdater, ipcMain } from "electron";
|
||||
import { autoUpdater, ipcMain } from "electron";
|
||||
|
||||
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
|
||||
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
|
||||
@@ -50,20 +50,14 @@ export function start(updateBaseUrl: string): void {
|
||||
}
|
||||
try {
|
||||
let url: string;
|
||||
// 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.
|
||||
let serverType: "json" | undefined;
|
||||
|
||||
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())}`;
|
||||
// On macOS it takes a JSON file with a map between versions and their URLs
|
||||
url = `${updateBaseUrl}macos/releases.json`;
|
||||
serverType = "json";
|
||||
} else if (process.platform === 'win32') {
|
||||
// On windows it takes a base path and looks for files under that path.
|
||||
url = `${updateBaseUrl}win32/${process.arch}/`;
|
||||
} else {
|
||||
// Squirrel / electron only supports auto-update on these two platforms.
|
||||
@@ -75,7 +69,7 @@ export function start(updateBaseUrl: string): void {
|
||||
|
||||
if (url) {
|
||||
console.log(`Update URL: ${url}`);
|
||||
autoUpdater.setFeedURL({ url });
|
||||
autoUpdater.setFeedURL({ url, serverType });
|
||||
// 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)
|
||||
|
||||
@@ -98,7 +98,7 @@ export function buildMenuTemplate(): Menu {
|
||||
// in macOS the Preferences menu item goes in the first menu
|
||||
...(!isMac ? [{
|
||||
label: _t('Preferences'),
|
||||
click() { global.mainWindow?.webContents.send('preferences'); },
|
||||
click(): void { global.mainWindow?.webContents.send('preferences'); },
|
||||
}] : []),
|
||||
{
|
||||
role: 'togglefullscreen',
|
||||
@@ -132,7 +132,7 @@ export function buildMenuTemplate(): Menu {
|
||||
submenu: [
|
||||
{
|
||||
label: _t('Element Help'),
|
||||
click() { shell.openExternal('https://element.io/help'); },
|
||||
click(): void { shell.openExternal('https://element.io/help'); },
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -153,7 +153,7 @@ export function buildMenuTemplate(): Menu {
|
||||
{
|
||||
label: _t('Preferences') + '…',
|
||||
accelerator: 'Command+,', // Mac-only accelerator
|
||||
click() { global.mainWindow?.webContents.send('preferences'); },
|
||||
click(): void { global.mainWindow?.webContents.send('preferences'); },
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: We
|
||||
if (!url.startsWith('blob:')) {
|
||||
popupMenu.append(new MenuItem({
|
||||
label: url,
|
||||
click() {
|
||||
click(): void {
|
||||
safeOpenURL(url);
|
||||
},
|
||||
}));
|
||||
@@ -107,7 +107,7 @@ function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: We
|
||||
popupMenu.append(new MenuItem({
|
||||
label: _t('Copy image'),
|
||||
accelerator: 'c',
|
||||
click() {
|
||||
click(): void {
|
||||
webContents.copyImageAt(params.x, params.y);
|
||||
},
|
||||
}));
|
||||
@@ -120,7 +120,7 @@ function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: We
|
||||
popupMenu.append(new MenuItem({
|
||||
label: _t('Copy email address'),
|
||||
accelerator: 'a',
|
||||
click() {
|
||||
click(): void {
|
||||
clipboard.writeText(url.substr(MAILTO_PREFIX.length));
|
||||
},
|
||||
}));
|
||||
@@ -130,7 +130,7 @@ function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: We
|
||||
? _t('Copy image address')
|
||||
: _t('Copy link address'),
|
||||
accelerator: 'a',
|
||||
click() {
|
||||
click(): void {
|
||||
clipboard.writeText(url);
|
||||
},
|
||||
}));
|
||||
@@ -143,7 +143,7 @@ function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: We
|
||||
popupMenu.append(new MenuItem({
|
||||
label: _t('Save image as...'),
|
||||
accelerator: 's',
|
||||
async click() {
|
||||
async click(): Promise<void> {
|
||||
const targetFileName = params.suggestedFilename || params.altText || "image.png";
|
||||
const { filePath } = await dialog.showSaveDialog({
|
||||
defaultPath: targetFileName,
|
||||
@@ -228,7 +228,7 @@ function cutCopyPasteSelectContextMenus(params: ContextMenuParams): MenuItemCons
|
||||
return options;
|
||||
}
|
||||
|
||||
function onSelectedContextMenu(ev: Event, params: ContextMenuParams) {
|
||||
function onSelectedContextMenu(ev: Event, params: ContextMenuParams): void {
|
||||
const items = cutCopyPasteSelectContextMenus(params);
|
||||
const popupMenu = Menu.buildFromTemplate(items);
|
||||
|
||||
@@ -237,7 +237,7 @@ function onSelectedContextMenu(ev: Event, params: ContextMenuParams) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
function onEditableContextMenu(ev: Event, params: ContextMenuParams) {
|
||||
function onEditableContextMenu(ev: Event, params: ContextMenuParams): void {
|
||||
const items: MenuItemConstructorOptions[] = [
|
||||
{ role: 'undo' },
|
||||
{ role: 'redo', enabled: params.editFlags.canRedo },
|
||||
@@ -263,7 +263,11 @@ ipcMain.on('userDownloadAction', function(ev: IpcMainEvent, { id, open = false }
|
||||
});
|
||||
|
||||
export default (webContents: WebContents): void => {
|
||||
webContents.on('new-window', onWindowOrNavigate);
|
||||
webContents.setWindowOpenHandler((details) => {
|
||||
safeOpenURL(details.url);
|
||||
return { action: "deny" };
|
||||
});
|
||||
|
||||
webContents.on('will-navigate', (ev: Event, target: string): void => {
|
||||
if (target.startsWith("vector://")) return;
|
||||
return onWindowOrNavigate(ev, target);
|
||||
|
||||
Reference in New Issue
Block a user