Compare commits

...
Author SHA1 Message Date
BFlat 1696efc922 Revert "shared component starting with toaster (#521)"
This reverts commit 35eac53b9d.
2025-04-17 17:20:26 +07:00
19 changed files with 184 additions and 293 deletions
-1
View File
@@ -15,7 +15,6 @@
"preview": "vite preview"
},
"dependencies": {
"@storyteller/shared": "file:../../shared/*",
"@devnomic/marquee": "^1.0.3",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
+3 -3
View File
@@ -5,7 +5,7 @@ import { RouterProvider } from "react-router-dom";
import { router } from "./router";
import { posthog } from "posthog-js";
import { PostHogProvider } from "posthog-js/react";
import { Toaster } from "@storyteller/shared/components";
import { Toaster } from "~/components/ui/Toast";
import { JobProvider } from "~/components/JobContext";
import "./global.css";
import { useRenderCounter } from "~/hooks/useRenderCounter";
@@ -33,7 +33,7 @@ const App = () => {
<JobProvider>
<PostHogProvider client={posthog}>
<RouterProvider router={router} />
<Toaster topOffset={70} rightOffset={12} />
<Toaster />
</PostHogProvider>
</JobProvider>
</StrictMode>
@@ -43,7 +43,7 @@ const App = () => {
<>
<JobProvider>
<RouterProvider router={router} />
<Toaster topOffset={70} rightOffset={12} />
<Toaster />
</JobProvider>
</>
);
@@ -77,9 +77,8 @@ export const Main = withProtectionRoute(() => {
</div>
</div>
</div>
{appModeValue === "gallery" && (
<GalleryRootComponent className="z-1 fixed h-full w-full bg-black" />
)}
{appModeValue === "gallery" &&
(<GalleryRootComponent className="fixed h-full w-full z-1 bg-black" />)}
</div>
);
});
@@ -6,7 +6,7 @@ import { CompletedCard } from "./CompletedCard";
import { InProgressCard } from "./InProgressCard";
import { useJobContext } from "~/components/JobContext";
import { Api } from "~/KonvaApp/Api";
import { toast } from "@storyteller/shared/components";
import { toast } from "sonner";
// Dummy data types
interface CompletedItem {
@@ -199,7 +199,7 @@ export function Activity() {
</div>
) : completedItems.length === 0 && jobs.length === 0 ? (
<div className="flex h-48 w-full flex-col justify-center gap-4 p-4 text-center align-middle">
<h3 className="text-lg text-gray-300">No activities yet</h3>
<h3 className="text-gray-300">No activities yet</h3>
</div>
) : (
<div>
+1 -2
View File
@@ -21,8 +21,7 @@
"noFallthroughCasesInSwitch": true,
"paths": {
"~/*": ["./src/*"],
"@ApiManager/*": ["./src/Classes/ApiManager/*"],
"@storyteller/shared/*": ["../../shared/*"]
"@ApiManager/*": ["./src/Classes/ApiManager/*"]
}
},
"include": ["src"]
@@ -52,7 +52,7 @@ export const TopBar = ({ pageName }: Props) => {
<SceneTitleInput pageName={pageName} />
</div>
<div className="flex justify-end gap-3">
<div className="flex justify-end gap-5">
<div className="flex gap-2">
<Button
variant="secondary"
@@ -6,8 +6,9 @@ import { useBackgroundLoadingMedia } from "~/hooks/useBackgroundLoadingMedia";
import { useQueueHandler } from "./hooks/useQueueHandler";
import { ErrorDialog, LoadingDots } from "~/components";
import { GenerateModals } from "~/pages/PageEnigma/comps/GenerateModals/GenerateModals";
import { Toaster } from "@storyteller/shared/components";
import { EditorLoadingBar } from "./comps/EditorLoadingBar";
import { Wizard } from "~/pages/PageEnigma/Wizard/Wizard";
import { useSignals } from "@preact/signals-react/runtime";
import { useEffect, useState } from "react";
@@ -16,12 +17,7 @@ import { UsersApi } from "~/Classes/ApiManager";
import { PageEnigmaComponent } from "~/pages/PageEnigma/PageEnigmaComponent";
import { TurnOnGpu } from "~/pages/PageEnigma/TurnOnGpu";
import { PrecisionSelector } from "./comps/PrecisionSelector/PrecisionSelector";
import {
precisionSelectedValue,
precisionSelectorMenuCoords,
precisionSelectorValues,
showPrecisionSelector,
} from "./signals/precisionSelectorMenu";
import { precisionSelectedValue, precisionSelectorMenuCoords, precisionSelectorValues, showPrecisionSelector } from "./signals/precisionSelectorMenu";
export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
useSignals();
@@ -108,7 +104,6 @@ export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
<GenerateModals />
<ErrorDialog />
<Wizard />
<Toaster topOffset={70} rightOffset={12} />
</EngineProvider>
<EditorLoadingBar />
</TrackProvider>
@@ -4,10 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PopoverMenu } from "~/components/reusable/Popover/Popover";
import { CompletedCard } from "./CompletedCard";
import { InProgressCard } from "./InProgressCard";
import { H3, Tooltip } from "~/components";
import { useEffect, useState, useRef, useCallback } from "react";
import { H3, P, Tooltip } from "~/components";
import { activeImageGenerationJobs, toasts, userMovies } from "~/signals";
import { useEffect, useState } from "react";
import { JobsApi } from "~/Classes/ApiManager/JobsApi";
import { toast } from "@storyteller/shared/components";
import { toast } from "sonner";
import { ActiveJob } from "~/pages/PageEnigma/models";
// TODO ensure we de-dupe all this extra code.
interface CompletedItem {
@@ -59,49 +60,26 @@ interface CompletedItem {
export function Activity() {
useSignals();
const [completedItems, setCompletedItems] = useState<CompletedItem[]>([]);
const [loading, setLoading] = useState(true);
const [jobs, setJobs] = useState<ActiveJob[]>([]);
const processedJobs = useRef(new Set<string>());
const isFirstLoad = useRef(true);
const toastTimeoutRef = useRef<NodeJS.Timeout | null>(null);
// Debounced toast function
const showToast = useCallback((items: CompletedItem[]) => {
if (toastTimeoutRef.current) {
clearTimeout(toastTimeoutRef.current);
}
toastTimeoutRef.current = setTimeout(() => {
const count = items.length;
toast.success(
count === 1
? `${items[0].maybe_title} completed successfully`
: `${count} images completed successfully`,
);
toastTimeoutRef.current = null;
}, 100); // Small delay to catch potential double calls
}, []);
useEffect(() => {
let mounted = true;
const pollData = async () => {
const fetchJobs = async () => {
try {
const jobsApi = new JobsApi();
const jobsResponse = await jobsApi.ListRecentJobs();
async function fetchJobs() {
try {
const jobsApi = new JobsApi();
const response = await jobsApi.ListRecentJobs();
if (!mounted || !response.success || !response.data) return;
// Handle active jobs
const activeJobs = response.data
.filter((job) => {
const status = job.status?.status?.toLowerCase();
return (
status && status !== "complete_success" && status !== "failed"
);
})
.map(
(job) =>
({
if (jobsResponse.success && jobsResponse.data) {
// Process active jobs
const activeJobs = jobsResponse.data
.filter((job) => {
const status = job.status?.status?.toLowerCase();
return (
status && status !== "complete_success" && status !== "failed"
);
})
.map((job) => ({
job_token: job.job_token,
request: {
maybe_model_title:
@@ -111,78 +89,79 @@ export function Activity() {
status: job.status?.status?.toUpperCase() || "",
progress_percentage: job.status?.progress_percentage || 0,
},
created_at: job.created_at || new Date().toISOString(),
}));
// Process completed items
// Get completed items and filter out any that are already in our list
const successfulJobs = jobsResponse.data.filter(
(job) => job.status?.status?.toLowerCase() === "complete_success",
);
// Create a set of existing tokens for faster lookup
const existingTokens = new Set(
completedItems.map((item) => item.token),
);
// Filter out jobs we already have in our list
const newCompletedItems = successfulJobs
.filter((job) => !existingTokens.has(job.job_token))
.map((job) => ({
token: job.job_token,
maybe_title:
job.request?.maybe_model_title || "Image Generation",
public_bucket_path:
job.maybe_result?.maybe_public_bucket_media_path || "",
updated_at: job.updated_at || new Date().toISOString(),
maybe_result: job.maybe_result || null,
}) as ActiveJob,
);
}));
// Handle completed jobs
const newlyCompleted = response.data.filter(
(job) =>
job.status?.status?.toLowerCase() === "complete_success" &&
!processedJobs.current.has(job.job_token),
);
// Show toast notification for newly completed items
if (newCompletedItems.length > 0) {
const count = newCompletedItems.length;
const message =
count === 1
? `${newCompletedItems[0].maybe_title} completed successfully`
: `${count} images completed successfully`;
toast.success(message);
}
if (newlyCompleted.length > 0) {
// Add to processed set
newlyCompleted.forEach((job) =>
processedJobs.current.add(job.job_token),
);
// Create completed items
const newItems = newlyCompleted.map((job) => ({
token: job.job_token,
maybe_title: job.request?.maybe_model_title || "Image Generation",
public_bucket_path:
job.maybe_result?.maybe_public_bucket_media_path || "",
updated_at: job.updated_at || new Date().toISOString(),
}));
// Show toast only if not first load
if (!isFirstLoad.current) {
showToast(newItems);
// Update completed items with a maximum limit of 50 items
setCompletedItems((prev) => {
const combined = [...newCompletedItems, ...prev];
// Remove duplicates based on token
const uniqueItems = Array.from(
new Map(combined.map((item) => [item.token, item])).values(),
);
// Sort by updated_at in descending order and limit to 50 items
return uniqueItems
.sort(
(a, b) =>
new Date(b.updated_at).getTime() -
new Date(a.updated_at).getTime(),
)
.slice(0, 50);
});
setJobs(activeJobs as ActiveJob[]);
setLoading(false);
}
// Update state
setCompletedItems((prev) => {
const combined = [...newItems, ...prev];
return combined
.filter(
(item, index, self) =>
index === self.findIndex((t) => t.token === item.token),
)
.sort(
(a, b) =>
new Date(b.updated_at).getTime() -
new Date(a.updated_at).getTime(),
)
.slice(0, 50);
});
} catch (error) {
toast.error("Error Fetching Recent Jobs");
console.error("Failed to fetch recent jobs:", error);
}
setJobs(activeJobs);
isFirstLoad.current = false;
} catch (error) {
console.error("Failed to fetch jobs:", error);
}
}
// Initial fetch
fetchJobs();
// Set up polling
const interval = setInterval(fetchJobs, 5000);
// Cleanup
return () => {
mounted = false;
clearInterval(interval);
if (toastTimeoutRef.current) {
clearTimeout(toastTimeoutRef.current);
}
};
await fetchJobs();
};
}, [showToast]);
// Initial load
// Initial call to pollData
pollData();
// Set up polling interval (every 5 seconds)
const interval = setInterval(async () => {
await pollData();
}, 5000);
return () => clearInterval(interval);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
<Tooltip content="Activity" position="bottom" closeOnClick={true}>
@@ -194,19 +173,20 @@ export function Activity() {
align="end"
triggerIcon={
<div>
{jobs.length > 0 ? (
{jobs && jobs.length > 0 ? (
<FontAwesomeIcon icon={faSpinnerThird} className="animate-spin" />
) : (
<FontAwesomeIcon icon={faBell} />
)}
{jobs.length > 0 && (
<div className="absolute -right-1 -top-1 h-3 w-3 animate-pulse rounded-full bg-brand-primary-400" />
{jobs && jobs.length > 0 && (
<div className="bg-blue-500 absolute -right-1 -top-1 h-3 w-3 animate-pulse rounded-full" />
)}
</div>
}
>
<div className="max-h-[480px] overflow-y-auto">
{jobs.length > 0 && (
{/* In progress */}
{jobs && jobs.length > 0 && (
<div>
{jobs.map((job) => (
<InProgressCard key={job.job_token} job={job} />
@@ -214,7 +194,7 @@ export function Activity() {
</div>
)}
{isFirstLoad.current ? (
{!userMovies.value && !activeImageGenerationJobs.value ? (
<div className="flex h-48 w-full flex-col justify-center gap-4 p-4 text-center align-middle">
<FontAwesomeIcon
icon={faSpinnerThird}
@@ -224,12 +204,18 @@ export function Activity() {
/>
<H3 className="text-gray-300">Retrieving Activities</H3>
</div>
) : jobs.length === 0 && completedItems.length === 0 ? (
) : userMovies.value &&
userMovies.value.length === 0 &&
!activeImageGenerationJobs.value ? (
<div className="flex h-48 w-full flex-col justify-center gap-4 p-4 text-center align-middle">
<h3 className="text-lg text-gray-300">No activities yet</h3>
<H3 className="text-gray-300">No activities yet</H3>
<P className="text-gray-400">
Try generating something new from the featured scenes
</P>
</div>
) : (
<div>
{/* Completed */}
<div className="flex flex-col">
{completedItems.map((item) => (
<CompletedCard key={item.token} job={item} />
@@ -58,7 +58,6 @@ interface ReferenceImage {
import { EngineApi } from "~/Classes/ApiManager/EngineApi";
import { UploaderStates } from "~/enums/UploaderStates";
import { CameraSettingsModal } from "../CameraSettingsModal";
import { toast } from "@storyteller/shared/components";
export const PromptBox = () => {
useSignals();
@@ -431,7 +430,7 @@ export const PromptBox = () => {
screenshot: snapshot.file,
sceneMediaToken: "",
});
console.log("useSystemPrompt", useSystemPrompt);
await engineApi.enqueueImageGeneration({
disableSystemPrompt: !useSystemPrompt,
@@ -452,7 +451,6 @@ export const PromptBox = () => {
await new Promise((resolve) => setTimeout(resolve, 2000));
} finally {
setisEnqueueing(false);
toast.success("Image generation enqueued");
}
}
setisEnqueueing(false);
+9 -10
View File
@@ -22,14 +22,13 @@
},
"dependencies": {
"@storyteller/api": "file:../../libs/api",
"@storyteller/shared": "file:../../shared/*",
"@awesome.me/kit-fde2be5eb0": "^1.0.7",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/pro-regular-svg-icons": "^6.7.2",
"@fortawesome/pro-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@headlessui/react": "^2.1.3",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18",
"@mediapipe/tasks-vision": "^0.10.20",
"@netlify/edge-functions": "^2.3.1",
"@netlify/remix-edge-adapter": "^3.2.0",
@@ -54,9 +53,9 @@
"isbot": "^4.1.0",
"lodash.debounce": "^4.0.8",
"posthog-js": "^1.141.0",
"react": "^18.3.1",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18.3.1",
"react-dom": "^18.2.0",
"react-drag-drop-files": "^2.3.10",
"react-helmet": "^6.1.0",
"react-image-crop": "^11.0.5",
@@ -64,7 +63,7 @@
"tailwind-merge": "^2.2.2",
"terser": "^5.30.3",
"three": "^0.162.0",
"uuid": "^10.0.0",
"uuid": "^9.0.1",
"wavesurfer.js": "^7.7.11",
"webm-writer": "^1.0.0"
},
+14 -4
View File
@@ -1,7 +1,16 @@
{
"include": ["env.d.ts", "**/*.ts", "**/*.tsx", "netlify-edge-plugin.ts"],
"include": [
"env.d.ts",
"**/*.ts",
"**/*.tsx",
"netlify-edge-plugin.ts"
],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
@@ -15,8 +24,9 @@
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"],
"@storyteller/shared/*": ["../../shared/*"]
"~/*": [
"./app/*"
]
},
// Vite takes care of building everything, not tsc.
"noEmit": true
+43 -80
View File
@@ -69,7 +69,6 @@
"@fortawesome/react-fontawesome": "^0.2.2",
"@headlessui/react": "^2.1.3",
"@preact/signals-react": "^2.2.0",
"@storyteller/shared": "file:../../shared/*",
"@tauri-apps/api": "^2.2.0",
"@techstark/opencv-js": "^4.10.0-release.1",
"@zip.js/zip.js": "^2.7.52",
@@ -571,6 +570,25 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"apps/editor2d/node_modules/@headlessui/react": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.1.tgz",
"integrity": "sha512-daiUqVLae8CKVjEVT19P/izW0aGK0GNhMSAeMlrDebKmoVZHcRRwbxzgtnEadUVDXyBsWo9/UH4KHeniO+0tMg==",
"license": "MIT",
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@react-aria/focus": "^3.17.1",
"@react-aria/interactions": "^3.21.3",
"@tanstack/react-virtual": "^3.11.1"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"react-dom": "^18 || ^19 || ^19.0.0-rc"
}
},
"apps/editor2d/node_modules/@preact/signals-react": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@preact/signals-react/-/signals-react-2.3.0.tgz",
@@ -1161,12 +1179,12 @@
"apps/editor3d": {
"dependencies": {
"@awesome.me/kit-fde2be5eb0": "^1.0.7",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/pro-regular-svg-icons": "^6.7.2",
"@fortawesome/pro-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@headlessui/react": "^2.1.3",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
"@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18",
"@mediapipe/tasks-vision": "^0.10.20",
"@netlify/edge-functions": "^2.3.1",
"@netlify/remix-edge-adapter": "^3.2.0",
@@ -1178,7 +1196,6 @@
"@remix-run/router": "^1.15.3",
"@remix-run/serve": "^2.8.1",
"@storyteller/api": "file:../../libs/api",
"@storyteller/shared": "file:../../shared/*",
"@tweenjs/tween.js": "^18.6.4",
"@types/lodash": "^4.17.6",
"@types/react-virtualized": "^9.22.2",
@@ -1193,9 +1210,9 @@
"isbot": "^4.1.0",
"lodash.debounce": "^4.0.8",
"posthog-js": "^1.141.0",
"react": "^18.3.1",
"react": "^18.2.0",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18.3.1",
"react-dom": "^18.2.0",
"react-drag-drop-files": "^2.3.10",
"react-helmet": "^6.1.0",
"react-image-crop": "^11.0.5",
@@ -1203,7 +1220,7 @@
"tailwind-merge": "^2.2.2",
"terser": "^5.30.3",
"three": "^0.162.0",
"uuid": "^10.0.0",
"uuid": "^9.0.1",
"wavesurfer.js": "^7.7.11",
"webm-writer": "^1.0.0"
},
@@ -1668,10 +1685,6 @@
"react": "^16.14.0 || 17.x || 18.x || 19.x"
}
},
"apps/editor3d/node_modules/@storyteller/shared": {
"resolved": "shared/components",
"link": true
},
"apps/editor3d/node_modules/@types/react": {
"version": "18.3.20",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz",
@@ -1919,41 +1932,6 @@
}
}
},
"apps/editor3d/node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"dependencies": {
"loose-envify": "^1.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"apps/editor3d/node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"apps/editor3d/node_modules/uuid": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/bin/uuid"
}
},
"apps/editor3d/node_modules/vite": {
"version": "5.4.18",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.18.tgz",
@@ -4737,21 +4715,20 @@
}
},
"node_modules/@headlessui/react": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.1.tgz",
"integrity": "sha512-daiUqVLae8CKVjEVT19P/izW0aGK0GNhMSAeMlrDebKmoVZHcRRwbxzgtnEadUVDXyBsWo9/UH4KHeniO+0tMg==",
"version": "1.7.19",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.19.tgz",
"integrity": "sha512-Ll+8q3OlMJfJbAKM/+/Y2q6PPYbryqNTXDbryx7SXLIDamkF6iQFbriYHga0dY44PvDhvvBWCx1Xj4U5+G4hOw==",
"license": "MIT",
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@react-aria/focus": "^3.17.1",
"@react-aria/interactions": "^3.21.3",
"@tanstack/react-virtual": "^3.11.1"
"@tanstack/react-virtual": "^3.0.0-beta.60",
"client-only": "^0.0.1"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"react-dom": "^18 || ^19 || ^19.0.0-rc"
"react": "^16 || ^17 || ^18",
"react-dom": "^16 || ^17 || ^18"
}
},
"node_modules/@humanfs/core": {
@@ -9920,10 +9897,6 @@
"resolved": "libs/api",
"link": true
},
"node_modules/@storyteller/shared": {
"resolved": "shared/*",
"link": true
},
"node_modules/@svgr/babel-plugin-add-jsx-attribute": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz",
@@ -14609,6 +14582,12 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/client-only": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@@ -30581,7 +30560,6 @@
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
"dev": true,
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
@@ -31875,21 +31853,6 @@
"type": "github",
"url": "https://github.com/sponsors/wooorm"
}
},
"shared": {
"name": "@storyteller/shared",
"version": "0.0.1",
"dependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0",
"sonner": "^1.4.3"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"shared/*": {},
"shared/components": {}
}
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
packages:
- "apps/*"
- "libs/*"
- "shared/*"
- 'apps/*'
- 'libs/*'
@@ -1,23 +0,0 @@
import { Toaster as SonnerToaster } from "sonner";
interface ToasterProps {
topOffset?: number;
rightOffset?: number;
}
export const Toaster = ({ topOffset = 0, rightOffset = 0 }: ToasterProps) => {
return (
<div className="relative z-[9]">
<SonnerToaster
position="top-right"
expand={false}
richColors
closeButton
style={{ top: topOffset, right: rightOffset }}
/>
</div>
);
};
// Re-export toast function from sonner for easy access
export { toast } from "sonner";
-1
View File
@@ -1 +0,0 @@
export * from "./Toaster";
-1
View File
@@ -1 +0,0 @@
-19
View File
@@ -1,19 +0,0 @@
{
"name": "@storyteller/shared",
"version": "0.0.1",
"private": true,
"main": "./components/index.ts",
"exports": {
"./components": "./components/index.ts",
"./contexts": "./contexts/index.ts"
},
"dependencies": {
"sonner": "^1.4.3",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
}
-12
View File
@@ -1,12 +0,0 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": ".",
"declaration": true,
"composite": true,
"jsx": "react-jsx"
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["dist", "node_modules"]
}
+1 -2
View File
@@ -16,7 +16,6 @@
"skipLibCheck": true,
"strict": true,
"target": "es2022",
"customConditions": ["development"],
"baseUrl": "."
"customConditions": ["development"]
}
}