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

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

Loading…
Cancel
Save