Merge pull request #360 from vector-im/bwindels/defaultsessionurl

Add url action to redirect to last session id
This commit is contained in:
Bruno Windels 2021-05-18 13:29:06 +00:00 committed by GitHub
commit 7488e0398c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 57 additions and 20 deletions

View file

@ -46,7 +46,7 @@ export class LoginViewModel extends ViewModel {
if (this._loadViewModel) { if (this._loadViewModel) {
this._loadViewModel = this.disposeTracked(this._loadViewModel); this._loadViewModel = this.disposeTracked(this._loadViewModel);
} }
this._loadViewModel = this.track(new SessionLoadViewModel({ this._loadViewModel = this.track(new SessionLoadViewModel(this.childOptions({
createAndStartSessionContainer: () => { createAndStartSessionContainer: () => {
this._sessionContainer = this._createSessionContainer(); this._sessionContainer = this._createSessionContainer();
this._sessionContainer.startWithLogin(homeserver, username, password); this._sessionContainer.startWithLogin(homeserver, username, password);
@ -58,7 +58,7 @@ export class LoginViewModel extends ViewModel {
this._ready(sessionContainer); this._ready(sessionContainer);
}, },
homeserver, homeserver,
})); })));
this._loadViewModel.start(); this._loadViewModel.start();
this.emitChange("loadViewModel"); this.emitChange("loadViewModel");
this._loadViewModelSubscription = this.track(this._loadViewModel.disposableOn("change", () => { this._loadViewModelSubscription = this.track(this._loadViewModel.disposableOn("change", () => {

View file

@ -35,10 +35,10 @@ export class RootViewModel extends ViewModel {
async load() { async load() {
this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation())); this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation()));
this._applyNavigation(this.urlCreator.getLastUrl()); this._applyNavigation(true);
} }
async _applyNavigation(restoreUrlIfAtDefault) { async _applyNavigation(shouldRestoreLastUrl) {
const isLogin = this.navigation.observe("login").get(); const isLogin = this.navigation.observe("login").get();
const sessionId = this.navigation.observe("session").get(); const sessionId = this.navigation.observe("session").get();
if (isLogin) { if (isLogin) {
@ -67,9 +67,7 @@ export class RootViewModel extends ViewModel {
} }
} else { } else {
try { try {
if (restoreUrlIfAtDefault) { if (!(shouldRestoreLastUrl && this.urlCreator.tryRestoreLastUrl())) {
this.urlCreator.pushUrl(restoreUrlIfAtDefault);
} else {
const sessionInfos = await this.platform.sessionInfoStorage.getAll(); const sessionInfos = await this.platform.sessionInfoStorage.getAll();
if (sessionInfos.length === 0) { if (sessionInfos.length === 0) {
this.navigation.push("login"); this.navigation.push("login");
@ -126,14 +124,14 @@ export class RootViewModel extends ViewModel {
_showSessionLoader(sessionId) { _showSessionLoader(sessionId) {
this._setSection(() => { this._setSection(() => {
this._sessionLoadViewModel = new SessionLoadViewModel({ this._sessionLoadViewModel = new SessionLoadViewModel(this.childOptions({
createAndStartSessionContainer: () => { createAndStartSessionContainer: () => {
const sessionContainer = this._createSessionContainer(); const sessionContainer = this._createSessionContainer();
sessionContainer.startWithExistingSession(sessionId); sessionContainer.startWithExistingSession(sessionId);
return sessionContainer; return sessionContainer;
}, },
ready: sessionContainer => this._showSession(sessionContainer) ready: sessionContainer => this._showSession(sessionContainer)
}); }));
this._sessionLoadViewModel.start(); this._sessionLoadViewModel.start();
}); });
} }

View file

@ -28,6 +28,7 @@ export class SessionLoadViewModel extends ViewModel {
this._deleteSessionOnCancel = deleteSessionOnCancel; this._deleteSessionOnCancel = deleteSessionOnCancel;
this._loading = false; this._loading = false;
this._error = null; this._error = null;
this.backUrl = this.urlCreator.urlForSegment("session", true);
} }
async start() { async start() {

View file

@ -23,12 +23,24 @@ export class URLRouter {
this._subscription = null; this._subscription = null;
this._pathSubscription = null; this._pathSubscription = null;
this._isApplyingUrl = false; this._isApplyingUrl = false;
this._defaultSessionId = this._getLastSessionId();
}
_getLastSessionId() {
const navPath = this._urlAsNavPath(this._history.getLastUrl() || "");
const sessionId = navPath.get("session")?.value;
if (typeof sessionId === "string") {
return sessionId;
}
return null;
} }
attach() { attach() {
this._subscription = this._history.subscribe(url => this._applyUrl(url)); this._subscription = this._history.subscribe(url => this._applyUrl(url));
// subscribe to path before applying initial url
// so redirects in _applyNavPathToHistory are reflected in url bar
this._pathSubscription = this._navigation.pathObservable.subscribe(path => this._applyNavPathToHistory(path));
this._applyUrl(this._history.get()); this._applyUrl(this._history.get());
this._pathSubscription = this._navigation.pathObservable.subscribe(path => this._applyNavigationPath(path));
} }
dispose() { dispose() {
@ -36,7 +48,7 @@ export class URLRouter {
this._pathSubscription = this._pathSubscription(); this._pathSubscription = this._pathSubscription();
} }
_applyNavigationPath(path) { _applyNavPathToHistory(path) {
const url = this.urlForPath(path); const url = this.urlForPath(path);
if (url !== this._history.get()) { if (url !== this._history.get()) {
if (this._isApplyingUrl) { if (this._isApplyingUrl) {
@ -48,10 +60,8 @@ export class URLRouter {
} }
} }
_applyUrl(url) { _applyNavPathToNavigation(navPath) {
const urlPath = this._history.urlAsPath(url) // this will cause _applyNavPathToHistory to be called,
const navPath = this._navigation.pathFrom(this._parseUrlPath(urlPath, this._navigation.path));
// this will cause _applyNavigationPath to be called,
// so set a flag whether this request came from ourselves // so set a flag whether this request came from ourselves
// (in which case it is a redirect if the url does not match the current one) // (in which case it is a redirect if the url does not match the current one)
this._isApplyingUrl = true; this._isApplyingUrl = true;
@ -59,12 +69,27 @@ export class URLRouter {
this._isApplyingUrl = false; this._isApplyingUrl = false;
} }
_urlAsNavPath(url) {
const urlPath = this._history.urlAsPath(url);
return this._navigation.pathFrom(this._parseUrlPath(urlPath, this._navigation.path, this._defaultSessionId));
}
_applyUrl(url) {
const navPath = this._urlAsNavPath(url);
this._applyNavPathToNavigation(navPath);
}
pushUrl(url) { pushUrl(url) {
this._history.pushUrl(url); this._history.pushUrl(url);
} }
getLastUrl() { tryRestoreLastUrl() {
return this._history.getLastUrl(); const lastNavPath = this._urlAsNavPath(this._history.getLastUrl() || "");
if (lastNavPath.segments.length !== 0) {
this._applyNavPathToNavigation(navPath);
return true;
}
return false;
} }
urlForSegments(segments) { urlForSegments(segments) {

View file

@ -85,7 +85,7 @@ function roomsSegmentWithRoom(rooms, roomId, path) {
} }
} }
export function parseUrlPath(urlPath, currentNavPath) { export function parseUrlPath(urlPath, currentNavPath, defaultSessionId) {
// substr(1) to take of initial / // substr(1) to take of initial /
const parts = urlPath.substr(1).split("/"); const parts = urlPath.substr(1).split("/");
const iterator = parts[Symbol.iterator](); const iterator = parts[Symbol.iterator]();
@ -113,6 +113,14 @@ export function parseUrlPath(urlPath, currentNavPath) {
segments.push(roomsSegmentWithRoom(rooms, roomId, currentNavPath)); segments.push(roomsSegmentWithRoom(rooms, roomId, currentNavPath));
} }
segments.push(new Segment("room", roomId)); segments.push(new Segment("room", roomId));
} else if (type === "last-session") {
let sessionSegment = currentNavPath.get("session");
if (typeof sessionSegment?.value !== "string" && defaultSessionId) {
sessionSegment = new Segment("session", defaultSessionId);
}
if (sessionSegment) {
segments.push(sessionSegment);
}
} else { } else {
// might be undefined, which will be turned into true by Segment // might be undefined, which will be turned into true by Segment
const value = iterator.next().value; const value = iterator.next().value;

View file

@ -215,6 +215,10 @@ a.button-action {
text-align: center; text-align: center;
} }
.SessionLoadView {
padding-top: 16px;
}
@media screen and (min-width: 600px) { @media screen and (min-width: 600px) {
.PreSessionScreen { .PreSessionScreen {
box-shadow: 0px 6px 32px rgba(0, 0, 0, 0.1); box-shadow: 0px 6px 32px rgba(0, 0, 0, 0.1);

View file

@ -22,9 +22,10 @@ export class SessionLoadView extends TemplateView {
return t.div({className: "PreSessionScreen"}, [ return t.div({className: "PreSessionScreen"}, [
t.div({className: "logo"}), t.div({className: "logo"}),
t.div({className: "SessionLoadView"}, [ t.div({className: "SessionLoadView"}, [
t.h1(vm.i18n`Loading…`),
t.view(new SessionLoadStatusView(vm)) t.view(new SessionLoadStatusView(vm))
]) ]),
t.div({className: {"button-row": true, hidden: vm => vm.loading}},
t.a({className: "button-action primary", href: vm.backUrl}, vm.i18n`Go back`))
]); ]);
} }
} }