mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 02:00:46 +00:00
reenable frontend
This commit is contained in:
1 parent
e2fe661bb7
commit
1622b68c64
9 files changed
+92
-73
No files matched your search
@@ -4,8 +4,8 @@ import Media from "../pages/media";
|
||||
import PressKit from "../pages/press-kit";
|
||||
import Navbar from "../components/navbar";
|
||||
import { ToastContainer } from "../components/toast/toast";
|
||||
// import CreateImage from "../pages/create-image";
|
||||
// import CreateVideo from "../pages/create-video";
|
||||
import CreateImage from "../pages/create-image";
|
||||
import CreateVideo from "../pages/create-video";
|
||||
import Landing2 from "../pages/landing2";
|
||||
import LandingSD2 from "../pages/landing-sd2";
|
||||
import TutorialsPage from "../pages/tutorials";
|
||||
@@ -30,8 +30,8 @@ export function App() {
|
||||
|
||||
<Routes>
|
||||
<Route path="/" element={<Landing2 />} />
|
||||
{/* <Route path="/create-image" element={<CreateImage />} />
|
||||
<Route path="/create-video" element={<CreateVideo />} /> */}
|
||||
<Route path="/create-image" element={<CreateImage />} />
|
||||
<Route path="/create-video" element={<CreateVideo />} />
|
||||
<Route path="/seedance-2" element={<LandingSD2 />} />
|
||||
<Route path="/download" element={<Download />} />
|
||||
<Route path="/media" element={<Media />} />
|
||||
|
||||
@@ -17,8 +17,8 @@ import { TaskQueue } from "./task-queue";
|
||||
|
||||
const NAV_ITEMS = [
|
||||
{ name: "Home", href: "/" },
|
||||
// { name: "Image", href: "/create-image" },
|
||||
// { name: "Video", href: "/create-video" },
|
||||
{ name: "Image", href: "/create-image" },
|
||||
{ name: "Video", href: "/create-video" },
|
||||
{ name: "Tutorials", href: "/tutorials" },
|
||||
{ name: "News", href: "/news" },
|
||||
{ name: "FAQ", href: "/faq" },
|
||||
|
||||
@@ -11,15 +11,16 @@ const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement,
|
||||
);
|
||||
|
||||
// In development, route API through the Vite dev server origin to avoid CORS
|
||||
if (import.meta.env.DEV) {
|
||||
try {
|
||||
const origin = window.location.origin;
|
||||
StorytellerApiHostStore.getInstance().setApiSchemeAndHost(origin);
|
||||
} catch (e) {
|
||||
console.warn("Failed to set dev API host override", e);
|
||||
}
|
||||
}
|
||||
// In development, route API through the Vite dev server proxy to avoid CORS,
|
||||
// unless VITE_API_HOST is explicitly set (eg. for an unsafe browser that ignores CORS).
|
||||
//if (import.meta.env.DEV && !import.meta.env.VITE_API_HOST) {
|
||||
// try {
|
||||
// const origin = window.location.origin;
|
||||
// StorytellerApiHostStore.getInstance().setApiSchemeAndHost(origin);
|
||||
// } catch (e) {
|
||||
// console.warn("Failed to set dev API host override", e);
|
||||
// }
|
||||
//}
|
||||
|
||||
// Cache the referrer immediately — it can change or disappear on navigation.
|
||||
// Only set once so subsequent in-site navigations don't overwrite the original.
|
||||
|
||||
@@ -50,9 +50,7 @@ const ROUTE_TO_FILTER: Record<string, string> = {
|
||||
meshes: "meshes",
|
||||
};
|
||||
|
||||
const getFilterMediaClass = (
|
||||
filter: string,
|
||||
): FilterMediaClasses[] | undefined => {
|
||||
const getFilterMediaClass = (filter: string): FilterMediaClasses[] | undefined => {
|
||||
switch (filter) {
|
||||
case "image":
|
||||
return [FilterMediaClasses.IMAGE];
|
||||
@@ -61,11 +59,7 @@ const getFilterMediaClass = (
|
||||
case "meshes":
|
||||
return [FilterMediaClasses.DIMENSIONAL];
|
||||
default:
|
||||
return [
|
||||
FilterMediaClasses.IMAGE,
|
||||
FilterMediaClasses.VIDEO,
|
||||
FilterMediaClasses.DIMENSIONAL,
|
||||
];
|
||||
return [FilterMediaClasses.IMAGE, FilterMediaClasses.VIDEO, FilterMediaClasses.DIMENSIONAL];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,9 +91,7 @@ const getLabel = (item: any) => {
|
||||
export default function Library() {
|
||||
const { filter: filterParam } = useParams<{ filter?: string }>();
|
||||
const navigate = useNavigate();
|
||||
const activeFilter = filterParam
|
||||
? (ROUTE_TO_FILTER[filterParam] ?? "all")
|
||||
: "all";
|
||||
const activeFilter = filterParam ? (ROUTE_TO_FILTER[filterParam] ?? "all") : "all";
|
||||
|
||||
const [username, setUsername] = useState<string | null>(null);
|
||||
const [isLoggedIn, setIsLoggedIn] = useState<boolean | null>(null);
|
||||
@@ -121,7 +113,11 @@ export default function Library() {
|
||||
const checkSession = async () => {
|
||||
const usersApi = new UsersApi();
|
||||
const response = await usersApi.GetSession();
|
||||
if (response.success && response.data?.loggedIn && response.data.user) {
|
||||
if (
|
||||
response.success &&
|
||||
response.data?.loggedIn &&
|
||||
response.data.user
|
||||
) {
|
||||
setUsername(response.data.user.username);
|
||||
setIsLoggedIn(true);
|
||||
} else {
|
||||
@@ -139,8 +135,8 @@ export default function Library() {
|
||||
const thumbnail = isDimensional
|
||||
? null
|
||||
: getMediaThumbnail(item.media_links, item.media_class, {
|
||||
size: THUMBNAIL_SIZES.MEDIUM,
|
||||
});
|
||||
size: THUMBNAIL_SIZES.MEDIUM,
|
||||
});
|
||||
|
||||
return {
|
||||
id: item.token,
|
||||
@@ -173,9 +169,7 @@ export default function Library() {
|
||||
|
||||
if (response.success && response.data) {
|
||||
const newItems = response.data
|
||||
.filter(
|
||||
(item: any) => item.media_type !== FilterMediaType.SCENE_JSON,
|
||||
)
|
||||
.filter((item: any) => item.media_type !== FilterMediaType.SCENE_JSON)
|
||||
.map(mapApiItem);
|
||||
|
||||
if (reset) {
|
||||
@@ -256,17 +250,17 @@ export default function Library() {
|
||||
const navigatePrev =
|
||||
currentIndex > 0
|
||||
? () => {
|
||||
const prev = flatItems[currentIndex - 1];
|
||||
setLightboxItem(prev);
|
||||
}
|
||||
const prev = flatItems[currentIndex - 1];
|
||||
setLightboxItem(prev);
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const navigateNext =
|
||||
currentIndex >= 0 && currentIndex < flatItems.length - 1
|
||||
? () => {
|
||||
const next = flatItems[currentIndex + 1];
|
||||
setLightboxItem(next);
|
||||
}
|
||||
const next = flatItems[currentIndex + 1];
|
||||
setLightboxItem(next);
|
||||
}
|
||||
: undefined;
|
||||
|
||||
const handleItemDeleted = useCallback((id: string) => {
|
||||
@@ -347,11 +341,10 @@ export default function Library() {
|
||||
<button
|
||||
key={filter.id}
|
||||
onClick={() => navigate(filter.route)}
|
||||
className={`flex items-center gap-2 px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${
|
||||
activeFilter === filter.id
|
||||
className={`flex items-center gap-2 px-4 py-1.5 rounded-md text-sm font-medium transition-colors ${activeFilter === filter.id
|
||||
? "bg-ui-controls text-white"
|
||||
: "text-white/60 hover:text-white"
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
<FontAwesomeIcon icon={filter.icon} className="text-xs" />
|
||||
{filter.label}
|
||||
@@ -393,8 +386,10 @@ export default function Library() {
|
||||
</div>
|
||||
) : allItems.length === 0 && !loading ? (
|
||||
<div className="flex flex-col items-center justify-center py-20">
|
||||
<p className="text-white/40 text-sm mb-4">No items yet.</p>
|
||||
{/* <div className="flex gap-3">
|
||||
<p className="text-white/40 text-sm mb-4">
|
||||
No items yet. Start generating!
|
||||
</p>
|
||||
<div className="flex gap-3">
|
||||
<Link to="/create-image">
|
||||
<Button variant="primary" className="text-sm px-4 py-2">
|
||||
Create Image
|
||||
@@ -408,7 +403,7 @@ export default function Library() {
|
||||
Create Video
|
||||
</Button>
|
||||
</Link>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
|
||||
@@ -60,7 +60,9 @@ export class ApiManager {
|
||||
}
|
||||
|
||||
protected getApiSchemeAndHost(): string {
|
||||
return StorytellerApiHostStore.getInstance().getApiSchemeAndHost();
|
||||
const host = StorytellerApiHostStore.getInstance().getApiSchemeAndHost();
|
||||
console.log('getSchemaAndHost()', host);
|
||||
return host;
|
||||
}
|
||||
|
||||
public async fetch<B, T>(
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
// Artcraft / Storyteller API backend
|
||||
const DEFAULT_API_HOST = "https://api.storyteller.ai";
|
||||
// Set VITE_API_HOST=http://localhost:12345 for local dev, or leave unset for production.
|
||||
//const DEFAULT_API_HOST = (import.meta as any).env?.VITE_API_HOST || "https://api.storyteller.ai";
|
||||
|
||||
const DEFAULT_API_HOST = "http://localhost:12345";
|
||||
|
||||
// NB(bt,2025-09-25): 'nx' is creating multiple copies of the library with name
|
||||
// mangling, so the singleton pattern fails to resolve to a single instance.
|
||||
|
||||
@@ -137,7 +137,7 @@ export const GalleryDraggableItem: React.FC<GalleryDraggableItemProps> = ({
|
||||
tabIndex={-1}
|
||||
className={twMerge(
|
||||
"w-full group relative overflow-visible rounded-md border-[3px] transition-all focus:outline-none",
|
||||
item.mediaClass === "video" ? "aspect-video" : "aspect-square",
|
||||
"aspect-square",
|
||||
selected || bulkSelected
|
||||
? "border-primary"
|
||||
: disableTooltipAndBadge
|
||||
@@ -171,7 +171,7 @@ export const GalleryDraggableItem: React.FC<GalleryDraggableItemProps> = ({
|
||||
alt={item.label}
|
||||
className={twMerge(
|
||||
"h-full w-full bg-black/30",
|
||||
item.mediaClass === "video" || imageFit === "contain" ? "object-contain" : "object-cover",
|
||||
imageFit === "contain" ? "object-contain" : "object-cover",
|
||||
)}
|
||||
draggable={false}
|
||||
onError={onImageError}
|
||||
@@ -187,7 +187,7 @@ export const GalleryDraggableItem: React.FC<GalleryDraggableItemProps> = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={twMerge("group relative w-full", item.mediaClass === "video" ? "aspect-video" : "aspect-square")}>
|
||||
<div className={twMerge("group relative w-full", "aspect-square")}>
|
||||
{/* dropdown menu */}
|
||||
{mode !== "select" && (
|
||||
<div
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../slider-v2"
|
||||
},
|
||||
{
|
||||
"path": "../button-icon-select"
|
||||
},
|
||||
@@ -14,9 +17,6 @@
|
||||
{
|
||||
"path": "../camera-settings-modal"
|
||||
},
|
||||
{
|
||||
"path": "../toaster"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-utils"
|
||||
},
|
||||
@@ -26,29 +26,38 @@
|
||||
{
|
||||
"path": "../../model-list"
|
||||
},
|
||||
{
|
||||
"path": "../modal"
|
||||
},
|
||||
{
|
||||
"path": "../popover"
|
||||
},
|
||||
{
|
||||
"path": "../slider-v2"
|
||||
},
|
||||
{
|
||||
"path": "../../common"
|
||||
},
|
||||
{
|
||||
"path": "../../api"
|
||||
"path": "../tooltip"
|
||||
},
|
||||
{
|
||||
"path": "../action-reminder-modal"
|
||||
},
|
||||
{
|
||||
"path": "../label"
|
||||
},
|
||||
{
|
||||
"path": "../button"
|
||||
},
|
||||
{
|
||||
"path": "../input"
|
||||
},
|
||||
{
|
||||
"path": "../gallery-modal"
|
||||
},
|
||||
{
|
||||
"path": "../tooltip"
|
||||
"path": "../toaster"
|
||||
},
|
||||
{
|
||||
"path": "../button"
|
||||
"path": "../../api"
|
||||
},
|
||||
{
|
||||
"path": "../modal"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
|
||||
@@ -43,6 +43,9 @@
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../slider-v2/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../button-icon-select/tsconfig.lib.json"
|
||||
},
|
||||
@@ -55,9 +58,6 @@
|
||||
{
|
||||
"path": "../camera-settings-modal/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../toaster/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-utils/tsconfig.lib.json"
|
||||
},
|
||||
@@ -67,29 +67,38 @@
|
||||
{
|
||||
"path": "../../model-list/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../modal/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../popover/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../slider-v2/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../common/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../api/tsconfig.lib.json"
|
||||
"path": "../tooltip/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../action-reminder-modal/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../label/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../button/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../input/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../gallery-modal/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../tooltip/tsconfig.lib.json"
|
||||
"path": "../toaster/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../button/tsconfig.lib.json"
|
||||
"path": "../../api/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../modal/tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user