aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/ImageBox.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-01-13 22:26:35 -0500
committerbobzel <zzzman@gmail.com>2025-01-13 22:26:35 -0500
commit12f5a435ee6476e2e07ded0c9cdd597c70ca8af0 (patch)
tree258d3f999329bf94b5725fb5a04392aa007d6150 /src/client/views/nodes/ImageBox.tsx
parentc2312afe4ee969043ba3ce4cb9c275a48b0f1ee0 (diff)
changing ai for images and collections to work mostly the same way. fixes for document view/collection/images to keep things working when the ai editor view reduces the rendered document size. fixed so that freeform views overlaid on images/vieos/etc have the ui menu items of collections.
Diffstat (limited to 'src/client/views/nodes/ImageBox.tsx')
-rw-r--r--src/client/views/nodes/ImageBox.tsx113
1 files changed, 70 insertions, 43 deletions
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 9838af4d0..9223fc180 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Tooltip } from '@mui/material';
+import { Slider, Tooltip } from '@mui/material';
import axios from 'axios';
import { Colors, Button, Type, Size } from '@dash/components';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction } from 'mobx';
@@ -44,6 +44,7 @@ import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler';
import { SettingsManager } from '../../util/SettingsManager';
import { AiOutlineSend } from 'react-icons/ai';
import { FireflyImageData } from '../smartdraw/FireflyConstants';
+import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler';
export class ImageEditorData {
// eslint-disable-next-line no-use-before-define
@@ -98,7 +99,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@observable private _regenInput = '';
@observable private _canInteract = true;
@observable private _regenerateLoading = false;
- @observable private _prevImgs: FireflyImageData[] = [];
+ @observable private _prevImgs: FireflyImageData[] = StrCast(this.Document.ai_firefly_history) ? JSON.parse(StrCast(this.Document.ai_firefly_history)) : [];
constructor(props: FieldViewProps) {
super(props);
@@ -386,8 +387,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
: UpdateIcon(
this.layoutDoc[Id] + '_icon_' + new Date().getTime(),
contentDiv,
- usePanelDimensions ? this._props.PanelWidth() : NumCast(this.layoutDoc._width),
- usePanelDimensions ? this._props.PanelHeight() : NumCast(this.layoutDoc._height),
+ usePanelDimensions || true ? this._props.PanelWidth() : NumCast(this.layoutDoc._width),
+ usePanelDimensions || true ? this._props.PanelHeight() : NumCast(this.layoutDoc._height),
this._props.PanelWidth(),
this._props.PanelHeight(),
0,
@@ -543,65 +544,91 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
<div key={img.pathname}>
<img
className="imageBox-aiView-img"
- src={img.href}
+ src={ClientUtils.prepend(img.pathname.replace(extname(img.pathname), '_s' + extname(img.pathname)))}
onClick={() => {
this.dataDoc[this.fieldKey] = new ImageField(img.pathname);
this.dataDoc.ai_firefly_prompt = img.prompt;
this.dataDoc.ai_firefly_seed = img.seed;
}}
/>
- <text>{img.prompt}</text>
+ <span>{img.prompt}</span>
</div>
))}
</div>
);
};
+ @observable private _fireflyRefStrength = 0;
componentAIView = () => {
const field = this.dataDoc[this.fieldKey] instanceof ImageField ? Cast(this.dataDoc[this.fieldKey], ImageField, null) : new ImageField(String(this.dataDoc[this.fieldKey]));
- const showRegenerate = this.Document[DocData].ai;
return (
<div className="imageBox-aiView">
- {showRegenerate && (
- <div className="imageBox-aiView-regenerate-container">
- <div className="imageBox-aiView-regenerate">
- <input
- className="imageBox-aiView-input"
- aria-label="Edit instructions input"
- type="text"
- value={this._regenInput}
- onChange={action(e => this._canInteract && (this._regenInput = e.target.value))}
- placeholder="Prompt (Optional)"
- />
- <Button
- text="Regenerate Image"
- type={Type.SEC}
- // style={{ alignSelf: 'flex-end' }}
- icon={this._regenerateLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
- iconPlacement="right"
- onClick={action(async () => {
- this._regenerateLoading = true;
- SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput, true).then(newImgs => {
- if (newImgs[0]) {
- const url = newImgs[0].pathname;
- const imgField = new ImageField(url);
- this._prevImgs.length === 0 &&
- this._prevImgs.push({ prompt: StrCast(this.dataDoc.ai_firefly_prompt), seed: this.dataDoc.ai_firefly_seed as number, href: this.paths.lastElement(), pathname: field.url.pathname });
- this._prevImgs.unshift({ prompt: newImgs[0].prompt, seed: newImgs[0].seed, href: this.paths.lastElement(), pathname: url });
- this.dataDoc.ai_firefly_history = `${this._prevImgs}`;
- this.dataDoc[this.fieldKey] = imgField;
- this._regenerateLoading = false;
- this._regenInput = '';
- }
- });
- })}
+ <div className="imageBox-aiView-regenerate-container">
+ <div className="imageBox-aiView-regenerate">
+ Firefly:
+ <input
+ className="imageBox-aiView-input"
+ aria-label="Edit instructions input"
+ type="text"
+ value={this._regenInput}
+ onChange={action(e => this._canInteract && (this._regenInput = e.target.value))}
+ placeholder={this._regenInput || StrCast(this.Document.title)}
+ />
+ <div className="imageBox-aiView-strength">
+ <span style={{ width: 60 }}>Similarity</span>
+ <Slider
+ className="imageBox-aiView-slider"
+ sx={{
+ '& .MuiSlider-track': { color: SettingsManager.userVariantColor },
+ '& .MuiSlider-rail': { color: SettingsManager.userBackgroundColor },
+ '& .MuiSlider-thumb': { color: SettingsManager.userVariantColor, '&.Mui-focusVisible, &:hover, &.Mui-active': { boxShadow: `0px 0px 0px 8px${SettingsManager.userColor.slice(0, 7)}10` } },
+ }}
+ min={0}
+ max={100}
+ step={1}
+ size="small"
+ value={this._fireflyRefStrength}
+ onChange={action((e, val) => this._canInteract && (this._fireflyRefStrength = val as number))}
+ valueLabelDisplay="auto"
/>
- <Button text="Get Variations" type={Type.SEC} iconPlacement="right" />
</div>
+ <Button
+ text="Create"
+ type={Type.SEC}
+ // style={{ alignSelf: 'flex-end' }}
+ icon={this._regenerateLoading ? <ReactLoading type="spin" color={SettingsManager.userVariantColor} width={16} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ onClick={action(async () => {
+ this._regenerateLoading = true;
+ if (this._fireflyRefStrength) {
+ DrawingFillHandler.drawingToImage(this.props.Document, this._fireflyRefStrength, this._regenInput || StrCast(this.Document.title))?.then(
+ action(() => {
+ this._regenerateLoading = false;
+ })
+ );
+ } else
+ SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput || StrCast(this.Document.title), true).then(
+ action(newImgs => {
+ if (newImgs[0]) {
+ const url = newImgs[0].pathname;
+ const imgField = new ImageField(url);
+ this._prevImgs.length === 0 &&
+ this._prevImgs.push({ prompt: StrCast(this.dataDoc.ai_firefly_prompt), seed: this.dataDoc.ai_firefly_seed as number, href: this.paths.lastElement(), pathname: field.url.pathname });
+ this._prevImgs.unshift({ prompt: newImgs[0].prompt, seed: newImgs[0].seed, pathname: url });
+ this.dataDoc.ai_firefly_history = JSON.stringify(this._prevImgs);
+ this.dataDoc.ai_firefly_prompt = newImgs[0].prompt;
+ this.dataDoc[this.fieldKey] = imgField;
+ this._regenerateLoading = false;
+ this._regenInput = '';
+ }
+ })
+ );
+ })}
+ />
</div>
- )}
+ </div>
<div className="imageBox-aiView-options-container">
- {showRegenerate && <text className="imageBox-aiView-subtitle"> More Options: </text>}
+ <span className="imageBox-aiView-subtitle"> More Options: </span>
<div className="imageBox-aiView-options">
<Button
type={Type.TERT}