Skip to content

Commit

Permalink
Add support of link types in the link hover menu
Browse files Browse the repository at this point in the history
  • Loading branch information
keianhzo committed Jun 1, 2023
1 parent 6a51665 commit 02abe4e
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 10 deletions.
67 changes: 59 additions & 8 deletions src/bit-systems/link-hover-menu.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { defineQuery, enterQuery, entityExists } from "bitecs";
import type { HubsWorld } from "../app";
import { Interacted, Link, LinkHoverMenu, LinkHoverMenuItem, HoveredRemoteRight } from "../bit-components";
import { anyEntityWith } from "../utils/bit-utils";
import { Interacted, Link, LinkHoverMenu, LinkHoverMenuItem, HoveredRemoteRight, TextTag } from "../bit-components";
import { anyEntityWith, findChildWithComponent } from "../utils/bit-utils";
import { isHubsRoomUrl, isLocalHubsAvatarUrl, isLocalHubsSceneUrl, isLocalHubsUrl } from "../utils/media-url-utils";
import { Text as TroikaText } from "troika-three-text";
import { handleExitTo2DInterstitial } from "../utils/vr-interstitial";
import { changeHub } from "../change-hub";

const NULL_EID = 0;

Expand All @@ -17,10 +21,31 @@ export function linkHoverMenuSystem(world: HubsWorld) {
const menuObject = world.eid2obj.get(menuEid)!;

// Save Link object eid in LinkHoverMenu when hovered.
hoveredEnterQuery(world).forEach((eid: number) => {
hoveredEnterQuery(world).forEach(async (eid: number) => {
LinkHoverMenu.targetObjectRef[menuEid] = eid;
const targetObject = world.eid2obj.get(eid)!;
targetObject.add(menuObject);

const buttonRef = LinkHoverMenu.linkButtonRef[menuEid];
let text = findChildWithComponent(world, TextTag, buttonRef)!;
let textObj = world.eid2obj.get(text)! as TroikaText;
const mayChangeScene = (APP.scene?.systems as any).permissions.canOrWillIfCreator("update_hub");
const src = APP.getString(Link.url[eid])!;
let hubId;
let label = "open link";
if (await isLocalHubsAvatarUrl(src)) {
label = "use avatar";
} else if ((await isLocalHubsSceneUrl(src)) && mayChangeScene) {
label = "use scene";
} else if ((hubId = await isHubsRoomUrl(src))) {
const url = new URL(src);
if (url.hash && APP.hub!.hub_id === hubId) {
label = "go to";
} else {
label = "visit room";
}
}
textObj.text = label;
});

// Check if the cursor it hovered on Link object or Link menu button object.
Expand All @@ -30,11 +55,37 @@ export function linkHoverMenuSystem(world: HubsWorld) {
if (hovered && entityExists(world, linkEid)) {
// Hovered then make the menu visible and handle clicks if needed.
menuObject.visible = true;
if (clickedMenuItemQuery(world).length > 0) {
// TODO: Change the action and label depending on
// target (eg: switching avatars for avatar url)
window.open(APP.getString(Link.url[linkEid])!);
}
clickedMenuItemQuery(world).forEach(async eid => {
const linkEid = LinkHoverMenu.targetObjectRef[menuEid];
const src = APP.getString(Link.url[linkEid])!;
const exitImmersive = async () => await handleExitTo2DInterstitial(false, () => {}, true);

const mayChangeScene = (APP.scene?.systems as any).permissions.canOrWillIfCreator("update_hub");
let hubId;
if (await isLocalHubsAvatarUrl(src)) {
const avatarId = new URL(src).pathname.split("/").pop();
window.APP.store.update({ profile: { avatarId } });
APP.scene!.emit("avatar_updated");
} else if ((await isLocalHubsSceneUrl(src)) && mayChangeScene) {
APP.scene!.emit("scene_media_selected", src);
} else if ((hubId = await isHubsRoomUrl(src))) {
const url = new URL(src);
if (url.hash && APP.hub!.hub_id === hubId) {
// move to waypoint w/o writing to history
window.history.replaceState(null, "", window.location.href.split("#")[0] + url.hash);
} else if (await isLocalHubsUrl(src)) {
const waypoint = url.hash && url.hash.substring(1);
// move to new room without page load or entry flow
changeHub(hubId, true, waypoint);
} else {
await exitImmersive();
location.href = src;
}
} else {
await exitImmersive();
window.open(src);
}
});
} else {
// Not hovered or target object has already been deleted
// then make the menu invisible and forget the Link object.
Expand Down
2 changes: 1 addition & 1 deletion src/change-hub.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function loadRoomObjects(hubId) {
objectsScene.appendChild(objectsEl);
}

export async function changeHub(hubId, addToHistory = true, waypoint = null) {
export async function changeHub(hubId, addToHistory = true, waypoint = "") {
if (hubId === APP.hub.hub_id) {
console.log("Change hub called with the current hub id. This is a noop.");
return;
Expand Down
2 changes: 1 addition & 1 deletion src/components/open-media-button.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ AFRAME.registerComponent("open-media-button", {
if (url.hash && window.APP.hub.hub_id === hubId) {
// move to waypoint w/o writing to history
window.history.replaceState(null, null, window.location.href.split("#")[0] + url.hash);
} else if (isLocalHubsUrl(this.src)) {
} else if (await isLocalHubsUrl(this.src)) {
const waypoint = url.hash && url.hash.substring(1);
// move to new room without page load or entry flow
changeHub(hubId, true, waypoint);
Expand Down

0 comments on commit 02abe4e

Please sign in to comment.