Allows useResource to have empty string

main
jaxoncreed 2 years ago
parent c98b451c7a
commit b616e720b2
  1. 35
      packages/demo-react/old/BlurTextInput.tsx
  2. 37
      packages/demo-react/old/Layout.tsx
  3. 40
      packages/demo-react/old/Profile.tsx
  4. 15
      packages/demo-react/src/MainContainerProvider.tsx
  5. 27
      packages/solid-react/src/useResource.ts

@ -1,35 +0,0 @@
import type { FunctionComponent } from "react";
import React, { useState } from "react";
interface BlurTextInputProps {
value: string;
onBlurText: (text: string) => void;
}
const BlurTextInput: FunctionComponent<BlurTextInputProps> = ({
value,
onBlurText,
}) => {
const [isFocused, setIsFocused] = useState(false);
const [text, setText] = useState(value);
return (
<input
type="text"
value={isFocused ? text : value}
onChange={(e) => setText(e.target.value)}
onFocus={() => {
setIsFocused(true);
setText(value);
}}
onBlur={(e) => {
setIsFocused(false);
if (e.target.value !== value) {
onBlurText(e.target.value);
}
}}
/>
);
};
export default BlurTextInput;

@ -1,37 +0,0 @@
import type { FunctionComponent, PropsWithChildren } from "react";
import React, { useCallback } from "react";
import { useSolidAuth } from "@ldobjects/solid-react";
const Layout: FunctionComponent<PropsWithChildren> = ({ children }) => {
const { login, session, logout } = useSolidAuth();
const loginCb = useCallback(async () => {
const issuer = prompt(
"Enter your Pod Provider",
"https://solidcommunity.net",
);
if (issuer) {
await login(issuer);
}
}, []);
return (
<div>
<h1>LDO Solid React Test</h1>
{session.isLoggedIn ? (
<div>
<p>
Logged in as {session.webId}{" "}
<button onClick={logout}>Log Out</button>
</p>
<hr />
{children}
</div>
) : (
<button onClick={loginCb}>Log In</button>
)}
</div>
);
};
export default Layout;

@ -1,40 +0,0 @@
import type { FunctionComponent } from "react";
import React from "react";
import { SolidProfileShapeShapeType } from "./ldo/solidProfile.shapeTypes";
import BlurTextInput from "./BlurTextInput";
import {
useSolidAuth,
useLdo,
useDataResource,
useSubject,
} from "@ldobjects/solid-react";
const Profile: FunctionComponent = () => {
const { changeData, commitData } = useLdo();
const { session } = useSolidAuth();
const webId = session.webId!;
const webIdResource = useDataResource(webId);
const [profile, profileError] = useSubject(SolidProfileShapeShapeType, webId);
if (webIdResource.isLoading) {
return <p>Loading</p>;
} else if (profileError) {
return <p>profileError.message</p>;
} else {
return (
<div>
<label>Name:</label>
<BlurTextInput
value={profile.name || ""}
onBlurText={async (text) => {
const cProfile = changeData(profile, webIdResource);
cProfile.name = text;
await commitData(cProfile);
}}
/>
</div>
);
}
};
export default Profile;

@ -3,13 +3,12 @@ import type { FunctionComponent, PropsWithChildren } from "react";
import type { Container, LeafUri } from "@ldobjects/solid"; import type { Container, LeafUri } from "@ldobjects/solid";
import { useSolidAuth, useLdo, useResource } from "@ldobjects/solid-react"; import { useSolidAuth, useLdo, useResource } from "@ldobjects/solid-react";
// Context will be set before any of it's children are rendered. export const MainContainerContext = createContext<Container | undefined>(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment undefined,
// @ts-ignore );
export const MainContainerContext = createContext<Container>(undefined);
const MainContainerSubProvider: FunctionComponent< const MainContainerSubProvider: FunctionComponent<
PropsWithChildren<{ uri: string }> PropsWithChildren<{ uri?: string }>
> = ({ uri, children }) => { > = ({ uri, children }) => {
const mainContainer = useResource(uri); const mainContainer = useResource(uri);
return ( return (
@ -60,12 +59,8 @@ export const MainContainerProvider: FunctionComponent<PropsWithChildren> = ({
} }
}, [session.webId]); }, [session.webId]);
if (!mainContainer) {
return null;
}
return ( return (
<MainContainerSubProvider uri={mainContainer.uri}> <MainContainerSubProvider uri={mainContainer?.uri}>
{children} {children}
</MainContainerSubProvider> </MainContainerSubProvider>
); );

@ -23,13 +23,26 @@ export function useResource(
options?: UseResourceOptions, options?: UseResourceOptions,
): Leaf | Container; ): Leaf | Container;
export function useResource( export function useResource(
uri: string, uri?: ContainerUri,
options?: UseResourceOptions,
): Container | undefined;
export function useResource(
uri?: LeafUri,
options?: UseResourceOptions,
): Leaf | undefined;
export function useResource(
uri?: string,
options?: UseResourceOptions, options?: UseResourceOptions,
): Leaf | Container { ): Leaf | Container | undefined;
export function useResource(
uri?: string,
options?: UseResourceOptions,
): Leaf | Container | undefined {
const { getResource } = useLdo(); const { getResource } = useLdo();
// Get the resource // Get the resource
const resource = useMemo(() => { const resource = useMemo(() => {
if (uri) {
const resource = getResource(uri); const resource = getResource(uri);
// Run read operations if necissary // Run read operations if necissary
if (!options?.suppressInitialRead) { if (!options?.suppressInitialRead) {
@ -40,24 +53,26 @@ export function useResource(
} }
} }
return resource; return resource;
}
return undefined;
}, [getResource, uri]); }, [getResource, uri]);
const [resourceRepresentation, setResourceRepresentation] = const [resourceRepresentation, setResourceRepresentation] =
useState(resource); useState(resource);
const pastResource = useRef< const pastResource = useRef<
{ resource: Resource; callback: () => void } | undefined { resource?: Resource; callback: () => void } | undefined
>(); >();
// Callback function to force the react dom to reload. // Callback function to force the react dom to reload.
const forceReload = useCallback( const forceReload = useCallback(
// Wrap the resource in a proxy so it's techically a different object // Wrap the resource in a proxy so it's techically a different object
() => { () => {
setResourceRepresentation(new Proxy(resource, {})); if (resource) setResourceRepresentation(new Proxy(resource, {}));
}, },
[resource], [resource],
); );
useEffect(() => { useEffect(() => {
// Remove listeners for the previous resource // Remove listeners for the previous resource
if (pastResource.current) { if (pastResource.current?.resource) {
pastResource.current.resource.off( pastResource.current.resource.off(
"update", "update",
pastResource.current.callback, pastResource.current.callback,
@ -65,6 +80,7 @@ export function useResource(
} }
// Set a new past resource to the current resource // Set a new past resource to the current resource
pastResource.current = { resource, callback: forceReload }; pastResource.current = { resource, callback: forceReload };
if (resource) {
// Add listener // Add listener
resource.on("update", forceReload); resource.on("update", forceReload);
@ -72,6 +88,7 @@ export function useResource(
return () => { return () => {
resource.off("update", forceReload); resource.off("update", forceReload);
}; };
}
}, [resource]); }, [resource]);
return resourceRepresentation; return resourceRepresentation;
} }

Loading…
Cancel
Save