mirror of
https://github.com/vector-im/hydrogen-web.git
synced 2025-02-02 07:31:38 +01:00
Merge pull request #939 from vector-im/fix-451
Fix '/' in room-id or mxid breaking navigation
This commit is contained in:
commit
cbf2d1c8e3
@ -144,7 +144,7 @@ export class URLRouter<T extends {session: string | boolean}> implements IURLRou
|
|||||||
|
|
||||||
openRoomActionUrl(roomId: string): string {
|
openRoomActionUrl(roomId: string): string {
|
||||||
// not a segment to navigation knowns about, so append it manually
|
// not a segment to navigation knowns about, so append it manually
|
||||||
const urlPath = `${this._stringifyPath(this._navigation.path.until("session"))}/open-room/${roomId}`;
|
const urlPath = `${this._stringifyPath(this._navigation.path.until("session"))}/open-room/${encodeURIComponent(roomId)}`;
|
||||||
return this._history.pathAsUrl(urlPath);
|
return this._history.pathAsUrl(urlPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ export function parseUrlPath(urlPath: string, currentNavPath: Path<SegmentType>,
|
|||||||
if (type === "rooms") {
|
if (type === "rooms") {
|
||||||
const roomsValue = iterator.next().value;
|
const roomsValue = iterator.next().value;
|
||||||
if (roomsValue === undefined) { break; }
|
if (roomsValue === undefined) { break; }
|
||||||
const roomIds = roomsValue.split(",");
|
const roomIds = roomsValue.split(",").map(id => decodeURIComponent(id));
|
||||||
segments.push(new Segment(type, roomIds));
|
segments.push(new Segment(type, roomIds));
|
||||||
const selectedIndex = parseInt(iterator.next().value || "0", 10);
|
const selectedIndex = parseInt(iterator.next().value || "0", 10);
|
||||||
const roomId = roomIds[selectedIndex];
|
const roomId = roomIds[selectedIndex];
|
||||||
@ -147,8 +147,9 @@ export function parseUrlPath(urlPath: string, currentNavPath: Path<SegmentType>,
|
|||||||
segments.push(new Segment("empty-grid-tile", selectedIndex));
|
segments.push(new Segment("empty-grid-tile", selectedIndex));
|
||||||
}
|
}
|
||||||
} else if (type === "open-room") {
|
} else if (type === "open-room") {
|
||||||
const roomId = iterator.next().value;
|
let roomId = iterator.next().value;
|
||||||
if (!roomId) { break; }
|
if (!roomId) { break; }
|
||||||
|
roomId = decodeURIComponent(roomId);
|
||||||
const rooms = currentNavPath.get("rooms");
|
const rooms = currentNavPath.get("rooms");
|
||||||
if (rooms) {
|
if (rooms) {
|
||||||
segments.push(roomsSegmentWithRoom(rooms, roomId, currentNavPath));
|
segments.push(roomsSegmentWithRoom(rooms, roomId, currentNavPath));
|
||||||
@ -176,8 +177,9 @@ export function parseUrlPath(urlPath: string, currentNavPath: Path<SegmentType>,
|
|||||||
} else if (type === "details" || type === "members") {
|
} else if (type === "details" || type === "members") {
|
||||||
pushRightPanelSegment(segments, type);
|
pushRightPanelSegment(segments, type);
|
||||||
} else if (type === "member") {
|
} else if (type === "member") {
|
||||||
const userId = iterator.next().value;
|
let userId = iterator.next().value;
|
||||||
if (!userId) { break; }
|
if (!userId) { break; }
|
||||||
|
userId = decodeURIComponent(userId);
|
||||||
pushRightPanelSegment(segments, type, userId);
|
pushRightPanelSegment(segments, type, userId);
|
||||||
} else if (type.includes("loginToken")) {
|
} else if (type.includes("loginToken")) {
|
||||||
// Special case for SSO-login with query parameter loginToken=<token>
|
// Special case for SSO-login with query parameter loginToken=<token>
|
||||||
@ -185,7 +187,11 @@ export function parseUrlPath(urlPath: string, currentNavPath: Path<SegmentType>,
|
|||||||
segments.push(new Segment("sso", loginToken));
|
segments.push(new Segment("sso", loginToken));
|
||||||
} 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;
|
let value = iterator.next().value;
|
||||||
|
if (value) {
|
||||||
|
// decode only if value isn't undefined!
|
||||||
|
value = decodeURIComponent(value)
|
||||||
|
}
|
||||||
segments.push(new Segment(type, value));
|
segments.push(new Segment(type, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,19 +202,20 @@ export function stringifyPath(path: Path<SegmentType>): string {
|
|||||||
let urlPath = "";
|
let urlPath = "";
|
||||||
let prevSegment: Segment<SegmentType> | undefined;
|
let prevSegment: Segment<SegmentType> | undefined;
|
||||||
for (const segment of path.segments) {
|
for (const segment of path.segments) {
|
||||||
|
const encodedSegmentValue = encodeSegmentValue(segment.value);
|
||||||
switch (segment.type) {
|
switch (segment.type) {
|
||||||
case "rooms":
|
case "rooms":
|
||||||
urlPath += `/rooms/${segment.value.join(",")}`;
|
urlPath += `/rooms/${encodedSegmentValue}`;
|
||||||
break;
|
break;
|
||||||
case "empty-grid-tile":
|
case "empty-grid-tile":
|
||||||
urlPath += `/${segment.value}`;
|
urlPath += `/${encodedSegmentValue}`;
|
||||||
break;
|
break;
|
||||||
case "room":
|
case "room":
|
||||||
if (prevSegment?.type === "rooms") {
|
if (prevSegment?.type === "rooms") {
|
||||||
const index = prevSegment.value.indexOf(segment.value);
|
const index = prevSegment.value.indexOf(segment.value);
|
||||||
urlPath += `/${index}`;
|
urlPath += `/${index}`;
|
||||||
} else {
|
} else {
|
||||||
urlPath += `/${segment.type}/${segment.value}`;
|
urlPath += `/${segment.type}/${encodedSegmentValue}`;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "right-panel":
|
case "right-panel":
|
||||||
@ -217,8 +224,8 @@ export function stringifyPath(path: Path<SegmentType>): string {
|
|||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
urlPath += `/${segment.type}`;
|
urlPath += `/${segment.type}`;
|
||||||
if (segment.value && segment.value !== true) {
|
if (encodedSegmentValue) {
|
||||||
urlPath += `/${segment.value}`;
|
urlPath += `/${encodedSegmentValue}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prevSegment = segment;
|
prevSegment = segment;
|
||||||
@ -226,6 +233,19 @@ export function stringifyPath(path: Path<SegmentType>): string {
|
|||||||
return urlPath;
|
return urlPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function encodeSegmentValue(value: SegmentType[keyof SegmentType]): string {
|
||||||
|
if (value === true) {
|
||||||
|
// Nothing to encode for boolean
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
else if (Array.isArray(value)) {
|
||||||
|
return value.map(v => encodeURIComponent(v)).join(",");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return encodeURIComponent(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function tests() {
|
export function tests() {
|
||||||
function createEmptyPath() {
|
function createEmptyPath() {
|
||||||
const nav: Navigation<SegmentType> = new Navigation(allowsChild);
|
const nav: Navigation<SegmentType> = new Navigation(allowsChild);
|
||||||
|
@ -48,7 +48,7 @@ export class MemberTileViewModel extends ViewModel {
|
|||||||
|
|
||||||
get detailsUrl() {
|
get detailsUrl() {
|
||||||
const roomId = this.navigation.path.get("room").value;
|
const roomId = this.navigation.path.get("room").value;
|
||||||
return `${this.urlRouter.openRoomActionUrl(roomId)}/member/${this._member.userId}`;
|
return `${this.urlRouter.openRoomActionUrl(roomId)}/member/${encodeURIComponent(this._member.userId)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_updatePreviousName(newName) {
|
_updatePreviousName(newName) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user