Merge pull request #27 from caranicas/beta-react-i18n-lint

Beta react i18n lint
This commit is contained in:
caranicas 2022-09-19 11:37:56 -04:00 committed by GitHub
commit 1210313e7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 5121 additions and 94 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

View File

@ -0,0 +1,84 @@
const path = require("path");
module.exports = {
env: {
browser: true,
es2021: true,
},
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["react"],
extends: [
"plugin:react/recommended",
"standard-with-typescript",
"plugin:i18next/recommended",
"plugin:i18n-json/recommended",
],
rules: {
// general things turned off for now
"prefer-const": "off",
"no-debugger": "warn",
"comma-dangle": ["off", "always-multiline"],
"no-void": ["off"],
"array-callback-return": ["off"],
"react/display-name": "warn",
quotes: ["off", "double"],
semi: ["off", "always"],
"no-multiple-empty-lines": ["off", { max: 2, maxEOF: 1 }],
yoda: ["off"],
eqeqeq: ["off"],
"spaced-comment": ["off"],
// TS things turned off for now
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-array-constructor": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/naming-convention": "off",
"@typescript-eslint/restrict-template-expressions": "off",
"@typescript-eslint/prefer-optional-chain": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/strict-boolean-expressions": "off",
"@typescript-eslint/no-floating-promises": "off",
"@typescript-eslint/consistent-type-assertions": "off",
"@typescript-eslint/comma-dangle": "off",
"@typescript-eslint/quotes": "off",
"@typescript-eslint/semi": "off",
"@typescript-eslint/restrict-plus-operands": "off",
"@typescript-eslint/brace-style": "off",
"@typescript-eslint/prefer-ts-expect-error": "off",
"@typescript-eslint/indent": "off",
"@typescript-eslint/member-delimiter-style": "off",
"@typescript-eslint/prefer-includes": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"@typescript-eslint/no-unnecessary-condition": "off",
"@typescript-eslint/no-unnecessary-type-assertion": "off",
"@typescript-eslint/space-before-function-paren": "off",
// i18n stuff no string literal works
"i18next/no-literal-string": "warn",
// still need to figure out how to get this to work
"i18n-json/identical-keys": [
"error",
{
filePath: {
"home.json/": path.resolve("./Translation/locales/en/home.json"),
},
},
],
},
overrides: [
{
files: ["*.ts", "*.tsx"],
parserOptions: {
project: ["./tsconfig.json"], // Specify it only for TypeScript files
},
},
],
// eslint-disable-next-line semi
};

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"lint": "eslint --ext .tsx --fix src",
"pretty": "prettier --write .",
"dev": "vite",
"build": "tsc && vite build --emptyOutDir",
@ -29,10 +30,21 @@
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@types/uuid": "^8.3.4",
"@typescript-eslint/eslint-plugin": "^5.37.0",
"@typescript-eslint/parser": "^5.37.0",
"@vitejs/plugin-react": "^2.0.1",
"eslint": "^8.23.1",
"eslint-config-standard-with-typescript": "^23.0.0",
"eslint-plugin-i18n-json": "^4.0.0",
"eslint-plugin-i18next": "^6.0.0-4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.2.5",
"eslint-plugin-promise": "^6.0.1",
"eslint-plugin-react": "^7.31.8",
"prettier": "^2.7.1",
"typescript": "^4.6.4",
"vite": "^3.0.7"
"typescript": "^4.8.3",
"vite": "^3.0.7",
"vite-plugin-eslint": "^1.8.1"
},
"overrides": {
"@vanilla-extract/vite-plugin": {

View File

@ -0,0 +1,7 @@
module.exports = {
singleQuote: true,
tabWidth: 2,
semi: true,
trailingComma: "es5",
endOfLine: "lf",
};

View File

@ -1,17 +1,15 @@
import React, { useState } from "react";
import { ReactLocation, Router } from "@tanstack/react-location";
import Home from "./pages/Home";
import Settings from "./pages/Settings";
// @ts-ignore
// @ts-expect-error
import { darkTheme, lightTheme } from "./styles/theme/index.css.ts";
import './Translation/config';
import "./Translation/config";
const location = new ReactLocation();
function App() {
// just check for the theme one 1 time
// var { matches } = window.matchMedia('(prefers-color-scheme: dark)')
const matches = true;
const themeClass = matches ? darkTheme : lightTheme;
@ -23,8 +21,7 @@ function App() {
{ path: "/", element: <Home className={themeClass} /> },
{ path: "/settings", element: <Settings className={themeClass} /> },
]}
>
</Router>
></Router>
);
}

View File

@ -1,5 +1,6 @@
import i18n from "i18next";
import translation from "./en.json";
// this should be updated to an interface
import translation from "./locales/en/home.json";
import { initReactI18next } from "react-i18next";
export const resources = {

View File

@ -0,0 +1,20 @@
{
"title": "Stable Diffusion UI",
"description": "",
"navbar": {},
"land-cre": {},
"land-pre": {},
"home": {},
"in-paint": {},
"settings": {},
"tags": {},
"preview-prompt": {},
"current-task": "",
"recent-create": "",
"popup": {},
"history": {},
"advanced-settings": {},
"storage": {},
"import": {},
"about": ""
}

View File

@ -1,9 +1,9 @@
import React from "react";
import { useImageCreate } from "../../../stores/imageCreateStore";
type ModifierTagProps = {
interface ModifierTagProps {
name: string;
};
}
export default function ModifierTag({ name }: ModifierTagProps) {
const hasTag = useImageCreate((state) => state.hasTag(name))

View File

@ -24,7 +24,7 @@ export default function BetaMode() {
// the toggle config
const { status: toggleStatus, data: toggleData } = useQuery(
[KEY_TOGGLE_CONFIG],
() => toggleBetaConfig(branchToGetNext),
async () => await toggleBetaConfig(branchToGetNext),
{
enabled: shouldSetCofig,
}
@ -47,7 +47,7 @@ export default function BetaMode() {
useEffect(() => {
if (toggleStatus === "success") {
if (toggleData[0] == "OK") {
if (toggleData[0] === "OK") {
// force a refetch of the config
queryClient.invalidateQueries([KEY_CONFIG]);
}

View File

@ -1,20 +1,20 @@
// @ts-nocheck
import React, { useRef, useState, useEffect } from "react";
import {
DrawImageMain, // @ts-expect-error
} from "./drawImage.css.ts";
// https://github.com/embiem/react-canvas-draw
type DrawImageProps = {
interface DrawImageProps {
imageData: string;
brushSize: string;
brushShape: string;
brushColor: string;
isErasing: boolean;
};
import {
DrawImageMain, //@ts-ignore
} from "./drawImage.css.ts";
}
export default function DrawImage({
imageData,
@ -42,7 +42,7 @@ export default function DrawImage({
useEffect(() => {
// when the brush color changes, change the color of all the
// drawn pixels to the new color
if (drawingRef.current) {
if (drawingRef.current != null) {
const ctx = drawingRef.current.getContext("2d");
const imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
const data = imageData.data;
@ -72,7 +72,7 @@ export default function DrawImage({
) => {
setIsUpdating(false);
const canvas = drawingRef.current;
if (canvas) {
if (canvas != null) {
const data = canvas.toDataURL();
// TODO: SEND THIS TO THE STATE
}
@ -80,7 +80,7 @@ export default function DrawImage({
const _drawCanvas = (x, y, brushSize, brushShape, brushColor) => {
const canvas = drawingRef.current;
if (canvas) {
if (canvas != null) {
const ctx = canvas.getContext("2d");
if (isErasing) {
// stack overflow https://stackoverflow.com/questions/10396991/clearing-circular-regions-from-html5-canvas
@ -101,7 +101,7 @@ export default function DrawImage({
const _drawCursor = (x, y, brushSize, brushShape, brushColor) => {
const canvas = cursorRef.current;
if (canvas) {
if (canvas != null) {
const ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.clearRect(0, 0, canvas.width, canvas.height);
@ -146,7 +146,7 @@ export default function DrawImage({
// function for external use
const fillCanvas = () => {
const canvas = drawingRef.current;
if (canvas) {
if (canvas != null) {
const ctx = canvas.getContext("2d");
ctx.fillStyle = brushColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);

View File

@ -4,15 +4,15 @@ import { ImageRequest, useImageCreate } from "../../../stores/imageCreateStore";
import {
generatedImageMain,
image, //@ts-ignore
image, // @ts-expect-error
} from "./generatedImage.css.ts";
type GeneretaedImageProps = {
interface GeneretaedImageProps {
imageData: string;
metadata: ImageRequest;
className?: string;
// children: never[];
};
}
export default function GeneratedImage({
imageData,

View File

@ -4,7 +4,7 @@ import { useImageCreate } from "../../../../../stores/imageCreateStore";
import { useCreateUI } from "../../creationPanelUIStore";
import {
MenuButton, //@ts-ignore
MenuButton, // @ts-expect-error
} from "../advancedsettings.css.ts";
export default function GpuSettings() {

View File

@ -4,7 +4,7 @@ import { useImageCreate } from "../../../../../stores/imageCreateStore";
import { useCreateUI } from "../../creationPanelUIStore";
import {
MenuButton, //@ts-ignore
MenuButton, // @ts-expect-error
} from "../advancedsettings.css.ts";
export default function ImprovementSettings() {

View File

@ -3,7 +3,7 @@ import { useCreateUI } from "../creationPanelUIStore";
import {
AdvancedSettingsList,
AdvancedSettingItem, // @ts-ignore
AdvancedSettingItem, // @ts-expect-error
} from "./advancedsettings.css.ts";
import ImprovementSettings from "./improvementSettings";

View File

@ -3,7 +3,7 @@ import { useImageCreate } from "../../../../../stores/imageCreateStore";
import { useCreateUI } from "../../creationPanelUIStore";
import {
MenuButton, //@ts-ignore
MenuButton, // @ts-expect-error
} from "../advancedsettings.css.ts";
// todo: move this someplace more global
const IMAGE_DIMENSIONS = [

View File

@ -4,7 +4,7 @@ import { useImageCreate } from "../../../../../stores/imageCreateStore";
import { useCreateUI } from "../../creationPanelUIStore";
import {
MenuButton, //@ts-ignore
MenuButton, // @ts-expect-error
} from "../advancedsettings.css.ts";
export default function WorkflowSettings() {

View File

@ -3,7 +3,7 @@ import { useImageCreate } from "../../../../stores/imageCreateStore";
import {
CreationBasicMain,
PromptDisplay, // @ts-ignore
PromptDisplay, // @ts-expect-error
} from "./basicCreation.css.ts";
import SeedImage from "./seedImage";

View File

@ -7,7 +7,7 @@ import { v4 as uuidv4 } from "uuid";
import { useRandomSeed } from "../../../../../utils";
import {
MakeButtonStyle, // @ts-ignore
MakeButtonStyle, // @ts-expect-error
} from "./makeButton.css.ts";
import { useTranslation } from "react-i18next";
@ -65,7 +65,7 @@ export default function MakeButton() {
// updated the number of images to make
num_outputs: num,
// update the seed
seed: seed,
seed,
});
});

View File

@ -6,7 +6,7 @@ import {
ImageInput,
ImageInputButton,
ImageFixer,
XButton, // @ts-ignore
XButton, // @ts-expect-error
} from "./seedImage.css.ts";
import { useImageCreate } from "../../../../../stores/imageCreateStore";
@ -27,13 +27,13 @@ export default function SeedImage(_props: any) {
imageInputRef.current?.click();
};
const _handleFileSelect = (event: ChangeEvent<HTMLInputElement>) => {
//@ts-ignore
// @ts-expect-error
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
if (e.target) {
if (e.target != null) {
setRequestOption("init_image", e.target.result);
}
};

View File

@ -1,7 +1,6 @@
import create from "zustand";
import produce from "immer";
import { persist } from "zustand/middleware";
import { devtools } from "zustand/middleware";
import { persist, devtools } from "zustand/middleware";
export type ImageCreationUIOptions = {
isOpenAdvancedSettings: boolean;

View File

@ -8,9 +8,9 @@ import { useCreateUI } from "../creationPanelUIStore";
import ModifierTag from "../../../atoms/modifierTag";
type ModifierListProps = {
interface ModifierListProps {
tags: string[];
};
}
function ModifierList({ tags }: ModifierListProps) {
return (
@ -24,10 +24,10 @@ function ModifierList({ tags }: ModifierListProps) {
);
}
type ModifierGroupingProps = {
interface ModifierGroupingProps {
title: string;
tags: string[];
};
}
function ModifierGrouping({ title, tags }: ModifierGroupingProps) {
// doing this localy for now, but could move to a store

View File

@ -13,7 +13,7 @@ import "./creationPanel.css";
import {
CreationPaneMain,
InpaintingSlider, // @ts-ignore
InpaintingSlider, // @ts-expect-error
} from "./creationpane.css.ts";
import BasicCreation from "./basicCreation";

View File

@ -6,7 +6,7 @@ import { useImageCreate } from "../../../../stores/imageCreateStore";
import {
InpaintingPanelMain,
InpaintingControls,
InpaintingControlRow, // @ts-ignore
InpaintingControlRow, // @ts-expect-error
} from "./inpaintingPanel.css.ts";
export default function InpaintingPanel() {

View File

@ -4,7 +4,7 @@ import { API_URL } from "../../../../api";
const url = `${API_URL}/ding.mp3`;
const AudioDing = React.forwardRef((props, ref) => (
// @ts-ignore
// @ts-expect-error
<audio ref={ref} style={{ display: "none" }}>
<source src={url} type="audio/mp3" />
</audio>

View File

@ -2,16 +2,16 @@ import React from "react";
import { CompletedImagesType } from "../index";
type CurrentDisplayProps = {
images: CompletedImagesType[] | null;
setCurrentDisplay: (image: CompletedImagesType) => void;
};
import {
completedImagesMain,
imageContain, //@ts-ignore
imageContain, // @ts-expect-error
} from "./completedImages.css.ts";
interface CurrentDisplayProps {
images: CompletedImagesType[] | null;
setCurrentDisplay: (image: CompletedImagesType) => void;
}
export default function CompletedImages({
images,
setCurrentDisplay,
@ -23,7 +23,7 @@ export default function CompletedImages({
return (
<div className={completedImagesMain}>
{images &&
{images != null &&
images.map((image, index) => {
if (void 0 === image) {
console.warn(`image ${index} is undefined`);

View File

@ -7,12 +7,13 @@ import {
import { CompletedImagesType } from "../index";
type CurrentDisplayProps = {
interface CurrentDisplayProps {
image: CompletedImagesType | null;
};
}
export default function CurrentDisplay({ image }: CurrentDisplayProps) {
const { info, data } = image || { info: null, data: null };
// @ts-ignore
const { info, data } = image != null || { info: null, data: null };
const setRequestOption = useImageCreate((state) => state.setRequestOptions);
@ -26,9 +27,9 @@ export default function CurrentDisplay({ image }: CurrentDisplayProps) {
use_upscale,
width,
height,
} = info!;
} = info;
//Most important information is the prompt
// Most important information is the prompt
let underscoreName = prompt.replace(/[^a-zA-Z0-9]/g, "_");
underscoreName = underscoreName.substring(0, 100);
// name and the top level metadata
@ -43,7 +44,7 @@ export default function CurrentDisplay({ image }: CurrentDisplayProps) {
// Add the width and height
fileName += `_${width}x${height}`;
// add the file extension
fileName += `.png`;
fileName += ".png";
// return fileName
return fileName;
};
@ -61,10 +62,10 @@ export default function CurrentDisplay({ image }: CurrentDisplayProps) {
return (
<div className="current-display">
{image && (
{image != null && (
<div>
<p> {info!.prompt}</p>
<GeneratedImage imageData={data!} metadata={info!}></GeneratedImage>
<p> {info.prompt}</p>
<GeneratedImage imageData={data} metadata={info}></GeneratedImage>
<div>
<button onClick={_handleSave}>Save</button>

View File

@ -20,19 +20,19 @@ import {
displayContainer,
// CurrentDisplay,
previousImages,
previousImage, //@ts-ignore
previousImage, // @ts-expect-error
} from "./displayPanel.css.ts";
export type CompletedImagesType = {
export interface CompletedImagesType {
id: string;
data: string;
info: ImageRequest;
};
}
export default function DisplayPanel() {
const dingRef = useRef<HTMLAudioElement>(null);
const isSoundEnabled = useImageCreate((state) => state.isSoundEnabled());
// @ts-ignore
// @ts-expect-error
const { id, options } = useImageQueue((state) => state.firstInQueue());
const removeFirstInQueue = useImageQueue((state) => state.removeFirstInQueue);
const [currentImage, setCurrentImage] = useState<CompletedImagesType | null>(
@ -41,7 +41,7 @@ export default function DisplayPanel() {
const { status, data } = useQuery(
[MakeImageKey, id],
() => doMakeImage(options),
async () => await doMakeImage(options),
{
enabled: void 0 !== id,
}
@ -84,13 +84,13 @@ export default function DisplayPanel() {
const temp = completedQueries
.map((query, index) => {
if (void 0 !== query) {
//@ts-ignore
// @ts-ignore
return query.output.map((data) => {
// @ts-ignore
return {
id: `${completedIds[index]}-${data.seed}`,
data: data.data,
//@ts-ignore
// @ts-ignore
info: { ...query.request, seed: data.seed },
};
});

View File

@ -9,7 +9,11 @@ export default function FooterDisplay() {
<div id="footer" className="panel-box">
<p>
If you found this project useful and want to help keep it alive, please{" "}
<a href="https://ko-fi.com/cmdr2_stablediffusion_ui" target="_blank">
<a
href="https://ko-fi.com/cmdr2_stablediffusion_ui"
target="_blank"
rel="noreferrer"
>
<img src={`${API_URL}/kofi.png`} id="coffeeButton" />
</a>{" "}
to help cover the cost of development and maintenance! Thank you for
@ -17,13 +21,18 @@ export default function FooterDisplay() {
</p>
<p>
Please feel free to join the{" "}
<a href="https://discord.com/invite/u9yhsFmEkB" target="_blank">
<a
href="https://discord.com/invite/u9yhsFmEkB"
target="_blank"
rel="noreferrer"
>
discord community
</a>{" "}
or{" "}
<a
href="https://github.com/cmdr2/stable-diffusion-ui/issues"
target="_blank"
rel="noreferrer"
>
file an issue
</a>{" "}
@ -43,6 +52,7 @@ export default function FooterDisplay() {
<a
href="https://github.com/cmdr2/stable-diffusion-ui/blob/main/LICENSE"
target="_blank"
rel="noreferrer"
>
the license
</a>

View File

@ -5,10 +5,10 @@ import { KEY_CONFIG, getConfig } from "../../../api";
import StatusDisplay from "./statusDisplay";
import { useTranslation } from "react-i18next"
import { useTranslation } from "react-i18next";
import {
HeaderDisplayMain, //@ts-ignore
HeaderDisplayMain, // @ts-expect-error
} from "./headerDisplay.css.ts";
export default function HeaderDisplay() {

View File

@ -3,16 +3,16 @@ import { useQuery } from "@tanstack/react-query";
import { healthPing, HEALTH_PING_INTERVAL } from "../../../../api";
const startingMessage = "Stable Diffusion is starting...";
const successMessage = "Stable Diffusion is ready to use!";
const errorMessage = "Stable Diffusion is not running!";
import {
StartingStatus,
ErrorStatus,
SuccessStatus,
} from "./statusDisplay.css";
const startingMessage = "Stable Diffusion is starting...";
const successMessage = "Stable Diffusion is ready to use!";
const errorMessage = "Stable Diffusion is not running!";
export default function StatusDisplay({ className }: { className?: string }) {
const [statusMessage, setStatusMessage] = useState(startingMessage);
const [statusClass, setStatusClass] = useState(StartingStatus);
@ -42,7 +42,7 @@ export default function StatusDisplay({ className }: { className?: string }) {
return (
<>
{/* alittle hacky but joins the class names, will probably need a better css in js solution or tailwinds*/}
{/* alittle hacky but joins the class names, will probably need a better css in js solution or tailwinds */}
<p className={[statusClass, className].join(" ")}>{statusMessage}</p>
</>
);

View File

@ -5,7 +5,7 @@ import {
HeaderLayout,
CreateLayout,
DisplayLayout,
FooterLayout, // @ts-ignore
FooterLayout, // @ts-expect-error
} from "./home.css.ts";
import { useQuery } from "@tanstack/react-query";
@ -45,7 +45,7 @@ function Home({ className }: { className: any }) {
if (statusMods === "success") {
setAllModifiers(dataMoads);
} else if (statusMods === "error") {
// @ts-ignore
// @ts-expect-error
setAllModifiers(Mockifiers);
}
}, [setRequestOption, statusMods, dataMoads]);

View File

@ -250,7 +250,7 @@ export const useImageCreate = create<ImageCreateState>(
},
isUsingUpscaling: () => {
const isUsing = get().getValueForRequestKey("use_upscale") != "";
const isUsing = get().getValueForRequestKey("use_upscale") !== "";
return isUsing;
},

View File

@ -1,4 +1,5 @@
import { defineConfig } from "vite";
import eslint from "vite-plugin-eslint";
import react from "@vitejs/plugin-react";
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
@ -14,6 +15,7 @@ export default defineConfig({
},
plugins: [
eslint(),
react(),
vanillaExtractPlugin({
// configuration

File diff suppressed because one or more lines are too long