aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/Network.ts2
-rw-r--r--src/client/apis/GoogleAuthenticationManager.tsx27
-rw-r--r--src/client/apis/google_docs/GoogleApiClientUtils.ts19
-rw-r--r--src/client/apis/google_docs/GooglePhotosClientUtils.ts18
-rw-r--r--src/client/util/Import & Export/ImageUtils.ts4
-rw-r--r--src/client/util/PingManager.ts2
-rw-r--r--src/client/util/SettingsManager.tsx3
-rw-r--r--src/client/views/collections/CollectionSubView.tsx3
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx5
-rw-r--r--src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx3
-rw-r--r--src/client/views/nodes/ImageBox.tsx20
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingView.tsx3
-rw-r--r--src/client/views/nodes/chatbot/tools/CreateCSVTool.ts4
-rw-r--r--src/client/views/nodes/chatbot/tools/ImageCreationTool.ts4
-rw-r--r--src/client/views/nodes/chatbot/tools/RAGTool.ts2
-rw-r--r--src/client/views/nodes/chatbot/tools/SearchTool.ts8
-rw-r--r--src/client/views/pdf/GPTPopup/GPTPopup.tsx13
-rw-r--r--src/client/views/smartdraw/FireflyConstants.ts5
-rw-r--r--src/client/views/smartdraw/SmartDrawHandler.tsx94
19 files changed, 123 insertions, 116 deletions
diff --git a/src/client/Network.ts b/src/client/Network.ts
index 323a2648c..a2ecf1bea 100644
--- a/src/client/Network.ts
+++ b/src/client/Network.ts
@@ -22,7 +22,7 @@ export namespace Networking {
},
body: body ? JSON.stringify(body) : undefined,
}).then(async response => {
- if (response.ok) return response.json();
+ if (response.ok) return response.json() as object;
return await response.text().then(text => ({ error: '' + response.status + ':' + response.statusText + '-' + text }));
});
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index 5269f763b..94ce42d8d 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -11,7 +11,8 @@ const AuthenticationUrl = 'https://accounts.google.com/o/oauth2/v2/auth';
const prompt = 'Paste authorization code here...';
@observer
-export class GoogleAuthenticationManager extends React.Component<{}> {
+export class GoogleAuthenticationManager extends React.Component<object> {
+ // eslint-disable-next-line no-use-before-define
public static Instance: GoogleAuthenticationManager;
private authenticationLink: Opt<string> = undefined;
@observable private openState = false;
@@ -19,7 +20,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
@observable private showPasteTargetState = false;
@observable private success: Opt<boolean> = undefined;
@observable private displayLauncher = true;
- @observable private credentials: any;
+ @observable private credentials: { user_info: { name: string; picture: string }; access_token: string } | undefined = undefined;
private disposer: Opt<IReactionDisposer>;
private set isOpen(value: boolean) {
@@ -35,25 +36,25 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
}
public fetchOrGenerateAccessToken = async (displayIfFound = false) => {
- let response: any = await Networking.FetchFromServer('/readGoogleAccessToken');
+ const response = await Networking.FetchFromServer('/readGoogleAccessToken');
// if this is an authentication url, activate the UI to register the new access token
if (new RegExp(AuthenticationUrl).test(response)) {
this.isOpen = true;
this.authenticationLink = response;
- return new Promise<string>(async resolve => {
+ return new Promise<string>(resolve => {
this.disposer?.();
this.disposer = reaction(
() => this.authenticationCode,
async authenticationCode => {
if (authenticationCode && /\d{1}\/[\w-]{55}/.test(authenticationCode)) {
this.disposer?.();
- const response = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
+ const response2 = await Networking.PostToServer('/writeGoogleAccessToken', { authenticationCode });
runInAction(() => {
this.success = true;
- this.credentials = response;
+ this.credentials = response2 as { user_info: { name: string; picture: string }; access_token: string };
});
this.resetState();
- resolve(response.access_token);
+ resolve((response2 as { access_token: string }).access_token);
}
}
);
@@ -61,16 +62,16 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
}
// otherwise, we already have a valid, stored access token and user info
- response = JSON.parse(response);
+ const response2 = JSON.parse(response) as { user_info: { name: string; picture: string }; access_token: string };
if (displayIfFound) {
runInAction(() => {
this.success = true;
- this.credentials = response;
+ this.credentials = response2;
});
this.resetState(-1, -1);
this.isOpen = true;
}
- return response.access_token;
+ return (response2 as { access_token: string }).access_token;
};
resetState = action((visibleForMS: number = 3000, fadesOutInMS: number = 500) => {
@@ -106,7 +107,7 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
}
});
- constructor(props: {}) {
+ constructor(props: object) {
super(props);
GoogleAuthenticationManager.Instance = this;
}
@@ -128,8 +129,8 @@ export class GoogleAuthenticationManager extends React.Component<{}> {
{this.showPasteTargetState ? <input className={'paste-target'} onChange={action(e => (this.authenticationCode = e.currentTarget.value))} placeholder={prompt} /> : null}
{this.credentials ? (
<>
- <img className={'avatar'} src={this.credentials.userInfo.picture} />
- <span className={'welcome'}>Welcome to Dash, {this.credentials.userInfo.name}</span>
+ <img className={'avatar'} src={this.credentials.user_info.picture} />
+ <span className={'welcome'}>Welcome to Dash, {this.credentials.user_info.name}</span>
<div
className={'disconnect'}
onClick={async () => {
diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts
index 0b303eacf..c1ac352b1 100644
--- a/src/client/apis/google_docs/GoogleApiClientUtils.ts
+++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts
@@ -1,7 +1,5 @@
-/* eslint-disable no-restricted-syntax */
/* eslint-disable no-use-before-define */
import { docs_v1 as docsV1 } from 'googleapis';
-// eslint-disable-next-line node/no-deprecated-api
import { isArray } from 'util';
import { EditorState } from 'prosemirror-state';
import { Opt } from '../../../fields/Doc';
@@ -37,7 +35,7 @@ export namespace GoogleApiClientUtils {
text: string | string[];
requests: docsV1.Schema$Request[];
}
- export type IdHandler = (id: DocumentId) => any;
+ export type IdHandler = (id: DocumentId) => unknown;
export type CreationResult = Opt<DocumentId>;
export type ReadLinesResult = Opt<{ title?: string; bodyLines?: string[] }>;
export type ReadResult = { title: string; body: string };
@@ -145,7 +143,7 @@ export namespace GoogleApiClientUtils {
if (paragraphs.length) {
const target = paragraphs[paragraphs.length - 1];
if (target.paragraph && target.paragraph.elements) {
- length = target.paragraph.elements.length;
+ const length = target.paragraph.elements.length;
if (length) {
const final = target.paragraph.elements[length - 1];
return final.endIndex ? final.endIndex - 1 : undefined;
@@ -208,13 +206,13 @@ export namespace GoogleApiClientUtils {
});
export const setStyle = async (options: UpdateOptions) => {
- const replies: any = await update({
+ const replies = await update({
documentId: options.documentId,
requests: options.requests,
});
- if ('errors' in replies) {
+ if (replies && 'errors' in replies) {
console.log('Write operation failed:');
- console.log(replies.errors.map((error: any) => error.message));
+ console.log(replies); //.errors.map((error: any) => error.message));
}
return replies;
};
@@ -229,7 +227,6 @@ export namespace GoogleApiClientUtils {
const { mode } = options;
if (!(index && mode === WriteMode.Insert)) {
const schema = await retrieve({ documentId });
- // eslint-disable-next-line no-cond-assign
if (!schema || !(index = Utils.endOf(schema))) {
return undefined;
}
@@ -258,10 +255,10 @@ export namespace GoogleApiClientUtils {
return undefined;
}
requests.push(...options.content.requests);
- const replies: any = await update({ documentId, requests });
- if ('errors' in replies) {
+ const replies = await update({ documentId, requests });
+ if (replies && 'errors' in replies) {
console.log('Write operation failed:');
- console.log(replies.errors.map((error: any) => error.message));
+ console.log(replies); // .errors.map((error: any) => error.message));
}
return replies;
};
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index b238f07e9..4b86a8341 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -1,5 +1,5 @@
/* eslint-disable no-use-before-define */
-import Photos = require('googlephotos');
+import Photos from 'googlephotos';
import { AssertionError } from 'assert';
import { EditorState } from 'prosemirror-state';
import { ClientUtils } from '../../../ClientUtils';
@@ -118,7 +118,7 @@ export namespace GooglePhotos {
}
export namespace Import {
- export type CollectionConstructor = (data: Array<Doc>, options: DocumentOptions, ...args: any) => Doc;
+ export type CollectionConstructor = (data: Array<Doc>, options: DocumentOptions, ...args: unknown[]) => Doc;
export const CollectionFromSearch = async (constructor: CollectionConstructor, requested: Opt<Partial<Query.SearchOptions>>): Promise<Doc> => {
await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
@@ -147,7 +147,7 @@ export namespace GooglePhotos {
values.forEach(async value => {
const searched = (await ContentSearch({ included: [value] }))?.mediaItems?.map(({ id }) => id);
searched?.forEach(async id => {
- const image = await Cast(idMapping[id], Doc);
+ const image = await Cast(idMapping[id as string], Doc);
if (image) {
const key = image[Id];
const tags = tagMapping.get(key);
@@ -193,7 +193,7 @@ export namespace GooglePhotos {
}
export interface SearchResponse {
- mediaItems: any[];
+ mediaItems: MediaItem[];
nextPageToken: string;
}
@@ -204,7 +204,7 @@ export namespace GooglePhotos {
const found = 0;
do {
// eslint-disable-next-line no-await-in-loop
- const response: any = await photos.mediaItems.search(albumId, pageSize, nextPageTokenStored);
+ const response = await photos.mediaItems.search(albumId, pageSize, nextPageTokenStored);
mediaItems.push(...response.mediaItems);
nextPageTokenStored = response.nextPageToken;
} while (found);
@@ -278,9 +278,9 @@ export namespace GooglePhotos {
return undefined;
};
- export const WriteMediaItemsToServer = async (body: { mediaItems: any[] }): Promise<UploadInformation[]> => {
+ export const WriteMediaItemsToServer = async (body: { mediaItems: MediaItem[] }): Promise<UploadInformation[]> => {
const uploads = await Networking.PostToServer('/googlePhotosMediaGet', body);
- return uploads;
+ return uploads as UploadInformation[];
};
export const UploadThenFetch = async (sources: Doc[], album?: AlbumReference, descriptionKey = 'caption') => {
@@ -320,7 +320,7 @@ export namespace GooglePhotos {
});
if (media.length) {
const results = await Networking.PostToServer('/googlePhotosMediaPost', { media, album });
- return results;
+ return results as Opt<ImageUploadResults>;
}
return undefined;
};
@@ -331,7 +331,7 @@ export namespace GooglePhotos {
if (typeof target === 'string') {
description = target;
} else if (target instanceof RichTextField) {
- description = RichTextUtils.ToPlainText(EditorState.fromJSON(new FormattedTextBox({} as any).config, JSON.parse(target.Data)));
+ description = RichTextUtils.ToPlainText(EditorState.fromJSON(FormattedTextBox.MakeConfig(undefined, undefined), JSON.parse(target.Data)));
}
return description;
};
diff --git a/src/client/util/Import & Export/ImageUtils.ts b/src/client/util/Import & Export/ImageUtils.ts
index f73149fdc..43807397f 100644
--- a/src/client/util/Import & Export/ImageUtils.ts
+++ b/src/client/util/Import & Export/ImageUtils.ts
@@ -8,9 +8,9 @@ import { Upload } from '../../../server/SharedMediaTypes';
import { Networking } from '../../Network';
export namespace ImageUtils {
- export const ExtractImgInfo = async (document: Doc): Promise<Upload.InspectionResults | undefined> => {
+ export const ExtractImgInfo = async (document: Doc) => {
const field = Cast(document.data, ImageField);
- return field ? Networking.PostToServer('/inspectImage', { source: field.url.href }) : undefined;
+ return field ? (Networking.PostToServer('/inspectImage', { source: field.url.href }) as Promise<Upload.InspectionResults>) : undefined;
};
export const AssignImgInfo = (document: Doc, data?: Upload.InspectionResults) => {
diff --git a/src/client/util/PingManager.ts b/src/client/util/PingManager.ts
index 170632836..0e4f8cab0 100644
--- a/src/client/util/PingManager.ts
+++ b/src/client/util/PingManager.ts
@@ -29,7 +29,7 @@ export class PingManager {
});
Networking.PostToServer('/ping', { date: new Date() })
.then(res => {
- SnappingManager.SetServerVersion(res.message);
+ SnappingManager.SetServerVersion((res as { message: string }).message);
!this.IsBeating && setIsBeating(true);
})
.catch(() => this.IsBeating && setIsBeating(false));
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 5d041f7b4..6ea242fc3 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -598,7 +598,8 @@ export class SettingsManager extends React.Component<object> {
});
} else {
const passwordBundle = { curr_pass: this._curr_password, new_pass: this._new_password, new_confirm: this._new_confirm };
- const { error } = await Networking.PostToServer('/internalResetPassword', passwordBundle);
+ const reset = await Networking.PostToServer('/internalResetPassword', passwordBundle);
+ const { error } = reset as { error: { msg: string }[] };
runInAction(() => {
this._passwordResultText = error ? 'Error: ' + error[0].msg + '...' : 'Password successfully updated!';
});
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index b40cd2761..ca830aa6f 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -28,6 +28,7 @@ import { FieldViewProps } from '../nodes/FieldView';
import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
import { FlashcardPracticeUI } from './FlashcardPracticeUI';
import { OpenWhere, OpenWhereMod } from '../nodes/OpenWhere';
+import { Upload } from '../../../server/SharedMediaTypes';
export enum docSortings {
Time = 'time',
@@ -407,7 +408,7 @@ export function CollectionSubView<X>() {
const imgSrc = img.split('src="')[1].split('"')[0];
const imgOpts = { ...options, _width: 300 };
if (imgSrc.startsWith('data:image') && imgSrc.includes('base64')) {
- const result = (await Networking.PostToServer('/uploadRemoteImage', { sources: [imgSrc] })).lastElement();
+ const result = ((await Networking.PostToServer('/uploadRemoteImage', { sources: [imgSrc] })) as Upload.ImageInformation[]).lastElement();
const newImgSrc =
result.accessPaths.agnostic.client.indexOf('dashblobstore') === -1 //
? ClientUtils.prepend(result.accessPaths.agnostic.client)
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 3c31b584e..b33c267ee 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1291,7 +1291,7 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
/**
* Adds the created drawing to the freeform canvas and sets the metadata.
*/
- addDrawing = (doc: Doc, opts: DrawingOptions, gptRes: string) => {
+ addDrawing = (doc: Doc, opts: DrawingOptions, gptRes: string, x?: number, y?: number) => {
const docData = doc[DocData];
docData.title = opts.text.match(/^(.*?)~~~.*$/)?.[1] || opts.text;
docData._width = opts.size;
@@ -1302,6 +1302,9 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection
docData.ai_drawing_data = gptRes;
docData.ai = 'gpt';
this._drawingContainer = doc;
+ if (x !== undefined && y !== undefined) {
+ [doc.x, doc.y] = this.screenToFreeformContentsXf.transformPoint(x, y);
+ }
this.addDocument(doc);
this._batch?.end();
};
diff --git a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
index 7fc906e59..4d9173211 100644
--- a/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
+++ b/src/client/views/nodes/DataVizBox/DocCreatorMenu.tsx
@@ -29,6 +29,7 @@ import './DocCreatorMenu.scss';
import { DefaultStyleProvider, returnEmptyDocViewList } from '../../StyleProvider';
import { Transform } from '../../../util/Transform';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { Upload } from '../../../../server/SharedMediaTypes';
export enum LayoutType {
Stacked = 'stacked',
@@ -536,7 +537,7 @@ export class DocCreatorMenu extends ObservableReactComponent<FieldViewProps> {
const res = await gptImageCall(prompt);
if (res) {
- const result = await Networking.PostToServer('/uploadRemoteImage', { sources: res });
+ const result = (await Networking.PostToServer('/uploadRemoteImage', { sources: res })) as Upload.FileInformation[];
const source = ClientUtils.prepend(result[0].accessPaths.agnostic.client);
return source;
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index b6b0e4a8a..9395863d8 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -36,7 +36,7 @@ import { OverlayView } from '../OverlayView';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { PinDocView, PinProps } from '../PinFuncs';
import { DrawingFillHandler } from '../smartdraw/DrawingFillHandler';
-import { FireflyImageData } from '../smartdraw/FireflyConstants';
+import { FireflyImageData, isFireflyImageData } from '../smartdraw/FireflyConstants';
import { SmartDrawHandler } from '../smartdraw/SmartDrawHandler';
import { StickerPalette } from '../smartdraw/StickerPalette';
import { StyleProp } from '../StyleProp';
@@ -354,7 +354,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const ext = extname(file);
return file.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
})(ImageCast(this.Document[Doc.LayoutFieldKey(this.Document)])?.url.href),
- }).then((info: Upload.ImageInformation) => {
+ }).then(res => {
+ const info = res as Upload.ImageInformation;
const img = Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { title: 'expand:' + this.Document.title });
DocUtils.assignImageInfo(info, img);
this._props.addDocTab(img, OpenWhere.addRight);
@@ -627,14 +628,15 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
} else
SmartDrawHandler.Instance.regenerate([this.Document], undefined, undefined, this._regenInput || StrCast(this.Document.title), true).then(
action(newImgs => {
- if (newImgs[0] && !(newImgs[0] instanceof Doc)) {
- const url = newImgs[0].pathname;
+ const firstImg = newImgs[0];
+ if (isFireflyImageData(firstImg)) {
+ const url = firstImg.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._prevImgs.unshift({ prompt: firstImg.prompt, seed: firstImg.seed, pathname: url });
this.dataDoc.ai_firefly_history = JSON.stringify(this._prevImgs);
- this.dataDoc.ai_firefly_prompt = newImgs[0].prompt;
+ this.dataDoc.ai_firefly_prompt = firstImg.prompt;
this.dataDoc[this.fieldKey] = imgField;
this._regenerateLoading = false;
this._regenInput = '';
@@ -688,7 +690,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
const ext = extname(file);
return file.replace(ext, (this._error ? '_o' : this._curSuffix) + ext);
})(ImageCast(this.Document[Doc.LayoutFieldKey(this.Document)])?.url.href),
- }).then((info: Upload.ImageInformation) => {
+ }).then(res => {
+ const info = res as Upload.ImageInformation;
const img = Docs.Create.ImageDocument(info.accessPaths.agnostic.client, { title: 'expand:' + this.Document.title });
DocUtils.assignImageInfo(info, img);
const genratedDocs = this.Document.generatedDocs
@@ -741,7 +744,8 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
focus = (anchor: Doc, options: FocusViewOptions) => (anchor.type === DocumentType.CONFIG ? undefined : this._ffref.current?.focus(anchor, options));
renderedPixelDimensions = async () => {
- const { nativeWidth: width, nativeHeight: height } = await Networking.PostToServer('/inspectImage', { source: this.paths[0] });
+ const res = await Networking.PostToServer('/inspectImage', { source: this.paths[0] });
+ const { nativeWidth: width, nativeHeight: height } = res as { nativeWidth: number; nativeHeight: number };
return { width, height };
};
savedAnnotations = () => this._savedAnnotations;
diff --git a/src/client/views/nodes/RecordingBox/RecordingView.tsx b/src/client/views/nodes/RecordingBox/RecordingView.tsx
index 37ffca2d6..e7a6193d4 100644
--- a/src/client/views/nodes/RecordingBox/RecordingView.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingView.tsx
@@ -1,4 +1,3 @@
-/* eslint-disable react/button-has-type */
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { IconContext } from 'react-icons';
@@ -72,7 +71,7 @@ export function RecordingView(props: IRecordingViewProps) {
const serverPaths: string[] = (await Networking.UploadFilesToServer(videoFiles.map(file => ({ file })))).map(res => (res.result instanceof Error ? '' : res.result.accessPaths.agnostic.server));
// concat the segments together using post call
- const result: Upload.AccessPathInfo | Error = await Networking.PostToServer('/concatVideos', serverPaths);
+ const result = (await Networking.PostToServer('/concatVideos', serverPaths)) as Upload.AccessPathInfo | Error;
!(result instanceof Error) ? props.setResult(result, concatPres || undefined) : console.error('video conversion failed');
})();
}
diff --git a/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts b/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts
index e8ef3fbfe..290c48d6c 100644
--- a/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts
+++ b/src/client/views/nodes/chatbot/tools/CreateCSVTool.ts
@@ -38,10 +38,10 @@ export class CreateCSVTool extends BaseTool<CreateCSVToolParamsType> {
async execute(args: ParametersType<CreateCSVToolParamsType>): Promise<Observation[]> {
try {
console.log('Creating CSV file:', args.filename, ' with data:', args.csvData);
- const { fileUrl, id } = await Networking.PostToServer('/createCSV', {
+ const { fileUrl, id } = (await Networking.PostToServer('/createCSV', {
filename: args.filename,
data: args.csvData,
- });
+ })) as { fileUrl: string; id: string };
this._handleCSVResult(fileUrl, args.filename, id, args.csvData);
diff --git a/src/client/views/nodes/chatbot/tools/ImageCreationTool.ts b/src/client/views/nodes/chatbot/tools/ImageCreationTool.ts
index dc6140871..e92d87dfd 100644
--- a/src/client/views/nodes/chatbot/tools/ImageCreationTool.ts
+++ b/src/client/views/nodes/chatbot/tools/ImageCreationTool.ts
@@ -37,9 +37,9 @@ export class ImageCreationTool extends BaseTool<ImageCreationToolParamsType> {
console.log(`Generating image for prompt: ${image_prompt}`);
// Create an array of promises, each one handling a search for a query
try {
- const { result, url } = await Networking.PostToServer('/generateImage', {
+ const { result, url } = (await Networking.PostToServer('/generateImage', {
image_prompt,
- });
+ })) as { result: Upload.FileInformation & Upload.InspectionResults; url: string };
console.log('Image generation result:', result);
this._createImage(result, { text: RTFCast(image_prompt) });
return url
diff --git a/src/client/views/nodes/chatbot/tools/RAGTool.ts b/src/client/views/nodes/chatbot/tools/RAGTool.ts
index 2db61c768..ef374ed22 100644
--- a/src/client/views/nodes/chatbot/tools/RAGTool.ts
+++ b/src/client/views/nodes/chatbot/tools/RAGTool.ts
@@ -75,7 +75,7 @@ export class RAGTool extends BaseTool<RAGToolParamsType> {
async getFormattedChunks(relevantChunks: RAGChunk[]): Promise<Observation[]> {
try {
- const { formattedChunks } = await Networking.PostToServer('/formatChunks', { relevantChunks });
+ const { formattedChunks } = await Networking.PostToServer('/formatChunks', { relevantChunks }) as { formattedChunks: Observation[]}
if (!formattedChunks) {
throw new Error('Failed to format chunks');
diff --git a/src/client/views/nodes/chatbot/tools/SearchTool.ts b/src/client/views/nodes/chatbot/tools/SearchTool.ts
index 5fc6ab768..6a11407a5 100644
--- a/src/client/views/nodes/chatbot/tools/SearchTool.ts
+++ b/src/client/views/nodes/chatbot/tools/SearchTool.ts
@@ -41,15 +41,15 @@ export class SearchTool extends BaseTool<SearchToolParamsType> {
// Create an array of promises, each one handling a search for a query
const searchPromises = queries.map(async query => {
try {
- const { results } = await Networking.PostToServer('/getWebSearchResults', {
+ const { results } = (await Networking.PostToServer('/getWebSearchResults', {
query,
max_results: this._max_results,
- });
+ })) as { results: { url: string; snippet: string }[] };
const data = results.map((result: { url: string; snippet: string }) => {
const id = uuidv4();
this._addLinkedUrlDoc(result.url, id);
return {
- type: 'text',
+ type: 'text' as const,
text: `<chunk chunk_id="${id}" chunk_type="url"><url>${result.url}</url><overview>${result.snippet}</overview></chunk>`,
};
});
@@ -58,7 +58,7 @@ export class SearchTool extends BaseTool<SearchToolParamsType> {
console.log(error);
return [
{
- type: 'text',
+ type: 'text' as const,
text: `An error occurred while performing the web search for query: ${query}`,
},
];
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index efddfb841..f4ab2f41c 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -21,11 +21,13 @@ import { DictationButton } from '../../DictationButton';
import { ObservableReactComponent } from '../../ObservableReactComponent';
import { TagItem } from '../../TagsView';
import { ChatSortField, docSortings } from '../../collections/CollectionSubView';
-import { DocumentView } from '../../nodes/DocumentView';
+import { DocumentView, DocumentViewInternal } from '../../nodes/DocumentView';
import { SmartDrawHandler } from '../../smartdraw/SmartDrawHandler';
import { AnchorMenu } from '../AnchorMenu';
import './GPTPopup.scss';
import { FireflyImageDimensions } from '../../smartdraw/FireflyConstants';
+import { Upload } from '../../../../server/SharedMediaTypes';
+import { OpenWhere } from '../../nodes/OpenWhere';
export enum GPTPopupMode {
SUMMARY, // summary of seleted document text
@@ -210,7 +212,12 @@ export class GPTPopup extends ObservableReactComponent<object> {
// );
// } else∂
return SmartDrawHandler.CreateWithFirefly(imgDesc, FireflyImageDimensions.Square, 0)
- .then(action(() => (this._userPrompt = '')))
+ .then(
+ action(doc => {
+ doc instanceof Doc && DocumentViewInternal.addDocTabFunc(doc, OpenWhere.addRight);
+ this._userPrompt = '';
+ })
+ )
.catch(e => {
alert(e);
return undefined;
@@ -259,7 +266,7 @@ export class GPTPopup extends ObservableReactComponent<object> {
.then(imageUrls =>
imageUrls?.[0]
? Networking.PostToServer('/uploadRemoteImage', { sources: [imageUrls[0]] }).then(res => {
- const source = ClientUtils.prepend(res[0].accessPaths.agnostic.client);
+ const source = ClientUtils.prepend((res as Upload.FileInformation[])[0].accessPaths.agnostic.client);
return this.setImgUrls([[imageUrls[0]!, source]]);
})
: undefined
diff --git a/src/client/views/smartdraw/FireflyConstants.ts b/src/client/views/smartdraw/FireflyConstants.ts
index 1f1781617..8cc9e36a5 100644
--- a/src/client/views/smartdraw/FireflyConstants.ts
+++ b/src/client/views/smartdraw/FireflyConstants.ts
@@ -5,6 +5,11 @@ export interface FireflyImageData {
href?: string;
}
+export function isFireflyImageData(obj: unknown): obj is FireflyImageData {
+ const tobj = obj as FireflyImageData;
+ return typeof obj === 'object' && obj !== null && typeof tobj.pathname === 'string' && typeof tobj.prompt === 'string' && typeof tobj.seed === 'number';
+}
+
export enum FireflyImageDimensions {
Square = 'square',
Landscape = 'landscape',
diff --git a/src/client/views/smartdraw/SmartDrawHandler.tsx b/src/client/views/smartdraw/SmartDrawHandler.tsx
index 9d67d111b..532391ac6 100644
--- a/src/client/views/smartdraw/SmartDrawHandler.tsx
+++ b/src/client/views/smartdraw/SmartDrawHandler.tsx
@@ -23,10 +23,10 @@ import { SVGToBezier, SVGType } from '../../util/bezierFit';
import { InkingStroke } from '../InkingStroke';
import { ObservableReactComponent } from '../ObservableReactComponent';
import { MarqueeView } from '../collections/collectionFreeForm';
-import { ActiveInkArrowEnd, ActiveInkArrowStart, ActiveInkBezierApprox, ActiveInkColor, ActiveInkDash, ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
-import { OpenWhere } from '../nodes/OpenWhere';
+import { ActiveInkArrowEnd, ActiveInkArrowStart, ActiveInkBezierApprox, ActiveInkColor, ActiveInkDash, ActiveInkFillColor, ActiveInkWidth, ActiveIsInkMask, DocumentView } from '../nodes/DocumentView';
import { FireflyDimensionsMap, FireflyImageData, FireflyImageDimensions } from './FireflyConstants';
import './SmartDrawHandler.scss';
+import { Upload } from '../../../server/SharedMediaTypes';
export interface DrawingOptions {
text: string;
@@ -60,7 +60,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
private _lastInput: DrawingOptions = { text: '', complexity: 5, size: 350, autoColor: true, x: 0, y: 0 };
private _lastResponse: string = '';
private _selectedDocs: Doc[] = [];
- private _errorOccurredOnce = false;
@observable private _display: boolean = false;
@observable private _pageX: number = 0;
@@ -95,7 +94,7 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
CollectionFreeForm, FormattedTextBox, StickerPalette) to define how a drawing document should be added
or removed in their respective locations (to the freeform canvas, to the sticker palette's preview, etc.)
*/
- public AddDrawing: (doc: Doc, opts: DrawingOptions, gptRes: string) => void = unimplementedFunction;
+ public AddDrawing: (doc: Doc, opts: DrawingOptions, gptRes: string, x?: number, y?: number) => void = unimplementedFunction;
public RemoveDrawing: (useLastContainer: boolean, doc?: Doc) => void = unimplementedFunction;
/**
* This creates the ink document that represents a drawing, so it goes through the strokes that make up the drawing,
@@ -206,16 +205,15 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
this._isLoading = true;
this._canInteract = false;
if (this.ShowRegenerate) {
- await this.regenerate(this._selectedDocs);
- runInAction(() => {
- this._selectedDocs = [];
- this._regenInput = '';
- this._showEditBox = false;
- });
+ await this.regenerate(this._selectedDocs).then(
+ action(() => {
+ this._selectedDocs = [];
+ this._regenInput = '';
+ this._showEditBox = false;
+ })
+ );
} else {
- runInAction(() => {
- this._showOptions = false;
- });
+ this._showOptions = false;
try {
if (this._generateImage) {
await this.createImageWithFirefly(this._userInput);
@@ -224,18 +222,8 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
await this.drawWithGPT({ X: this._pageX, Y: this._pageY }, this._userInput, this._complexity, this._size, this._autoColor);
}
this.hideSmartDrawHandler();
-
- runInAction(() => {
- this.ShowRegenerate = true;
- });
} catch (err) {
- if (this._errorOccurredOnce) {
- console.error('GPT call failed', err);
- this._errorOccurredOnce = false;
- } else {
- this._errorOccurredOnce = true;
- await this.handleSendClick();
- }
+ console.error('GPT call failed', err);
}
}
runInAction(() => {
@@ -256,7 +244,6 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
const drawingDoc = strokeData && this.CreateDrawingDoc(strokeData.data, strokeData.lastInput, strokeData.lastRes);
drawingDoc && this.AddDrawing(drawingDoc, this._lastInput, res);
drawingDoc && this._selectedDocs.push(drawingDoc);
- this._errorOccurredOnce = false;
return strokeData;
} else {
console.error('GPT call failed');
@@ -270,7 +257,10 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
*/
createImageWithFirefly = (input: string, seed?: number): Promise<FireflyImageData | Doc | undefined> => {
this._lastInput.text = input;
- return SmartDrawHandler.CreateWithFirefly(input, this._imgDims, seed);
+ return SmartDrawHandler.CreateWithFirefly(input, this._imgDims, seed).then(doc => {
+ doc instanceof Doc && this.AddDrawing(doc, this._lastInput, input, this._pageX, this._pageY);
+ return doc;
+ });
}; /**
* Calls Firefly API to create an image based on user input
*/
@@ -281,9 +271,11 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
public static ReCreateWithFirefly(input: string, imgDims: FireflyImageDimensions, seed?: number): Promise<FireflyImageData | Doc | undefined> {
const dims = FireflyDimensionsMap[imgDims];
return Networking.PostToServer('/queryFireflyImage', { prompt: input, width: dims.width, height: dims.height, seed })
- .then(img => {
- if (img.error) {
- alert('recreate image failed: ' + img.error);
+ .then(res => {
+ const img = res as Upload.FileInformation;
+ const error = res as { error: string };
+ if ('error' in error) {
+ alert('recreate image failed: ' + error.error);
return undefined;
}
return { prompt: input, seed, pathname: img.accessPaths.agnostic.client };
@@ -296,21 +288,22 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
public static CreateWithFirefly(input: string, imgDims: FireflyImageDimensions, seed?: number): Promise<FireflyImageData | Doc | undefined> {
const dims = FireflyDimensionsMap[imgDims];
return Networking.PostToServer('/queryFireflyImage', { prompt: input, width: dims.width, height: dims.height, seed })
- .then(img => {
- if (img.error) {
- alert('create image failed: ' + img.error);
+ .then(res => {
+ const img = res as Upload.FileInformation;
+ const error = res as { error: string };
+ if ('error' in error) {
+ alert('create image failed: ' + error.error);
return undefined;
}
- const newseed = img.accessPaths.agnostic.client.match(/\/(\d+)upload/)[1];
+ const newseed = img.accessPaths.agnostic.client.match(/\/(\d+)upload/)?.[1];
const imgDoc: Doc = Docs.Create.ImageDocument(img.accessPaths.agnostic.client, {
title: input.match(/^(.*?)~~~.*$/)?.[1] || input,
nativeWidth: dims.width,
nativeHeight: dims.height,
ai: 'firefly',
- ai_firefly_seed: newseed,
+ ai_firefly_seed: +(newseed ?? 0),
ai_firefly_prompt: input,
});
- DocumentViewInternal.addDocTabFunc(imgDoc, OpenWhere.addRight);
return imgDoc;
})
.catch(e => {
@@ -331,26 +324,21 @@ export class SmartDrawHandler extends ObservableReactComponent<object> {
return Promise.all(
drawingDocs.map(async doc => {
switch (doc.type) {
- case DocumentType.IMG:
- if (this._regenInput) {
- // if (this._selectedDoc) {
- const newPrompt = doc.ai_firefly_prompt ? `${doc.ai_firefly_prompt} ~~~ ${this._regenInput}` : this._regenInput;
- return changeInPlace ? this.recreateImageWithFirefly(newPrompt, NumCast(doc?.ai_firefly_seed)) : this.createImageWithFirefly(newPrompt, NumCast(doc?.ai_firefly_seed));
- // }
- }
- return changeInPlace
- ? this.recreateImageWithFirefly(this._lastInput.text || StrCast(doc.ai_firefly_prompt), NumCast(doc?.ai_firefly_seed))
- : this.createImageWithFirefly(this._lastInput.text || StrCast(doc.ai_firefly_prompt), NumCast(doc?.ai_firefly_seed));
+ case DocumentType.IMG: {
+ const func = changeInPlace ? this.recreateImageWithFirefly : this.createImageWithFirefly;
+ const newPrompt = doc.ai_firefly_prompt ? `${doc.ai_firefly_prompt} ~~~ ${this._regenInput}` : this._regenInput;
+ return this._regenInput ? func(newPrompt, NumCast(doc?.ai_firefly_seed)) : func(this._lastInput.text || StrCast(doc.ai_firefly_prompt));
+ }
case DocumentType.COL: {
try {
- let res;
- if (this._regenInput) {
- const prompt = `This is your previously generated svg code: ${this._lastResponse} for the user input "${this._lastInput.text}". Please regenerate it with the provided specifications.`;
- res = await gptAPICall(`"${this._regenInput}"`, GPTCallType.DRAW, prompt, true);
- this._lastInput.text = `${this._lastInput.text} ~~~ ${this._regenInput}`;
- } else {
- res = await gptAPICall(`"${this._lastInput.text}", "${this._lastInput.complexity}", "${this._lastInput.size}"`, GPTCallType.DRAW, undefined, true);
- }
+ const res = await (async () => {
+ if (this._regenInput) {
+ const prompt = `This is your previously generated svg code: ${this._lastResponse} for the user input "${this._lastInput.text}". Please regenerate it with the provided specifications.`;
+ this._lastInput.text = `${this._lastInput.text} ~~~ ${this._regenInput}`;
+ return gptAPICall(`"${this._regenInput}"`, GPTCallType.DRAW, prompt, true);
+ }
+ return gptAPICall(`"${this._lastInput.text}", "${this._lastInput.complexity}", "${this._lastInput.size}"`, GPTCallType.DRAW, undefined, true);
+ })();
if (res) {
const strokeData = await this.parseSvg(res, { X: this._lastInput.x, Y: this._lastInput.y }, true, lastInput?.autoColor || this._autoColor);
this.RemoveDrawing !== unimplementedFunction && this.RemoveDrawing(true, doc);