Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try open matrix: links before showing clients #223

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions css/open.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@ limitations under the License.
border-bottom: 1px solid var(--grey);
padding: 4px 0;
}

.OpeningClientView {
display: flex;
align-items: center;
text-align: center;
flex-direction: column;
margin: 0;
}

.OpeningClientView .defaultAvatar {
width: 64px;
height: 64px;
background-image: url('../images/chat-icon.svg');
background-repeat: no-repeat;
background-position: center;
background-size: 85%;
}

.OpeningClientView .spinner {
margin-top: 15px;
}
25 changes: 25 additions & 0 deletions src/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export const IdentifierKind = createEnum(
"GroupId",
);

function idToPath(identifier) {
return encodeURIComponent(identifier.substring(1));
}

function asPrefix(identifierKind) {
switch (identifierKind) {
case IdentifierKind.RoomId: return "!";
Expand All @@ -40,6 +44,16 @@ function asPrefix(identifierKind) {
}
}

function asPath(identifierKind) {
switch (identifierKind) {
case IdentifierKind.RoomId: return "roomid";
case IdentifierKind.RoomAlias: return "r";
case IdentifierKind.GroupId: return null;
case IdentifierKind.UserId: return "u";
default: throw new Error("invalid id kind " + identifierKind);
}
}

function getWebInstanceMap(queryParams) {
const prefix = "web-instance[";
const postfix = "]";
Expand Down Expand Up @@ -183,4 +197,15 @@ export class Link {
return `/${this.identifier}`;
}
}

toMatrixUrl() {
const prefix = asPath(this.identifierKind);
if (!prefix) {
// Some matrix.to links aren't valid matrix: links (i.e. groups)
return null;
}
const identifier = idToPath(this.identifier);
const suffix = this.eventId ? `/e/${idToPath(this.eventId)}` : "";
return `matrix:${prefix}/${identifier}${suffix}`;
}
}
1 change: 1 addition & 0 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export async function main(container) {
const vm = new RootViewModel({
request: xhrRequest,
openLink: url => location.href = url,
setTimeout: (f, time) => window.setTimeout(f, time),
platforms: guessApplicablePlatforms(navigator.userAgent, navigator.platform),
preferences: new Preferences(window.localStorage),
origin: location.origin,
Expand Down
20 changes: 17 additions & 3 deletions src/open/OpenLinkView.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,28 @@ import {ServerConsentView} from "./ServerConsentView.js";
export class OpenLinkView extends TemplateView {
render(t, vm) {
return t.div({className: "OpenLinkView card"}, [
t.mapView(vm => vm.previewViewModel, previewVM => previewVM ?
new ShowLinkView(vm) :
new ServerConsentView(vm.serverConsentViewModel)
t.map(vm => vm.tryingLink, tryingLink => tryingLink ?
t.view(new TryingLinkView(vm)) :
t.mapView(vm => vm.previewViewModel, previewVM => previewVM ?
new ShowLinkView(vm) :
new ServerConsentView(vm.serverConsentViewModel)
),
),
]);
}
}

class TryingLinkView extends TemplateView {
render (t, vm) {
return t.div({ className: "OpeningClientView" }, [
t.div({className: "defaultAvatar"}),
t.h1("Trying to open your default client..."),
t.span("If this doesn't work, you will be redirected shortly."),
t.div({className: "spinner"}),
]);
}
}

class ShowLinkView extends TemplateView {
render(t, vm) {
return t.div([
Expand Down
14 changes: 14 additions & 0 deletions src/open/OpenLinkViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,27 @@ export class OpenLinkViewModel extends ViewModel {
this.previewViewModel = null;
this.clientsViewModel = null;
this.previewLoading = false;
this.tryingLink = false;
this._tryLink();
if (this.preferences.homeservers === null) {
this._showServerConsent();
} else {
this._showLink();
}
}

_tryLink() {
const matrixUrl = this._link.toMatrixUrl()
if (matrixUrl) {
this.tryingLink = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you need an emitChange here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed not, since this is called from the constructor, and the views are only created afterwards. I don't think any handlers can be registered at the time of the constructor call? Maybe I'm misunderstanding.

this.setTimeout(() => {
this.tryingLink = false;
this.emitChange();
}, 1000);
this.openLink(matrixUrl);
}
}

_showServerConsent() {
let servers = [];
if (this.preferences.homeservers) {
Expand Down
2 changes: 2 additions & 0 deletions src/utils/ViewModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class ViewModel extends EventEmitter {
get request() { return this._options.request; }
get origin() { return this._options.origin; }
get openLink() { return this._options.openLink; }
get setTimeout() { return this._options.setTimeout; }
get platforms() { return this._options.platforms; }
get preferences() { return this._options.preferences; }

Expand All @@ -71,6 +72,7 @@ export class ViewModel extends EventEmitter {
request: this.request,
origin: this.origin,
openLink: this.openLink,
setTimeout: this.setTimeout,
platforms: this.platforms,
preferences: this.preferences,
}, options);
Expand Down