mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 09:28:11 +00:00
open the login modals on failure !
This commit is contained in:
1 parent
26c856ed43
commit
3960cfcfec
20 files changed
+421
-9
No files matched your search
@@ -28,6 +28,7 @@ import { PageEditor } from "~/pages/PageEnigma/PageEditor";
|
||||
import { GalleryDragComponent } from "@storyteller/ui-gallery-modal";
|
||||
import { LoadingDots } from "@storyteller/ui-loading";
|
||||
import { PricingModal } from "@storyteller/ui-pricing-modal";
|
||||
import { ProviderSetupModal } from "@storyteller/provider-setup-modal";
|
||||
|
||||
import {
|
||||
isActionReminderOpen,
|
||||
@@ -35,6 +36,8 @@ import {
|
||||
ActionReminderModal,
|
||||
} from "@storyteller/ui-action-reminder-modal";
|
||||
import { useFlashUserInputErrorEvent } from "@storyteller/tauri-events";
|
||||
import { useShowProviderLoginModalEvent } from "@storyteller/tauri-events";
|
||||
|
||||
|
||||
export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
|
||||
useSignals();
|
||||
@@ -93,6 +96,11 @@ export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
|
||||
toast.error(event.message);
|
||||
});
|
||||
|
||||
useShowProviderLoginModalEvent(async (event) => {
|
||||
console.log("Show provider login modal event received:", event);
|
||||
toast.error(event.provider);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log("installing event listeners");
|
||||
InstallSounds();
|
||||
@@ -120,6 +128,7 @@ export const PageEnigma = ({ sceneToken }: { sceneToken?: string }) => {
|
||||
/>
|
||||
<GenerateModals />
|
||||
<ErrorDialog />
|
||||
<ProviderSetupModal />
|
||||
|
||||
<EditorLoadingBar />
|
||||
<Toaster offsetTop={70} offsetRight={12} />
|
||||
|
||||
@@ -115,6 +115,9 @@
|
||||
{
|
||||
"path": "../../libs/components/upload-modal"
|
||||
},
|
||||
{
|
||||
"path": "../../libs/components/provider-setup-modal"
|
||||
},
|
||||
{
|
||||
"path": "../../libs/components/modal"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
export enum GenerationProvider {
|
||||
Artcraft = "artcraft",
|
||||
Fal = "fal",
|
||||
Midjourney = "midjourney",
|
||||
Sora = "sora",
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
export * from "./EditorState";
|
||||
export * from "./Queue";
|
||||
export * from "./UploaderStates";
|
||||
export * from "./Hotkeys";
|
||||
export * from "./Toaster";
|
||||
export * from "./AssetFilterOption";
|
||||
export * from "./ThumbnailsFileType";
|
||||
export * from "./EditorState";
|
||||
export * from "./GenerationProvider";
|
||||
export * from "./Hotkeys";
|
||||
export * from "./MediaFileAnimationType";
|
||||
export * from "./Queue";
|
||||
export * from "./ThumbnailsFileType";
|
||||
export * from "./Toaster";
|
||||
export * from "./UploaderStates";
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@nx/react/babel",
|
||||
{
|
||||
"runtime": "automatic",
|
||||
"useBuiltIns": "usage"
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# @frontend/provider-setup-modal
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test @frontend/provider-setup-modal` to execute the unit tests via [Vitest](https://vitest.dev/).
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@storyteller/provider-setup-modal",
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"development": "./src/index.ts",
|
||||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './lib/provider-setup-modal';
|
||||
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Replace this with your own classes
|
||||
*
|
||||
* e.g.
|
||||
* .container {
|
||||
* }
|
||||
*/
|
||||
@@ -0,0 +1,12 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import FrontendProviderSetupModal from './provider-setup-modal';
|
||||
|
||||
describe('FrontendProviderSetupModal', () => {
|
||||
|
||||
it('should render successfully', () => {
|
||||
const { baseElement } = render(<FrontendProviderSetupModal />);
|
||||
expect(baseElement).toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,118 @@
|
||||
import { Modal } from "@storyteller/ui-modal";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faArrowRight,
|
||||
faMagicWandSparkles,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Button } from "@storyteller/ui-button";
|
||||
import { useState } from "react";
|
||||
import { useShowProviderLoginModalEvent } from "@storyteller/tauri-events";
|
||||
import { GenerationProvider } from "@storyteller/common";
|
||||
|
||||
interface ProviderSetupModalProps {
|
||||
}
|
||||
|
||||
export function ProviderSetupModal({
|
||||
}: ProviderSetupModalProps) {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [provider, setProvider] = useState<GenerationProvider>(GenerationProvider.Artcraft);
|
||||
|
||||
useShowProviderLoginModalEvent(async (event) => {
|
||||
console.log("Show provider login modal event received from Tauri:", event);
|
||||
setProvider(event.provider);
|
||||
setShowModal(true);
|
||||
});
|
||||
|
||||
const serviceProviderName = getServiceProviderName(provider);
|
||||
|
||||
const modalTitle = `Set up ${serviceProviderName}`;
|
||||
const modalSubTitle = `Add your ${serviceProviderName} account to ArtCraft!`;
|
||||
|
||||
const modalDescription = `You can add your ${serviceProviderName} account to ArtCraft by simply logging in. Use your credits and account directly within Artcraft. You can add all of your AI accounts to Artcraft to use them all in one place and build the ultimate AI art tool.`;
|
||||
|
||||
const modalButtonText = `Set up ${serviceProviderName}`;
|
||||
|
||||
const buttonOnClick = async () => {
|
||||
switch (provider) {
|
||||
case GenerationProvider.Midjourney:
|
||||
await invoke("midjourney_open_login_command");
|
||||
break;
|
||||
case GenerationProvider.Sora:
|
||||
await invoke("open_sora_login_command"); // TODO: Rename in Tauri
|
||||
break;
|
||||
case GenerationProvider.Fal:
|
||||
break; // TODO: None yet.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
setShowModal(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
//title={modalTitle}
|
||||
isOpen={showModal}
|
||||
onClose={() => {
|
||||
setShowModal(false);
|
||||
}}
|
||||
className="max-w-2xl max-h-[500px] p-6"
|
||||
showClose={true}
|
||||
>
|
||||
<div className="flex flex-col items-center justify-center gap-6">
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="text-3xl font-bold">
|
||||
<FontAwesomeIcon
|
||||
icon={faMagicWandSparkles}
|
||||
className="mr-3 text-[24px]"
|
||||
/>
|
||||
{modalTitle}
|
||||
</h1>
|
||||
<div className="text-center">
|
||||
<p className="text-lg font-medium text-white/80">{modalSubTitle}</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p className="text-white/60">{modalDescription}</p>
|
||||
|
||||
<br />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/*<div className="aspect-video w-full overflow-hidden rounded-md">
|
||||
Test
|
||||
</div>*/}
|
||||
<Button
|
||||
className="font-semibold"
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
onClick={() => {
|
||||
buttonOnClick();
|
||||
}}
|
||||
>
|
||||
{modalButtonText}
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
function getServiceProviderName(provider: GenerationProvider) : string {
|
||||
switch (provider) {
|
||||
case GenerationProvider.Sora:
|
||||
return "Sora";
|
||||
case GenerationProvider.Fal:
|
||||
return "Fal";
|
||||
case GenerationProvider.Midjourney:
|
||||
return "Midjourney";
|
||||
case GenerationProvider.Artcraft:
|
||||
default:
|
||||
return "Artcraft";
|
||||
}
|
||||
}
|
||||
|
||||
export default ProviderSetupModal;
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "../button"
|
||||
},
|
||||
{
|
||||
"path": "../modal"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-events"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-api"
|
||||
},
|
||||
{
|
||||
"path": "../../common"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"extends": "../../../tsconfig.base.json"
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"types": [
|
||||
"node",
|
||||
"@nx/react/typings/cssmodule.d.ts",
|
||||
"@nx/react/typings/image.d.ts",
|
||||
"vite/client"
|
||||
],
|
||||
"rootDir": "src",
|
||||
"jsx": "react-jsx",
|
||||
"tsBuildInfoFile": "dist/tsconfig.lib.tsbuildinfo"
|
||||
},
|
||||
"exclude": [
|
||||
"out-tsc",
|
||||
"dist",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx",
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx"
|
||||
],
|
||||
"include": [
|
||||
"src/**/*.js",
|
||||
"src/**/*.jsx",
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../button/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../modal/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-events/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../tauri-api/tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "../../common/tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out-tsc/vitest",
|
||||
"types": [
|
||||
"vitest/globals",
|
||||
"vitest/importMeta",
|
||||
"vite/client",
|
||||
"node",
|
||||
"vitest"
|
||||
],
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts",
|
||||
"vite.config.mts",
|
||||
"vitest.config.ts",
|
||||
"vitest.config.mts",
|
||||
"src/**/*.test.ts",
|
||||
"src/**/*.spec.ts",
|
||||
"src/**/*.test.tsx",
|
||||
"src/**/*.spec.tsx",
|
||||
"src/**/*.test.js",
|
||||
"src/**/*.spec.js",
|
||||
"src/**/*.test.jsx",
|
||||
"src/**/*.spec.jsx",
|
||||
"src/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/// <reference types='vitest' />
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import dts from 'vite-plugin-dts';
|
||||
import * as path from 'path';
|
||||
|
||||
export default defineConfig(() => ({
|
||||
root: __dirname,
|
||||
cacheDir: '../../../node_modules/.vite/libs/components/provider-setup-modal',
|
||||
plugins: [react(), dts({ entryRoot: 'src', tsconfigPath: path.join(__dirname, 'tsconfig.lib.json') })],
|
||||
// Uncomment this if you are using workers.
|
||||
// worker: {
|
||||
// plugins: [ nxViteTsPaths() ],
|
||||
// },
|
||||
// Configuration for building your library.
|
||||
// See: https://vitejs.dev/guide/build.html#library-mode
|
||||
build: {
|
||||
outDir: './dist',
|
||||
emptyOutDir: true,
|
||||
reportCompressedSize: true,
|
||||
commonjsOptions: {
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
lib: {
|
||||
// Could also be a dictionary or array of multiple entry points.
|
||||
entry: 'src/index.ts',
|
||||
name: '@storyteller/provider-setup-modal',
|
||||
fileName: 'index',
|
||||
// Change this to the formats you want to support.
|
||||
// Don't forget to update your package.json as well.
|
||||
formats: ['es' as const]
|
||||
},
|
||||
rollupOptions: {
|
||||
// External packages that should not be bundled into your library.
|
||||
external: ['react','react-dom','react/jsx-runtime']
|
||||
},
|
||||
},
|
||||
test: {
|
||||
watch: false,
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
reporters: ['default'],
|
||||
coverage: {
|
||||
reportsDirectory: './test-output/vitest/coverage',
|
||||
provider: 'v8' as const,
|
||||
}
|
||||
},
|
||||
}));
|
||||
@@ -12,6 +12,5 @@ export interface MidjourneyGetCredentialInfoSuccess extends CommandResult {
|
||||
|
||||
export const MidjourneyGetCredentialInfo = async (): Promise<MidjourneyGetCredentialInfoSuccess> => {
|
||||
const result = await invoke("midjourney_get_credential_info_command");
|
||||
console.log(">>> mj result", result);
|
||||
return result as MidjourneyGetCredentialInfoSuccess;
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './lib/tauri-events';
|
||||
export * from './lib/common/BasicEventWrapper';
|
||||
export * from './lib/events/RefreshAccountStateEvent';
|
||||
export * from './lib/events/FlashUserInputErrorEvent';
|
||||
export * from './lib/events/RefreshAccountStateEvent';
|
||||
export * from './lib/events/ShowProviderLoginModalEvent';
|
||||
export * from './lib/tauri-events';
|
||||
@@ -0,0 +1,35 @@
|
||||
import { listen, UnlistenFn } from '@tauri-apps/api/event';
|
||||
import { BasicEventWrapper } from '../common/BasicEventWrapper';
|
||||
import { useEffect } from 'react';
|
||||
import { GenerationProvider } from '@storyteller/common';
|
||||
|
||||
const EVENT_NAME : string = 'show_provider_login_modal_event';
|
||||
|
||||
export interface ShowProviderLoginModalEvent {
|
||||
provider: GenerationProvider,
|
||||
}
|
||||
|
||||
export const useShowProviderLoginModalEvent = (asyncCallback: (event: ShowProviderLoginModalEvent) => Promise<void>) => {
|
||||
useEffect(() => {
|
||||
let isUnmounted = false;
|
||||
let unlisten: Promise<UnlistenFn>;
|
||||
|
||||
const setup = async () => {
|
||||
unlisten = listen<BasicEventWrapper<ShowProviderLoginModalEvent>>(EVENT_NAME, async (wrappedEvent) => {
|
||||
await asyncCallback(wrappedEvent.payload.data);
|
||||
});
|
||||
|
||||
if (isUnmounted) {
|
||||
unlisten.then(f => f()); // Unsubscribe if unmounted early.
|
||||
}
|
||||
};
|
||||
|
||||
setup();
|
||||
|
||||
return () => {
|
||||
isUnmounted = true;
|
||||
unlisten.then(f => f());
|
||||
};
|
||||
|
||||
}, []);
|
||||
}
|
||||
Generated
+8
@@ -1304,6 +1304,10 @@
|
||||
"name": "@storyteller/ui-promptbox",
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"libs/components/provider-setup-modal": {
|
||||
"name": "@storyteller/provider-setup-modal",
|
||||
"version": "0.0.1"
|
||||
},
|
||||
"libs/components/search": {
|
||||
"name": "@storyteller/ui-search",
|
||||
"version": "0.0.1"
|
||||
@@ -10363,6 +10367,10 @@
|
||||
"resolved": "libs/model-list",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@storyteller/provider-setup-modal": {
|
||||
"resolved": "libs/components/provider-setup-modal",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@storyteller/soundboard": {
|
||||
"resolved": "libs/soundboard",
|
||||
"link": true
|
||||
|
||||
@@ -152,6 +152,9 @@
|
||||
},
|
||||
{
|
||||
"path": "./libs/tauri-events"
|
||||
},
|
||||
{
|
||||
"path": "./libs/components/provider-setup-modal"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user