Skip to content

Commit

Permalink
save work
Browse files Browse the repository at this point in the history
  • Loading branch information
nounspaceryan committed Jul 8, 2024
1 parent c18d047 commit 9f00091
Show file tree
Hide file tree
Showing 15 changed files with 409 additions and 233 deletions.
1 change: 1 addition & 0 deletions src/common/components/organisms/EditorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const EditorPanel: React.FC<EditorPanelProps> = ({
setIsPickingFidget,
openFidgetPicker,
}) => {
console.log("Rendering EditorPanel");
function generateFidgetInstance(
fidgetId: string,
fidget: FidgetModule<FidgetArgs>,
Expand Down
157 changes: 50 additions & 107 deletions src/common/components/pages/UserDefinedSpace.tsx
Original file line number Diff line number Diff line change
@@ -1,114 +1,48 @@
import { indexOf, isNil, mapValues, noop } from "lodash";
import { isNil, mapValues, noop } from "lodash";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useAuthenticatorManager } from "@/authenticators/AuthenticatorManager";
import { useAppStore } from "@/common/data/stores/app";
import createIntialPersonSpaceConfigForFid from "@/constants/initialPersonSpace";
import { SpaceConfigSaveDetails } from "../templates/Space";
import Profile from "@/fidgets/ui/profile";
import SpacePage from "./SpacePage";

const FARCASTER_NOUNSPACE_AUTHENTICATOR_NAME = "farcaster:nounspace";
import { useSpaceConfig } from "@/common/lib/hooks/useCurrentSpaceConfig";
import useCurrentUserFid from "@/common/lib/hooks/useCurrentUserFid";
import useIsSpaceEditable from "@/common/lib/hooks/useIsSpaceEditable";

export default function UserDefinedSpace({
spaceId: providedSpaceId,
spaceId: spaceId,
fid,
}: {
spaceId: string | null;
fid: number;
}) {
const {
lastUpdatedAt: authManagerLastUpdatedAt,
getInitializedAuthenticators: authManagerGetInitializedAuthenticators,
callMethod: authManagerCallMethod,
} = useAuthenticatorManager();
const {
editableSpaces,
loadSpace,
remoteSpaces,
saveLocalCopy,
commitSpaceToDb,
registerSpace,
getCurrentSpaceConfig,
setCurrentSpaceId,
} = useAppStore((state) => ({
editableSpaces: state.space.editableSpaces,
loadSpace: state.space.loadSpace,
remoteSpaces: state.space.remoteSpaces,
saveLocalCopy: state.space.saveLocalSpace,
commitSpaceToDb: state.space.commitSpaceToDatabase,
registerSpace: state.space.registerSpace,
currentSpaceId: state.currentSpace.currentSpaceId,
getCurrentSpaceConfig: state.currentSpace.getCurrentSpaceConfig,
setCurrentSpaceId: state.currentSpace.setCurrentSpaceId,
}));
const [loading, setLoading] = useState(!isNil(providedSpaceId));

useEffect(() => {
setCurrentSpaceId(providedSpaceId);
if (!isNil(providedSpaceId)) {
setLoading(true);
loadSpace(providedSpaceId, fid).then(() => {
setSpaceId(providedSpaceId);
setLoading(false);
});
}
}, [providedSpaceId]);

const [spaceId, setSpaceId] = useState(providedSpaceId);

const [isSignedIntoFarcaster, setIsSignedIntoFarcaster] = useState(false);
useEffect(() => {
authManagerGetInitializedAuthenticators().then((authNames) => {
setIsSignedIntoFarcaster(
indexOf(authNames, FARCASTER_NOUNSPACE_AUTHENTICATOR_NAME) > -1,
);
});
}, [authManagerLastUpdatedAt]);

const [currentUserFid, setCurrentUserFid] = useState<number | null>(null);
useEffect(() => {
if (!isSignedIntoFarcaster) return;
authManagerCallMethod({
requestingFidgetId: "root",
authenticatorId: FARCASTER_NOUNSPACE_AUTHENTICATOR_NAME,
methodName: "getAccountFid",
isLookup: true,
}).then((authManagerResp) => {
if (authManagerResp.result === "success") {
setCurrentUserFid(authManagerResp.value as number);
}
});
}, [isSignedIntoFarcaster, authManagerLastUpdatedAt]);

const isEditable = useMemo(() => {
return (
(isNil(spaceId) && fid === currentUserFid) ||
(!isNil(spaceId) && spaceId in editableSpaces)
);
}, [editableSpaces, currentUserFid]);

const INITIAL_PERSONAL_SPACE_CONFIG = useMemo(
() => createIntialPersonSpaceConfigForFid(fid),
[fid],
);

const currentConfig = getCurrentSpaceConfig();

const config = useMemo(
() => ({
...(currentConfig ? currentConfig : INITIAL_PERSONAL_SPACE_CONFIG),
isEditable,
}),
[currentConfig, isEditable],
);

useEffect(() => {
if (isEditable && isNil(spaceId) && !isNil(currentUserFid)) {
registerSpace(currentUserFid, "profile").then((newSpaceId) => {
setSpaceId(newSpaceId || null);
});
}
}, [isEditable, spaceId, currentUserFid]);
const { spaceConfig, loading } = useSpaceConfig(spaceId);

const { remoteSpaces, saveLocalCopy, commitSpaceToDb, registerSpace } =
useAppStore((state) => ({
remoteSpaces: state.space.remoteSpaces,
saveLocalCopy: state.space.saveLocalSpace,
commitSpaceToDb: state.space.commitSpaceToDatabase,
registerSpace: state.space.registerSpace,
}));
const currentUserFid = useCurrentUserFid();
const isEditable = useIsSpaceEditable(spaceId, fid);

const newSpaceConfigTemplate = useMemo(() => {
return createIntialPersonSpaceConfigForFid(fid);
}, [fid]);

const config = spaceConfig ?? newSpaceConfigTemplate;

// Create/register a new space if user is authed, on their own profile,
// and their space hasn't been created yet
// useEffect(() => {
// if (isEditable && isNil(spaceId) && !isNil(currentUserFid)) {
// registerSpace(currentUserFid, "profile").then((newSpaceId) => {
// setSpaceId(newSpaceId || null);
// });
// }
// }, [isEditable, spaceId, currentUserFid]);

const saveConfig = useCallback(
async (spaceConfig: SpaceConfigSaveDetails) => {
Expand Down Expand Up @@ -146,22 +80,31 @@ export default function UserDefinedSpace({
if (isNil(spaceId)) return;
if (isNil(remoteSpaces[spaceId])) {
saveLocalCopy(spaceId, {
...INITIAL_PERSONAL_SPACE_CONFIG,
...newSpaceConfigTemplate,
isPrivate: false,
});
} else {
saveLocalCopy(spaceId, remoteSpaces[spaceId].config);
}
}, [spaceId, INITIAL_PERSONAL_SPACE_CONFIG, remoteSpaces]);

const profile = (
<Profile.fidget
settings={{ fid }}
saveData={async () => noop()}
data={{}}
/>
}, [spaceId, newSpaceConfigTemplate, remoteSpaces]);

const profile = useMemo(
() => (
<Profile.fidget
settings={{ fid }}
saveData={async () => noop()}
data={{}}
/>
),
[fid],
);

console.log(config, spaceId, fid);

if (!config) {
return null;
}

return (
<SpacePage
config={config}
Expand Down
2 changes: 1 addition & 1 deletion src/common/data/stores/app/currentSpace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export type CurrentSpaceStore = CurrentSpaceStoreState &
CurrentSpaceStoreActions;

export const currentSpaceStoreDefaults: CurrentSpaceStoreState = {
currentSpaceId: HOMEBASE_ID,
currentSpaceId: null,
};

export const createCurrentSpaceStoreFunc = (
Expand Down
24 changes: 13 additions & 11 deletions src/common/data/stores/app/space/spaceStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from "@/common/providers/AnalyticsProvider";
import createIntialPersonSpaceConfigForFid from "@/constants/initialPersonSpace";

type SpaceId = string;
export type SpaceId = string;

// SpaceConfig includes all of the Fidget Config
// But a space that is saved in the DB doesn't store
Expand Down Expand Up @@ -71,7 +71,7 @@ export type UpdatableSpaceConfig = DatabaseWritableSpaceConfig & {
isPrivate: boolean;
};

interface CachedSpace {
export interface CachedSpace {
// Machine generated ID, immutable
id: SpaceId;
config: UpdatableSpaceConfig;
Expand All @@ -85,7 +85,7 @@ interface SpaceState {
}

interface SpaceActions {
loadSpace: (spaceId: string, fid: number) => Promise<void>;
loadSpace: (spaceId: string, fid?: number) => Promise<void>;
registerSpace: (fid: number, name: string) => Promise<string | undefined>;
renameSpace: (spaceId: string, name: string) => Promise<void>;
loadEditableSpaces: () => Promise<Record<SpaceId, string>>;
Expand All @@ -110,7 +110,7 @@ export const createSpaceStoreFunc = (
get: StoreGet<AppStore>,
): SpaceStore => ({
...spaceStoreDefaults,
loadSpace: async (spaceId, fid) => {
loadSpace: async (spaceId, fid?) => {
// TO DO: skip if cached copy is recent enough
try {
const supabase = createClient();
Expand Down Expand Up @@ -143,13 +143,15 @@ export const createSpaceStoreFunc = (
draft.space.localSpaces[spaceId] = cloneDeep(updatableSpaceConfig);
}, "loadSpace");
} catch (e) {
const initialHomebase = {
...createIntialPersonSpaceConfigForFid(fid),
isPrivate: false,
};
set((draft) => {
draft.space.localSpaces[spaceId] = cloneDeep(initialHomebase);
}, "loadSpace");
if (fid) {
const initialHomebase = {
...createIntialPersonSpaceConfigForFid(fid),
isPrivate: false,
};
set((draft) => {
draft.space.localSpaces[spaceId] = cloneDeep(initialHomebase);
}, "loadSpace");
}
console.debug(e);
}
},
Expand Down
77 changes: 77 additions & 0 deletions src/common/lib/hooks/useCurrentSpaceConfig.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { useState, useEffect, useCallback } from "react";
import { mapValues } from "lodash";
import { useAppStore } from "@/common/data/stores/app";
import { SpaceConfig } from "@/common/components/templates/Space";
import useIsSpaceEditable from "@/common/lib/hooks/useIsSpaceEditable";
import { SpaceId } from "@/common/data/stores/app/space/spaceStore";
import { useCurrentSpaceId } from "@/common/lib/hooks/useIsSpaceEditable";

const HOMEBASE_ID = "homebase";

interface useSpaceConfigReturnValue {
spaceConfig?: SpaceConfig | null;
loading: boolean;
}

export const useCurrentSpaceConfig = (): useSpaceConfigReturnValue => {
const spaceId = useCurrentSpaceId();
return useSpaceConfig(spaceId);
};

// Gets space config from local data store (localStorage)
const useLocalSpaceConfig = (spaceId?: SpaceId | null): SpaceConfig | null => {
const isEditable = useIsSpaceEditable(spaceId);

return useAppStore((state) => {
if (spaceId === HOMEBASE_ID) return state.homebase.homebaseConfig;
if (!spaceId || !(spaceId in state.space.localSpaces)) return null;

const spaceConfig = state.space.localSpaces[spaceId];
if (!spaceConfig) return null;

const fidgetInstanceDatums = mapValues(
spaceConfig.fidgetInstanceDatums,
(datum) => ({
...datum,
config: {
settings: datum.config.settings,
editable: datum.config.editable,
data: {}, // TO DO: Inject fidget data here
},
}),
);

// Populate missing fields
return { ...spaceConfig, isEditable, fidgetInstanceDatums };
}) as SpaceConfig | null;
};

export const useSpaceConfig = (
spaceId?: SpaceId | null,
): useSpaceConfigReturnValue => {
const [loading, setLoading] = useState(false);
const { loadSpace, setCurrentSpaceId } = useAppStore((state) => ({
loadSpace: state.space.loadSpace,
setCurrentSpaceId: state.currentSpace.setCurrentSpaceId,
}));
const spaceConfig = useLocalSpaceConfig(spaceId);

const refetch = useCallback(async () => {
if (spaceId) {
setLoading(true);
await loadSpace(spaceId);
setLoading(false);
}
}, [spaceId]);

useEffect(() => {
if (spaceId) {
setCurrentSpaceId(spaceId);
refetch();
}
}, [spaceId]);

return { spaceConfig, loading };
};

export default useCurrentSpaceConfig;
10 changes: 10 additions & 0 deletions src/common/lib/hooks/useCurrentSpaceTheme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useCurrentSpaceConfig } from "@/common/lib/hooks/useCurrentSpaceConfig";
import DEFAULT_THEME from "@/common/lib/theme/defaultTheme";
import { UserTheme } from "@/common/lib/theme";

export const useCurrentSpaceTheme = (): UserTheme => {
const { spaceConfig } = useCurrentSpaceConfig();
return spaceConfig?.theme ?? DEFAULT_THEME;
};

export default useCurrentSpaceTheme;
34 changes: 34 additions & 0 deletions src/common/lib/hooks/useCurrentUserFid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useEffect, useState } from "react";
import { useAuthenticatorManager } from "@/authenticators/AuthenticatorManager";
import useIsSignedIntoFarcaster from "@/common/lib/hooks/useIsSignedIntoFarcaster";

const FARCASTER_NOUNSPACE_AUTHENTICATOR_NAME = "farcaster:nounspace";

export const useCurrentUserFid = () => {
const [currentUserFid, setCurrentUserFid] = useState<number | null>(null);
const { callMethod: authManagerCallMethod, lastUpdatedAt } =
useAuthenticatorManager();
const isSignedIntoFarcaster = useIsSignedIntoFarcaster();

useEffect(() => {
if (!isSignedIntoFarcaster || !lastUpdatedAt) return;

const fetchCurrentUserFid = async () => {
const authManagerResp = await authManagerCallMethod({
requestingFidgetId: "root",
authenticatorId: FARCASTER_NOUNSPACE_AUTHENTICATOR_NAME,
methodName: "getAccountFid",
isLookup: true,
});
if (authManagerResp.result === "success") {
setCurrentUserFid(authManagerResp.value as number);
}
};

fetchCurrentUserFid();
}, [isSignedIntoFarcaster, lastUpdatedAt]);

return currentUserFid;
};

export default useCurrentUserFid;
7 changes: 7 additions & 0 deletions src/common/lib/hooks/useEditableSpaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useAppStore } from "@/common/data/stores/app";

export const useEditableSpaces = () => {
return useAppStore((state) => state.space.editableSpaces);
};

export default useEditableSpaces;
Loading

0 comments on commit 9f00091

Please sign in to comment.