Skip to content

Commit

Permalink
Merge pull request #1091 from vector-im/tr-master
Browse files Browse the repository at this point in the history
Latest changes for thirdroom/dev
  • Loading branch information
robertlong authored May 15, 2023
2 parents a913fbb + 701a6fa commit 563853e
Show file tree
Hide file tree
Showing 124 changed files with 5,438 additions and 1,053 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/sdk-release.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Publish to npm
on:
push:
tags:
- "sdk-v**"
jobs:
npm:
name: Publish to npm
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.1.0]

steps:
- name: 🧮 Checkout code
uses: actions/checkout@v3

- name: Install tools
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}

- name: 🔧 Yarn cache
uses: actions/setup-node@v3
with:
cache: "yarn"
registry-url: "https://registry.npmjs.org"

- name: 🔨 Install dependencies
run: "yarn install --prefer-offline --frozen-lockfile"

- name: Run Unit tests
run: "yarn test"

- name: Run Lint Checks
run: "yarn run lint-ci"

- name: Run Typescript Checks
run: "yarn run tsc"

- name: Run SDK tests
run: "yarn test:sdk"

- name: Build SDK
run: "yarn build:sdk"

- name: 🚀 Publish to npm
id: npm-publish
uses: JS-DevTools/npm-publish@v2
with:
token: ${{ secrets.NPM_TOKEN }}
access: public
package: ./target
dry-run: true
6 changes: 5 additions & 1 deletion doc/SDK.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ yarn create vite
cd <your-project-name>
yarn
yarn add hydrogen-view-sdk
yarn add https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz
```

You should see a `index.html` in the project root directory, containing an element with `id="app"`. Add the attribute `class="hydrogen"` to this element, as the CSS we'll include from the SDK assumes for now that the app is rendered in an element with this classname.
Expand All @@ -32,7 +33,8 @@ import {
createRouter,
RoomViewModel,
TimelineView,
viewClassForTile
viewClassForTile,
FeatureSet
} from "hydrogen-view-sdk";
import downloadSandboxPath from 'hydrogen-view-sdk/download-sandbox.html?url';
import workerPath from 'hydrogen-view-sdk/main.js?url';
Expand Down Expand Up @@ -81,12 +83,14 @@ async function main() {
const {session} = client;
// looks for room corresponding to #element-dev:matrix.org, assuming it is already joined
const room = session.rooms.get("!bEWtlqtDwCLFIAKAcv:matrix.org");
const features = await FeatureSet.load(platform.settingsStorage);
const vm = new RoomViewModel({
room,
ownUserId: session.userId,
platform,
urlRouter: urlRouter,
navigation,
features,
});
await vm.load();
const view = new TimelineView(vm.timelineViewModel, viewClassForTile);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"xxhashjs": "^0.2.2"
},
"dependencies": {
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
"another-json": "^0.2.0",
"base64-arraybuffer": "^0.2.0",
"dompurify": "^2.3.0",
Expand Down
2 changes: 1 addition & 1 deletion scripts/sdk/base-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@thirdroom/hydrogen-view-sdk",
"description": "Embeddable matrix client library, including view components",
"version": "0.1.1",
"version": "0.1.2",
"main": "./lib-build/hydrogen.cjs.js",
"exports": {
".": {
Expand Down
2 changes: 1 addition & 1 deletion src/domain/AccountSetupViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

import {ViewModel} from "./ViewModel";
import {KeyType} from "../matrix/ssss/index";
import {Status} from "./session/settings/KeyBackupViewModel.js";
import {Status} from "./session/settings/KeyBackupViewModel";

export class AccountSetupViewModel extends ViewModel {
constructor(options) {
Expand Down
2 changes: 1 addition & 1 deletion src/domain/SessionLoadViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class SessionLoadViewModel extends ViewModel {
this._ready(client);
}
if (loadError) {
console.error("session load error", loadError);
console.error("session load error", loadError.stack);
}
} catch (err) {
this._error = err;
Expand Down
4 changes: 3 additions & 1 deletion src/domain/navigation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export type SegmentType = {
"details": true;
"members": true;
"member": string;
"device-verification": string | boolean;
"join-room": true;
"oidc": {
state: string,
} &
Expand Down Expand Up @@ -63,7 +65,7 @@ function allowsChild(parent: Segment<SegmentType> | undefined, child: Segment<Se
// allowed root segments
return type === "login" || type === "session" || type === "sso" || type === "logout" || type === "oidc";
case "session":
return type === "room" || type === "rooms" || type === "settings" || type === "create-room" || type === "join-room";
return type === "room" || type === "rooms" || type === "settings" || type === "create-room" || type === "join-room" || type === "device-verification";
case "rooms":
// downside of the approach: both of these will control which tile is selected
return type === "room" || type === "empty-grid-tile";
Expand Down
28 changes: 27 additions & 1 deletion src/domain/session/SessionViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {RoomGridViewModel} from "./RoomGridViewModel.js";
import {SettingsViewModel} from "./settings/SettingsViewModel.js";
import {CreateRoomViewModel} from "./CreateRoomViewModel.js";
import {JoinRoomViewModel} from "./JoinRoomViewModel";
import {DeviceVerificationViewModel} from "./verification/DeviceVerificationViewModel";
import {ViewModel} from "../ViewModel";
import {RoomViewModelObservable} from "./RoomViewModelObservable.js";
import {RightPanelViewModel} from "./rightpanel/RightPanelViewModel.js";
Expand All @@ -48,6 +49,7 @@ export class SessionViewModel extends ViewModel {
this._gridViewModel = null;
this._createRoomViewModel = null;
this._joinRoomViewModel = null;
this._verificationViewModel = null;
this._toastCollectionViewModel = this.track(new ToastCollectionViewModel(this.childOptions({
session: this._client.session,
})));
Expand Down Expand Up @@ -95,6 +97,14 @@ export class SessionViewModel extends ViewModel {
}));
this._updateJoinRoom(joinRoom.get());

if (this.features.crossSigning) {
const verification = this.navigation.observe("device-verification");
this.track(verification.subscribe((txnId) => {
this._updateVerification(txnId);
}));
this._updateVerification(verification.get());
}

const lightbox = this.navigation.observe("lightbox");
this.track(lightbox.subscribe(eventId => {
this._updateLightbox(eventId);
Expand Down Expand Up @@ -143,7 +153,8 @@ export class SessionViewModel extends ViewModel {
this._gridViewModel ||
this._settingsViewModel ||
this._createRoomViewModel ||
this._joinRoomViewModel
this._joinRoomViewModel ||
this._verificationViewModel
);
}

Expand Down Expand Up @@ -179,6 +190,10 @@ export class SessionViewModel extends ViewModel {
return this._joinRoomViewModel;
}

get verificationViewModel() {
return this._verificationViewModel;
}

get toastCollectionViewModel() {
return this._toastCollectionViewModel;
}
Expand Down Expand Up @@ -327,6 +342,17 @@ export class SessionViewModel extends ViewModel {
this.emitChange("activeMiddleViewModel");
}

_updateVerification(txnId) {
if (this._verificationViewModel) {
this._verificationViewModel = this.disposeTracked(this._verificationViewModel);
}
if (txnId) {
const request = this._client.session.crossSigning.get()?.receivedSASVerifications.get(txnId);
this._verificationViewModel = this.track(new DeviceVerificationViewModel(this.childOptions({ session: this._client.session, request })));
}
this.emitChange("activeMiddleViewModel");
}

_updateLightbox(eventId) {
if (this._lightboxViewModel) {
this._lightboxViewModel = this.disposeTracked(this._lightboxViewModel);
Expand Down
68 changes: 68 additions & 0 deletions src/domain/session/rightpanel/MemberDetailsViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
import {ViewModel} from "../../ViewModel";
import {RoomVisibility} from "../../../matrix/room/common";
import {avatarInitials, getIdentifierColorNumber, getAvatarHttpUrl} from "../../avatar";
import {UserTrust} from "../../../matrix/verification/CrossSigning";

export class MemberDetailsViewModel extends ViewModel {
constructor(options) {
Expand All @@ -29,13 +30,56 @@ export class MemberDetailsViewModel extends ViewModel {
this._session = options.session;
this.track(this._powerLevelsObservable.subscribe(() => this._onPowerLevelsChange()));
this.track(this._observableMember.subscribe( () => this._onMemberChange()));
this._userTrust = undefined;
this._userTrustSubscription = undefined;
if (this.features.crossSigning) {
this.track(this._session.crossSigning.subscribe(() => {
this._onCrossSigningChange();
}));
}
this._onCrossSigningChange();
}

get name() { return this._member.name; }

get userId() { return this._member.userId; }

get trustDescription() {
switch (this._userTrust?.get()) {
case UserTrust.Trusted: return this.i18n`You have verified this user. This user has verified all of their sessions.`;
case UserTrust.UserNotSigned: return this.i18n`You have not verified this user.`;
case UserTrust.UserSignatureMismatch: return this.i18n`You appear to have signed this user, but the signature is invalid.`;
case UserTrust.UserDeviceNotSigned: return this.i18n`You have verified this user, but they have one or more unverified sessions.`;
case UserTrust.UserDeviceSignatureMismatch: return this.i18n`This user has a session signature that is invalid.`;
case UserTrust.UserSetupError: return this.i18n`This user hasn't set up cross-signing correctly`;
case UserTrust.OwnSetupError: return this.i18n`Cross-signing wasn't set up correctly on your side.`;
case undefined:
default: // adding default as well because jslint can't check for switch exhaustiveness
return this.i18n`Please wait…`;
}
}

get trustShieldColor() {
if (!this._isEncrypted) {
return "";
}
switch (this._userTrust?.get()) {
case undefined:
case UserTrust.OwnSetupError:
return "";
case UserTrust.Trusted:
return "green";
case UserTrust.UserNotSigned:
return "black";
default:
return "red";
}
}

get type() { return "member-details"; }

get shouldShowBackButton() { return true; }

get previousSegmentName() { return "members"; }

get role() {
Expand All @@ -54,6 +98,15 @@ export class MemberDetailsViewModel extends ViewModel {
this.emitChange("role");
}

async signUser() {
const crossSigning = this._session.crossSigning.get();
if (crossSigning) {
await this.logger.run("MemberDetailsViewModel.signUser", async log => {
await crossSigning.signUser(this.userId, log);
});
}
}

get avatarLetter() {
return avatarInitials(this.name);
}
Expand Down Expand Up @@ -94,4 +147,19 @@ export class MemberDetailsViewModel extends ViewModel {
}
this.navigation.push("room", roomId);
}

_onCrossSigningChange() {
const crossSigning = this._session.crossSigning.get();
this._userTrustSubscription = this.disposeTracked(this._userTrustSubscription);
this._userTrust = undefined;
if (crossSigning) {
this.logger.run("MemberDetailsViewModel.observeUserTrust", log => {
this._userTrust = crossSigning.observeUserTrust(this.userId, log);
this._userTrustSubscription = this.track(this._userTrust.subscribe(() => {
this.emitChange("trustShieldColor");
}));
});
}
this.emitChange("trustShieldColor");
}
}
5 changes: 5 additions & 0 deletions src/domain/session/room/timeline/tiles/BaseMessageTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {SimpleTile} from "./SimpleTile.js";
import {ReactionsViewModel} from "../ReactionsViewModel.js";
import {getIdentifierColorNumber, avatarInitials, getAvatarHttpUrl} from "../../../../avatar";


export class BaseMessageTile extends SimpleTile {
constructor(entry, options) {
super(entry, options);
Expand All @@ -44,6 +45,10 @@ export class BaseMessageTile extends SimpleTile {
return `https://matrix.to/#/${encodeURIComponent(this._room.id)}/${encodeURIComponent(this._entry.id)}`;
}

copyPermalink() {
this.platform.copyPlaintext(this.permaLink);
}

get senderProfileLink() {
return `https://matrix.to/#/${encodeURIComponent(this.sender)}`;
}
Expand Down
Loading

0 comments on commit 563853e

Please sign in to comment.