import { Button, Colors, EditableText, IconButton, NumberDropdown, Size, Toggle, ToggleType, Type } from '@dash/components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import axios from 'axios'; import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { extname } from 'path'; import * as React from 'react'; import { AiOutlineSend } from 'react-icons/ai'; import ReactLoading from 'react-loading'; import { ClientUtils, DashColor, imageUrlToBase64, returnEmptyString, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, UpdateIcon } from '../../../ClientUtils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; import { InkTool } from '../../../fields/InkField'; import { List } from '../../../fields/List'; import { ObjectField } from '../../../fields/ObjectField'; import { ComputedField } from '../../../fields/ScriptField'; import { Cast, DocCast, ImageCast, ImageCastWithSuffix, NumCast, RTFCast, StrCast } from '../../../fields/Types'; import { ImageField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; import { emptyFunction } from '../../../Utils'; import { gptImageLabel } from '../../apis/gpt/GPT'; import { Docs } from '../../documents/Documents'; import { DocumentType } from '../../documents/DocumentTypes'; import { DocUtils, FollowLinkScript } from '../../documents/DocUtils'; import { Networking } from '../../Network'; import { DragManager } from '../../util/DragManager'; import { SettingsManager } from '../../util/SettingsManager'; import { SnappingManager } from '../../util/SnappingManager'; import { undoable, undoBatch, UndoManager } from '../../util/UndoManager'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; import { ViewBoxAnnotatableComponent } from '../DocComponent'; import { MarqueeAnnotator } from '../MarqueeAnnotator'; import { OverlayView } from '../OverlayView'; import { AnchorMenu } from '../pdf/AnchorMenu'; import { PinDocView, PinProps } from '../PinFuncs'; import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler'; import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler'; import { StickerPalette } from '../smartdraw/StickerPalette'; import { StyleProp } from '../StyleProp'; import { DocumentView } from './DocumentView'; import { FieldView, FieldViewProps } from './FieldView'; import { FocusViewOptions } from './FocusViewOptions'; import './ImageBox.scss'; import { OpenWhere } from './OpenWhere'; import { ImageUtils } from '../../util/Import & Export/ImageUtils'; const DefaultPath = '/assets/unknown-file-icon-hi.png'; export class ImageEditorData { private static _instance: ImageEditorData; private static get imageData() { return (ImageEditorData._instance ?? new ImageEditorData()).imageData; } // prettier-ignore @observable imageData: { rootDoc: Doc | undefined; open: boolean; source: string; addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean> } = observable({ rootDoc: undefined, open: false, source: '', addDoc: undefined }); private static set = action((open: boolean, rootDoc: Doc | undefined, source: string, addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean>) => { this._instance.imageData = { open, rootDoc, source, addDoc }; }); constructor() { makeObservable(this); ImageEditorData._instance = this; } public static get Open() { return ImageEditorData.imageData.open; } // prettier-ignore public static set Open(open: boolean) { ImageEditorData.set(open, this.imageData.rootDoc, this.imageData.source, this.imageData.addDoc); } // prettier-ignore public static get Source() { return ImageEditorData.imageData.source; } // prettier-ignore public static set Source(source: string) { ImageEditorData.set(this.imageData.open, this.imageData.rootDoc, source, this.imageData.addDoc); } // prettier-ignore public static get RootDoc() { return ImageEditorData.imageData.rootDoc; } // prettier-ignore public static set RootDoc(rootDoc: Opt) { ImageEditorData.set(this.imageData.open, rootDoc, this.imageData.source, this.imageData.addDoc); } // prettier-ignore public static get AddDoc() { return ImageEditorData.imageData.addDoc; } // prettier-ignore public static set AddDoc(addDoc: Opt<(doc: Doc | Doc[], annotationKey?: string) => boolean>) { ImageEditorData.set(this.imageData.open, this.imageData.rootDoc, this.imageData.source, addDoc); } // prettier-ignore } const UNSPLASH_API = 'https://api.unsplash.com/search/photos'; @observer export class ImageBox extends ViewBoxAnnotatableComponent() { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(ImageBox, fieldKey); } _ffref = React.createRef(); private _ignoreScroll = false; private _forcedScroll = false; private _dropDisposer?: DragManager.DragDropDisposer; private _disposers: { [name: string]: IReactionDisposer } = {}; private _getAnchor: (savedAnnotations: Opt>, addAsAnnotation: boolean) => Opt = () => undefined; private _overlayIconRef = React.createRef(); private _regenerateIconRef = React.createRef(); private _mainCont: HTMLDivElement | null = null; private _annotationLayer: React.RefObject = React.createRef(); imageRef: HTMLImageElement | null = null; //