diff --git a/.env b/.env deleted file mode 100644 index 534ef54..0000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -NOVELAI_BACKEND_URL=https://imgen.hyperz.top \ No newline at end of file diff --git a/package.json b/package.json index b331368..e4e8a0e 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "@types/libsodium-wrappers": "^0.7.9", "@types/node": "^18.8.0", "@types/nprogress": "^0.2.0", + "@types/prosemirror-dev-tools": "^3.0.2", "@types/react": "^18.0.21", "@types/react-dom": "^18.0.6", "@types/react-lazy-load-image-component": "^1.5.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 191a146..9f45a6f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,6 +18,7 @@ specifiers: '@types/libsodium-wrappers': ^0.7.9 '@types/node': ^18.8.0 '@types/nprogress': ^0.2.0 + '@types/prosemirror-dev-tools': ^3.0.2 '@types/react': ^18.0.21 '@types/react-dom': ^18.0.6 '@types/react-lazy-load-image-component': ^1.5.2 @@ -193,6 +194,7 @@ devDependencies: '@types/libsodium-wrappers': 0.7.9 '@types/node': 18.8.0 '@types/nprogress': 0.2.0 + '@types/prosemirror-dev-tools': registry.npmjs.org/@types/prosemirror-dev-tools/3.0.2 '@types/react': 18.0.21 '@types/react-dom': 18.0.6 '@types/react-lazy-load-image-component': 1.5.2 @@ -8550,11 +8552,61 @@ packages: requiresBuild: true optional: true + registry.npmjs.org/@types/orderedmap/1.0.0: + resolution: {integrity: sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz} + name: '@types/orderedmap' + version: 1.0.0 + dev: true + registry.npmjs.org/@types/parse-json/4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz} name: '@types/parse-json' version: 4.0.0 + registry.npmjs.org/@types/prosemirror-dev-tools/3.0.2: + resolution: {integrity: sha512-lZiu4pZ3JfZKdWJDj6e1Gy28Ee3wIH3bOoAG432B7PuEPaV+S5oRMsZMdiuolNyD3T4XylJxAE3ARFxAAT+Jkg==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-3.0.2.tgz} + name: '@types/prosemirror-dev-tools' + version: 3.0.2 + dependencies: + '@types/prosemirror-view': registry.npmjs.org/@types/prosemirror-view/1.23.3 + dev: true + + registry.npmjs.org/@types/prosemirror-model/1.16.2: + resolution: {integrity: sha512-1XPJopkKP3oHSBP61uuSuW13DIDZPWvAzP6Pv2/6mixk8EBPUeRGIW548DjJTicMo23gEg1zvCZy9asblQdWag==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/prosemirror-model/-/prosemirror-model-1.16.2.tgz} + name: '@types/prosemirror-model' + version: 1.16.2 + dependencies: + '@types/orderedmap': registry.npmjs.org/@types/orderedmap/1.0.0 + dev: true + + registry.npmjs.org/@types/prosemirror-state/1.3.0: + resolution: {integrity: sha512-nMdUF6w8B++NH4V54X+4GvDty7M02UfuHQW0s1AS25Z4ZrOW4RSY2+s57doXBbeMSjzYV/QoMxCY2sT3KQ2VdQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.3.0.tgz} + name: '@types/prosemirror-state' + version: 1.3.0 + dependencies: + '@types/prosemirror-model': registry.npmjs.org/@types/prosemirror-model/1.16.2 + '@types/prosemirror-transform': registry.npmjs.org/@types/prosemirror-transform/1.4.2 + '@types/prosemirror-view': registry.npmjs.org/@types/prosemirror-view/1.23.3 + dev: true + + registry.npmjs.org/@types/prosemirror-transform/1.4.2: + resolution: {integrity: sha512-FZNzjYm6YUkb1XXOrw2193TiFzwM92ui1nycNaRSd5JDbugf9yBLkXm4Rq3HGJJxBBkRcUE8niqUW5aWlXQQiQ==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/prosemirror-transform/-/prosemirror-transform-1.4.2.tgz} + name: '@types/prosemirror-transform' + version: 1.4.2 + dependencies: + '@types/prosemirror-model': registry.npmjs.org/@types/prosemirror-model/1.16.2 + dev: true + + registry.npmjs.org/@types/prosemirror-view/1.23.3: + resolution: {integrity: sha512-T5dPDmZiXAazJVSvnx55D6h4mcpiH2q2wTyO9zIeOdox5zx964+zcDl9dFNaXG3qCGlERwMPckhBZL1HCxyygw==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/@types/prosemirror-view/-/prosemirror-view-1.23.3.tgz} + name: '@types/prosemirror-view' + version: 1.23.3 + dependencies: + '@types/prosemirror-model': registry.npmjs.org/@types/prosemirror-model/1.16.2 + '@types/prosemirror-state': registry.npmjs.org/@types/prosemirror-state/1.3.0 + '@types/prosemirror-transform': registry.npmjs.org/@types/prosemirror-transform/1.4.2 + dev: true + registry.npmjs.org/acorn-jsx-walk/2.0.0: resolution: {integrity: sha512-uuo6iJj4D4ygkdzd6jPtcxs8vZgDX9YFIkqczGImoypX2fQ4dVImmu3UzA4ynixCIMTrEOWW+95M2HuBaCEOVA==, registry: https://registry.npmjs.com/, tarball: https://registry.npmjs.org/acorn-jsx-walk/-/acorn-jsx-walk-2.0.0.tgz} name: acorn-jsx-walk diff --git a/src/components/conversation/conversationeditor.tsx b/src/components/conversation/conversationeditor.tsx index ddc4632..c2dd766 100644 --- a/src/components/conversation/conversationeditor.tsx +++ b/src/components/conversation/conversationeditor.tsx @@ -332,7 +332,7 @@ export default function ConversationEditor(props: { }), devTool(), placeholder(), - new Plugin({ props: { plainTextPaste: true } as EditorProps }), + new Plugin({ props: { plainTextPaste: true } as any }), ], }) diff --git a/src/components/editor/commands.ts b/src/components/editor/commands.ts index 7cacafc..e770155 100644 --- a/src/components/editor/commands.ts +++ b/src/components/editor/commands.ts @@ -15,13 +15,11 @@ import { AllSelection, EditorState, Transaction, + Command, } from 'prosemirror-state' import { EditorView } from 'prosemirror-view' import { logError } from '../../util/browser' -export interface Command { - (state: EditorState, dispatch?: (tr: Transaction) => void, view?: EditorView): boolean -} export interface Keymap { [key: string]: Command } @@ -538,7 +536,7 @@ export const selectTextblockEnd = selectTextblockSide(1) // Combine a number of command functions into a single function. // Calls them one by one until one returns true. -export function chainCommands(...commands: Array): Command { +export function chainCommands(...commands: Array): Command { return (state, dispatch, view) => { for (const command of commands) { if (command(state, dispatch, view)) return true diff --git a/src/components/editor/keymap.ts b/src/components/editor/keymap.ts index 564fe23..7025b50 100644 --- a/src/components/editor/keymap.ts +++ b/src/components/editor/keymap.ts @@ -92,7 +92,7 @@ export function keydownHandler( const isChar = name.length == 1 && name != ' ' let baseName const direct = map[keyNameWithModifiers(name, event, !isChar)] - if (direct && direct(view.state, view.dispatch, view)) return true + if (direct && direct(view.state, view.dispatch, view as any)) return true if ( isChar && (event.shiftKey || event.altKey || event.metaKey || (name.codePointAt(0) ?? 0) > 127) && @@ -100,12 +100,12 @@ export function keydownHandler( baseName != name ) { const fromCode = map[keyNameWithModifiers(baseName, event, true)] - if (fromCode && fromCode(view.state, view.dispatch, view)) return true + if (fromCode && fromCode(view.state, view.dispatch, view as any)) return true } else if (isChar && event.shiftKey) { // Otherwise, if shift is active, also try the binding with the // Shift- prefix enabled. See #997 const withShift = map[keyNameWithModifiers(name, event, true)] - if (withShift && withShift(view.state, view.dispatch, view)) return true + if (withShift && withShift(view.state, view.dispatch, view as any)) return true } return false } diff --git a/src/components/editor/plugins.ts b/src/components/editor/plugins.ts index 13bdae3..09e2439 100644 --- a/src/components/editor/plugins.ts +++ b/src/components/editor/plugins.ts @@ -17,7 +17,7 @@ export function keymap(bindings: KeymapBindings): Plugin { props: { handleKeyDown: keydownHandler(bindings), }, - }) + } as any) } export const placeholder = (): Plugin => { @@ -37,7 +37,7 @@ export const placeholder = (): Plugin => { return DecorationSet.create(state.doc, decorations) }, }, - }) + } as any) } export const clipboardTransform = (): Plugin => { @@ -50,7 +50,7 @@ export const clipboardTransform = (): Plugin => { clipboardTextParser: handlePasteText, transformPastedHTML: transformHTML, } as EditorProps, - }) + } as any) } export const propsOverride = (props: Partial): Plugin => { @@ -60,7 +60,7 @@ export const propsOverride = (props: Partial): Plugin => { props: { ...props, }, - }) + } as any) } export const inspectNodeChanges = ( @@ -208,7 +208,7 @@ export const devTool = (): Plugin => { init(config, state) { if (Environment === 'debug') { import('prosemirror-dev-tools') - .then(({ createDevTools }) => { + .then(({ createDevTools }: any) => { instance.update = createDevTools({ state }, {}) }) .catch(() => { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 1b41f98..98d34ac 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -418,7 +418,7 @@ async function fillImageBackground( canvas.height = height || image.height const ctx = canvas.getContext('2d') if (!ctx) { - toast('Could not create canvas context') + toast.error('Could not create canvas context') return } ctx.fillStyle = color @@ -455,14 +455,14 @@ function ImageGenContent(): JSX.Element { }, [images.length]) const [generating, setGenerating] = useState(false) const [progress, setProgress] = useState(0) - const [queuePos, setQueuePos] = useState(0) + const [queuePos, setQueuePos] = useState(0) const [selectedImage, setSelectedImage] = useState(0) const [session, setSession] = useRecoilState(Session) const [params, actualSetParams] = useState( getModelDefaultParams(ImageGenerationModels.stableDiffusion) ) - const [prompt, setPrompt] = useState([''] as string[]) + const [prompt, setPrompt] = useRememberedValue('imagegen-prompt', [''] as string[]) const [promptLines, setPromptLines] = useState([1] as number[]) const [negPrompt, setNegPrompt] = useRememberedValue('imagegen-negativeprompt', '') @@ -493,7 +493,7 @@ function ImageGenContent(): JSX.Element { const didMessageNoAccount = useRef(false) useEffect(() => { if (session.noAccount && !didMessageNoAccount.current) { - toast('An account is required to generate images.') + toast.warn('An account is required to generate images.') didMessageNoAccount.current = true } }, [session]) @@ -582,7 +582,7 @@ function ImageGenContent(): JSX.Element { useEffect(() => { if (promptTokens.some((t) => t > SD_TOKEN_LIMIT) && lastPromptTokensGood.current) { lastPromptTokensGood.current = false - toast( + toast.warn( 'Prompt is too long and will be cut off. Using ' + promptTokens + ' out of ' + @@ -624,7 +624,7 @@ function ImageGenContent(): JSX.Element { useEffect(() => { if (negPromptTokens > SD_TOKEN_LIMIT && lastNegPromptTokensGood.current) { lastNegPromptTokensGood.current = false - toast( + toast.warn( 'Negative prompt is too long and will be cut off. Using ' + negPromptTokens + ' out of ' + @@ -675,6 +675,9 @@ function ImageGenContent(): JSX.Element { }) .catch((error) => { logError(error) + toast.error(`Error: ${error.message} - Unable to reach NovelAI servers. Please wait for a moment and try again`, { + toastId: 'promptSuggesionError' + }) }) .finally(() => { setSearchingTags(false) @@ -761,9 +764,7 @@ function ImageGenContent(): JSX.Element { if (!prompt[lastFocusedPrompt].slice(cursorPosition)?.trim()) { newPrompt += ', ' } - setPrompt((v) => { - return [...v.slice(0, lastFocusedPrompt), newPrompt, ...v.slice(lastFocusedPrompt + 1)] - }) + setPrompt([...prompt.slice(0, lastFocusedPrompt), newPrompt, ...prompt.slice(lastFocusedPrompt + 1)]) if (promptid !== undefined) { setTimeout(() => { const input = document.querySelector(`#prompt-input-${promptid}`) as HTMLInputElement @@ -893,7 +894,7 @@ function ImageGenContent(): JSX.Element { return } if (session.noAccount) { - toast('An account is required to generate images.') + toast.warn('An account is required to generate images.') return } try { @@ -946,7 +947,7 @@ function ImageGenContent(): JSX.Element { } if (!validateParameters(tempParams, selectedModel)) { - toast('Invalid parameters') + toast.error('Invalid parameters') return } @@ -1033,7 +1034,7 @@ function ImageGenContent(): JSX.Element { }, (error: any) => { setGenerating(false) - toast(error.message); + toast.error(error.message); }, () => { setGenerating(false) @@ -1052,7 +1053,7 @@ function ImageGenContent(): JSX.Element { } ) } catch (error: any) { - toast('Error generating image: ' + error.message ?? error) + toast.error('Error generating image: ' + error.message ?? error) setGenerating(false) return } @@ -1127,7 +1128,7 @@ function ImageGenContent(): JSX.Element { }, (error: any) => { setGenerating(false) - toast(error.message ?? error) + toast.error(error.message ?? error) }, () => { setGenerating(false) @@ -1140,7 +1141,7 @@ function ImageGenContent(): JSX.Element { } ) } catch { - toast('Error generating image') + toast.error('Error generating image') setGenerating(false) reject() return @@ -1612,10 +1613,10 @@ function ImageGenContent(): JSX.Element { if (!img.data) return copyPngToClipboard(img.data) .then(() => { - toast('Image copied to clipboard') + toast.success('Image copied to clipboard') }) .catch((error) => { - toast('Error copying image to clipboard: ' + error) + toast.error('Error copying image to clipboard: ' + error) }) }} > @@ -1843,7 +1844,9 @@ function ImageGenContent(): JSX.Element { return acc + image.length }, 0) const dupeNames: any = {} - toast(`Downloading ${imageCount} images...`) + const loadingToastId = toast.loading(`Downloading ${imageCount} images...`, { + autoClose: false + }) images.forEach((image, i) => { image.forEach((img, j) => { if (img.isVariationOriginal) return @@ -1862,7 +1865,8 @@ function ImageGenContent(): JSX.Element { }).then(function (content) { saveAs(content, 'images.zip') setDownloadingImages(false) - toast('Images downloaded') + toast.dismiss(loadingToastId) + toast.success('Images downloaded') }) } @@ -3865,7 +3869,7 @@ const GenerateButton = styled.button` display: flex; flex-direction: row; - justify-content: space-between; + justify-content: space-around; align-items: center; padding-left: 20px; padding-right: 20px; @@ -4776,7 +4780,7 @@ function Canvas(props: { const newWidth = width + right + left const newHeight = height + bottom + top if (newWidth < 128 || newHeight < 128) { - toast('Canvas dimensions must be at least 128x128') + toast.warn('Canvas dimensions must be at least 128x128') return } // transfer old canvas content to new canvas @@ -4877,8 +4881,8 @@ function Canvas(props: { }, [canvasInternalSize, resizeModalOpen]) const [generating, setGenerating] = useState(false) - const [progress, setProgress] = useState(0) - const [queuePos, setQueuePos] = useState(0) + const [progress, setProgress] = useState(0) + const [queuePos, setQueuePos] = useState(0) // Queue remaining toast const queueToastId = React.useRef(null); @@ -5166,7 +5170,7 @@ function Canvas(props: { }) .catch((error) => { setGenerating(false) - toast( + toast.error( (error?.message ?? error).replace(/training steps/g, 'Anlas') ) }) @@ -5908,11 +5912,11 @@ function ImageGenImportOverlay(props: { onFileImport: (file: Buffer) => void }) const buffer = Buffer.from(result.value) props.onFileImport(buffer) } else { - toast('Something went wrong while importing a file.') + toast.error('Something went wrong while importing a file.') } }) .catch((error) => { - toast('Something went wrong while importing a file: ' + error.message ?? error) + toast.error('Something went wrong while importing a file: ' + error.message ?? error) }) } diff --git a/tsconfig.json b/tsconfig.json index 97c4545..065f8b4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ ], "allowJs": true, "skipLibCheck": true, - "strict": true, + "strict": false, "alwaysStrict": false, "strictPropertyInitialization": false, "forceConsistentCasingInFileNames": true,