Skip to content

Commit

Permalink
Add pinning support
Browse files Browse the repository at this point in the history
  • Loading branch information
keianhzo committed Sep 13, 2023
1 parent 59eefaa commit 273f33e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 26 deletions.
83 changes: 59 additions & 24 deletions src/react-components/room/object-hooks.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { useEffect, useState, useCallback, useMemo } from "react";
import { removeNetworkedObject } from "../../utils/removeNetworkedObject";
import { shouldUseNewLoader } from "../../utils/bit-utils";
import { findAncestorWithComponent, shouldUseNewLoader } from "../../utils/bit-utils";
import { rotateInPlaceAroundWorldUp, affixToWorldUp } from "../../utils/three-utils";
import { getPromotionTokenForFile } from "../../utils/media-utils";
import { hasComponent } from "bitecs";
import { isPinned as isObjectPinned } from "../../bit-systems/networking";
import { isPinned as getPinnedState } from "../../bit-systems/networking";
import { MediaInfo, Static } from "../../bit-components";
import { MediaContentBounds, MediaInfo, MediaLoader, Owned, Static } from "../../bit-components";
import { deleteTheDeletableAncestor } from "../../bit-systems/delete-entity-system";
import { setPinned } from "../../utils/bit-pinning-helper";
import { debounce } from "lodash";

export function isMe(object) {
return object.id === "avatar-rig";
}

export function isPlayer(object) {
if (shouldUseNewLoader()) {
// TODO Add when networked avatar is migrated
// TODO Add when networked avatar is migrated?
// We don't list players in the objects list so do we need this function at all?
return false;
} else {
return !!object.el.components["networked-avatar"];
Expand Down Expand Up @@ -43,29 +47,51 @@ export function usePinObject(hubChannel, scene, object) {
const [isPinned, setIsPinned] = useState(getPinnedState(object.eid));

const pinObject = useCallback(() => {
const el = object.el;
if (!NAF.utils.isMine(el) && !NAF.utils.takeOwnership(el)) return;
window.APP.pinningHelper.setPinned(el, true);
}, [object]);
if (shouldUseNewLoader()) {
const mediaRootEid = findAncestorWithComponent(APP.world, MediaContentBounds, object.eid);
setPinned(hubChannel, APP.world, mediaRootEid, true);
} else {
const el = object.el;
if (!NAF.utils.isMine(el) && !NAF.utils.takeOwnership(el)) return;
window.APP.pinningHelper.setPinned(el, true);
}
}, [object, hubChannel]);

const unpinObject = useCallback(() => {
const el = object.el;
if (!NAF.utils.isMine(el) && !NAF.utils.takeOwnership(el)) return;
window.APP.pinningHelper.setPinned(el, false);
}, [object]);
if (shouldUseNewLoader()) {
const mediaRootEid = findAncestorWithComponent(APP.world, MediaContentBounds, object.eid);
setPinned(hubChannel, APP.world, mediaRootEid, false);
} else {
const el = object.el;
if (!NAF.utils.isMine(el) && !NAF.utils.takeOwnership(el)) return;
window.APP.pinningHelper.setPinned(el, false);
}
}, [object, hubChannel]);

const togglePinned = useCallback(() => {
const _togglePinned = useCallback(() => {
if (isPinned) {
unpinObject();
} else {
pinObject();
}
}, [isPinned, pinObject, unpinObject]);

const togglePinned = useMemo(() => debounce(_togglePinned, 100), [_togglePinned]);
useEffect(() => {
return () => {
togglePinned.cancel();
};
}, [togglePinned]);

useEffect(() => {
// TODO Add when pinning is migrated
if (shouldUseNewLoader()) {
return;
const handler = setInterval(() => {
const mediaRootEid = findAncestorWithComponent(APP.world, MediaContentBounds, object.eid);
setIsPinned(isObjectPinned(mediaRootEid));
}, 100);
return () => {
clearInterval(handler);
};
}

const el = object.el;
Expand All @@ -82,24 +108,33 @@ export function usePinObject(hubChannel, scene, object) {
};
}, [object]);

if (shouldUseNewLoader()) {
// TODO Add when pinning is migrated
return false;
}

const el = object.el;

let userOwnsFile = false;

if (el.components["media-loader"]) {
const { fileIsOwned, fileId } = el.components["media-loader"].data;
if (shouldUseNewLoader()) {
const fileId = MediaLoader.fileId[object.eid];
const mediaRootEid = findAncestorWithComponent(APP.world, MediaContentBounds, object.eid);
const fileIsOwned = hasComponent(APP.world, Owned, mediaRootEid);
userOwnsFile = fileIsOwned || (fileId && getPromotionTokenForFile(fileId));
} else {
const el = object.el;
if (el.components["media-loader"]) {
const { fileIsOwned, fileId } = el.components["media-loader"].data;
userOwnsFile = fileIsOwned || (fileId && getPromotionTokenForFile(fileId));
}
}

let targetEid;
if (shouldUseNewLoader()) {
targetEid = findAncestorWithComponent(APP.world, MediaContentBounds, object.eid);
} else {
targetEid = object.el.eid;
}
const isStatic = hasComponent(APP.world, Static, targetEid);

const canPin = !!(
scene.is("entered") &&
!isPlayer(object) &&
!hasComponent(APP.world, Static, el.eid) &&
!isStatic &&
hubChannel.can("pin_objects") &&
userOwnsFile
);
Expand Down
3 changes: 3 additions & 0 deletions src/scene-entry-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export default class SceneEntryManager {
this.leftCursorController = document.getElementById("left-cursor-controller");
this.avatarRig = document.getElementById("avatar-rig");
this._entered = false;
/**
* @type {Function}
*/
this.performConditionalSignIn = () => {};
this.history = history;
}
Expand Down
11 changes: 9 additions & 2 deletions src/utils/bit-pinning-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import HubChannel from "./hub-channel";
import { EntityID } from "./networking-types";
import { takeOwnership } from "./take-ownership";
import { createMessageDatas, isNetworkInstantiated, isPinned } from "../bit-systems/networking";
import { SignInMessages } from "../react-components/auth/SignInModal";

export const setPinned = async (hubChannel: HubChannel, world: HubsWorld, eid: EntityID, shouldPin: boolean) => {
_signInAndPinOrUnpinElement(hubChannel, world, eid, shouldPin);
Expand All @@ -29,8 +30,14 @@ const unpinElement = (hubChannel: HubChannel, world: HubsWorld, eid: EntityID) =

const _signInAndPinOrUnpinElement = (hubChannel: HubChannel, world: HubsWorld, eid: EntityID, shouldPin: boolean) => {
const action = shouldPin ? () => _pinElement(hubChannel, world, eid) : () => unpinElement(hubChannel, world, eid);
// TODO: Perform conditional sign in
action();
APP.entryManager!.performConditionalSignIn(
() => hubChannel.signedIn,
action,
shouldPin ? SignInMessages.pin : SignInMessages.unpin,
(e: Error) => {
console.warn(`PinningHelper: Conditional sign-in failed. ${e}`);
}
);
};

export const canPin = (hubChannel: HubChannel, eid: EntityID): boolean => {
Expand Down

0 comments on commit 273f33e

Please sign in to comment.