-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
1,650 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
pnpm-debug.log* | ||
lerna-debug.log* | ||
|
||
node_modules | ||
dist | ||
dist-ssr | ||
*.local | ||
|
||
# Editor directories and files | ||
.vscode/* | ||
!.vscode/extensions.json | ||
.idea | ||
.DS_Store | ||
*.suo | ||
*.ntvs* | ||
*.njsproj | ||
*.sln | ||
*.sw? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link | ||
rel="icon" | ||
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%220.9em%22 font-size=%2290%22>👩🎨</text></svg>" | ||
/> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta name="color-scheme" content="light dark" /> | ||
<title>StableCanvas - PNG info explorer</title> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<script type="module" src="/src/index.tsx"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"preview": "vite preview" | ||
}, | ||
"dependencies": { | ||
"@quik-fe/stand": "^1.0.2", | ||
"@stable-canvas/sd-webui-a1111-pnginfo": "^1.0.1", | ||
"preact": "^10.13.1", | ||
"styled-components": "^6.1.8" | ||
}, | ||
"devDependencies": { | ||
"@preact/preset-vite": "^2.5.0", | ||
"vite": "^4.3.2" | ||
}, | ||
"eslintConfig": { | ||
"extends": "preact" | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import React, { memo } from "preact/compat"; | ||
import styled from "styled-components"; | ||
|
||
const Container = styled.div` | ||
box-sizing: border-box; | ||
width: 100%; | ||
`; | ||
|
||
const Header = styled.div` | ||
display: flex; | ||
justify-content: space-between; | ||
background-color: rgba(0, 0, 0, 0.4); | ||
`; | ||
|
||
const Title = styled.div` | ||
padding: 8px; | ||
cursor: pointer; | ||
font-weight: bold; | ||
user-select: none; | ||
flex: 1; | ||
`; | ||
|
||
const Content = styled.div` | ||
padding: 8px; | ||
word-break: break-all; | ||
width: 100%; | ||
box-sizing: border-box; | ||
`; | ||
|
||
const CopyButton = styled.button` | ||
border: none; | ||
padding: 4px 8px; | ||
width: 64px; | ||
text-align: center; | ||
background-color: rgba(0, 0, 0, 0.4); | ||
color: #fff; | ||
cursor: pointer; | ||
box-sizing: border-box; | ||
`; | ||
|
||
type AccordionProps = { | ||
title: string; | ||
children: React.ReactNode; | ||
defaultOpen?: boolean; | ||
onToggle?: (open: boolean) => void; | ||
showCopyButton?: boolean; | ||
requestCopy?: () => string; | ||
}; | ||
|
||
export const Accordion = memo((props: AccordionProps) => { | ||
const { | ||
title, | ||
children, | ||
defaultOpen = false, | ||
onToggle, | ||
showCopyButton, | ||
requestCopy, | ||
} = props; | ||
|
||
const hasCopyButton = showCopyButton && requestCopy; | ||
|
||
const [open, setOpen] = React.useState(defaultOpen); | ||
const [copied, setCopied] = React.useState(false); | ||
|
||
const handleToggle = () => { | ||
setOpen(!open); | ||
onToggle?.(!open); | ||
}; | ||
|
||
const handleCopy = () => { | ||
if (requestCopy) { | ||
navigator.clipboard.writeText(requestCopy()); | ||
setCopied(true); | ||
setTimeout(() => { | ||
setCopied(false); | ||
}, 1000); | ||
} | ||
}; | ||
|
||
const handleContentClick = (e: React.TargetedEvent) => { | ||
// NOTE: 效果有点奇怪...算了 | ||
// 点击之后就全选 | ||
// const range = document.createRange(); | ||
// const selection = window.getSelection(); | ||
// range.selectNodeContents(e.target as Node); | ||
// selection?.removeAllRanges(); | ||
// selection?.addRange(range); | ||
}; | ||
|
||
return ( | ||
<Container> | ||
<Header> | ||
<Title onClick={handleToggle}> | ||
{open ? "🔽" : "▶️"} {title} | ||
</Title> | ||
{hasCopyButton && ( | ||
<CopyButton onClick={handleCopy}> | ||
{copied ? "Copied!" : "Copy"} | ||
</CopyButton> | ||
)} | ||
</Header> | ||
{open && <Content onClick={handleContentClick}>{children}</Content>} | ||
</Container> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import styled from "styled-components"; | ||
import { useAppStore } from "../useAppStore"; | ||
import { memo } from "preact/compat"; | ||
|
||
const Dropzone = styled.div` | ||
position: relative; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
border: 2px dashed #ccc; | ||
border-radius: 8px; | ||
cursor: pointer; | ||
user-select: none; | ||
transition: border-color 0.3s; | ||
width: 100%; | ||
height: calc(100% - 2rem); | ||
box-sizing: border-box; | ||
margin: 1rem; | ||
padding: 1rem; | ||
&:hover { | ||
border-color: #333; | ||
} | ||
`; | ||
|
||
const ImageContainer = styled.div` | ||
position: relative; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
width: 100%; | ||
height: 100%; | ||
background-color: #333; | ||
img { | ||
max-width: 100%; | ||
max-height: 100%; | ||
} | ||
`; | ||
|
||
const ClearButton = styled.button` | ||
border: none; | ||
background-color: rgba(0, 0, 0, 0.4); | ||
color: #fff; | ||
height: 64px; | ||
width: 64px; | ||
cursor: pointer; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
`; | ||
|
||
export const ImageViewer = memo(() => { | ||
const { image, updateFile } = useAppStore(); | ||
|
||
const uploadImage = () => { | ||
const input = document.createElement("input"); | ||
input.type = "file"; | ||
input.accept = "image/*"; | ||
input.onchange = (e) => { | ||
const file = (e.target as HTMLInputElement).files?.[0]; | ||
if (file) { | ||
updateFile(file); | ||
} | ||
}; | ||
input.click(); | ||
}; | ||
|
||
if (image) { | ||
return ( | ||
<ImageContainer> | ||
<ClearButton | ||
onClick={() => updateFile(null)} | ||
title={"clear image and info"} | ||
> | ||
Clear | ||
</ClearButton> | ||
<img src={image} alt="image" /> | ||
</ImageContainer> | ||
); | ||
} | ||
return ( | ||
<Dropzone onClick={uploadImage}> | ||
<p>📥 Drop your image here</p> | ||
</Dropzone> | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import styled from "styled-components"; | ||
import { useAppStore } from "../useAppStore"; | ||
import { Accordion } from "./Accordion"; | ||
import { memo } from "preact/compat"; | ||
|
||
const Container = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
width: 100%; | ||
height: 100%; | ||
`; | ||
|
||
const NoInfo = styled.div` | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
height: 100%; | ||
`; | ||
|
||
// 以下列根据顺序排序,其余根据文本长度排序 | ||
const columnsTop = [ | ||
"prompt", | ||
"negative_prompt", | ||
"sampler", | ||
"cfg_scale", | ||
"size_1", | ||
"size_2", | ||
"seed", | ||
"model_hash", | ||
"clip_skip", | ||
"version", | ||
]; | ||
|
||
export const InfoPanel = memo(() => { | ||
const { pngInfo } = useAppStore(); | ||
const columns = Object.entries(pngInfo || {}) | ||
.filter(([k, v]) => { | ||
return v !== "" && v !== null && v !== undefined && v !== 0; | ||
}) | ||
.sort((a, b) => { | ||
const aIndex = columnsTop.indexOf(a[0]); | ||
const bIndex = columnsTop.indexOf(b[0]); | ||
if (aIndex !== -1 && bIndex !== -1) { | ||
return aIndex - bIndex; | ||
} | ||
if (aIndex !== -1) { | ||
return -1; | ||
} | ||
if (bIndex !== -1) { | ||
return 1; | ||
} | ||
return a[0].length - b[0].length; | ||
}) | ||
.map(([key, value]) => { | ||
return ( | ||
<Accordion | ||
title={key} | ||
key={key} | ||
defaultOpen | ||
showCopyButton | ||
requestCopy={() => { | ||
return String(value); | ||
}} | ||
> | ||
{value} | ||
</Accordion> | ||
); | ||
}); | ||
if (columns.length === 0) { | ||
return ( | ||
<Container> | ||
<NoInfo>🤔No info available or parser failed.</NoInfo> | ||
</Container> | ||
); | ||
} | ||
return <Container>{columns}</Container>; | ||
}); |
Oops, something went wrong.