aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/MapBox/MapAnchorMenu.tsx')
-rw-r--r--src/client/views/nodes/MapBox/MapAnchorMenu.tsx355
1 files changed, 54 insertions, 301 deletions
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index 798905bcd..439c1f14f 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -3,18 +3,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, observable, ObservableMap, reaction } from 'mobx';
import { observer } from 'mobx-react';
import { ColorState } from 'react-color';
-import { Doc, Opt } from '../../../fields/Doc';
-import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../Utils';
-import { SelectionManager } from '../../util/SelectionManager';
-import { AntimodeMenu, AntimodeMenuProps } from "../AntimodeMenu"
-import { LinkPopup } from '../linking/LinkPopup';
-import { gptAPICall, GPTCallType } from '../../apis/gpt/GPT';
-import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
+import { Doc, Opt } from '../../../../fields/Doc';
+import { returnFalse, setupMoveUpEvents, unimplementedFunction, Utils } from '../../../../Utils';
+import { SelectionManager } from '../../../util/SelectionManager';
+import { AntimodeMenu, AntimodeMenuProps } from "../../AntimodeMenu"
+import { LinkPopup } from '../../linking/LinkPopup';
+import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT';
+// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup';
import { EditorView } from 'prosemirror-view';
import './MapAnchorMenu.scss';
import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
-import { StrCast } from '../../../fields/Types';
-import { DocumentType } from '../../documents/DocumentTypes';
+import { StrCast } from '../../../../fields/Types';
+import { DocumentType } from '../../../documents/DocumentTypes';
@observer
export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -24,73 +24,22 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
private _disposer2: IReactionDisposer | undefined;
private _commentCont = React.createRef<HTMLButtonElement>();
- @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)';
- @observable public Status: 'marquee' | 'annotation' | '' = '';
- // GPT additions
- @observable private GPTpopupText: string = '';
- @observable private loadingGPT: boolean = false;
- @observable private showGPTPopup: boolean = false;
- @observable private GPTMode: GPTPopupMode = GPTPopupMode.SUMMARY;
- @observable private selectedText: string = '';
- @observable private editorView?: EditorView;
- @observable private textDoc?: Doc;
- @observable private highlightRange: number[] | undefined;
- private selectionRange: number[] | undefined;
-
- @action
- setGPTPopupVis = (vis: boolean) => {
- this.showGPTPopup = vis;
- };
- @action
- setGPTMode = (mode: GPTPopupMode) => {
- this.GPTMode = mode;
- };
-
- @action
- setGPTPopupText = (txt: string) => {
- this.GPTpopupText = txt;
- };
-
- @action
- setLoading = (loading: boolean) => {
- this.loadingGPT = loading;
- };
-
- @action
- setHighlightRange(r: number[] | undefined) {
- this.highlightRange = r;
- }
-
- @action
- public setSelectedText = (txt: string) => {
- this.selectedText = txt;
- };
-
- @action
- public setEditorView = (editor: EditorView) => {
- this.editorView = editor;
- };
-
- @action
- public setTextDoc = (textDoc: Doc) => {
- this.textDoc = textDoc;
- };
public onMakeAnchor: () => Opt<Doc> = () => undefined; // Method to get anchor from text search
- public OnCrop: (e: PointerEvent) => void = unimplementedFunction;
- public OnClick: (e: PointerEvent) => void = unimplementedFunction;
- public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
- public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
- public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
+ public Center: () => void = unimplementedFunction;
+ // public OnClick: (e: PointerEvent) => void = unimplementedFunction;
+ // public OnAudio: (e: PointerEvent) => void = unimplementedFunction;
+ // public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
+ // public StartCropDrag: (e: PointerEvent, ele: HTMLElement) => void = unimplementedFunction;
public Highlight: (color: string, isTargetToggler: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>, addAsAnnotation?: boolean) => Opt<Doc> = (color: string, isTargetToggler: boolean) => undefined;
public GetAnchor: (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => Opt<Doc> = (savedAnnotations: Opt<ObservableMap<number, HTMLDivElement[]>>, addAsAnnotation: boolean) => undefined;
public Delete: () => void = unimplementedFunction;
- public PinToPres: () => void = unimplementedFunction;
- public MakeTargetToggle: () => void = unimplementedFunction;
- public ShowTargetTrail: () => void = unimplementedFunction;
+ public LinkNote: () => void = unimplementedFunction;
+ // public MakeTargetToggle: () => void = unimplementedFunction;
+ // public ShowTargetTrail: () => void = unimplementedFunction;
public IsTargetToggler: () => boolean = returnFalse;
public get Active() {
return this._left > 0;
@@ -113,8 +62,6 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
() => this._opacity,
opacity => {
if (!opacity) {
- this.setGPTPopupVis(false);
- this.setGPTPopupText('');
}
},
{ fireImmediately: true }
@@ -122,259 +69,62 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
this._disposer = reaction(
() => SelectionManager.Views().slice(),
selected => {
- this.setGPTPopupVis(false);
- this.setGPTPopupText('');
MapAnchorMenu.Instance.fadeOut(true);
}
);
}
+ // audioDown = (e: React.PointerEvent) => {
+ // setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e));
+ // };
+
+ // cropDown = (e: React.PointerEvent) => {
+ // setupMoveUpEvents(
+ // this,
+ // e,
+ // (e: PointerEvent) => {
+ // this.StartCropDrag(e, this._commentCont.current!);
+ // return true;
+ // },
+ // returnFalse,
+ // e => this.OnCrop?.(e)
+ // );
+ // };
+
+
+ static top = React.createRef<HTMLDivElement>();
+ // public get Top(){
+ // return this.top
+ // }
- /**
- * Invokes the API with the selected text and stores it in the summarized text.
- * @param e pointer down event
- */
- gptSummarize = async (e: React.PointerEvent) => {
- this.setHighlightRange(undefined);
- this.setGPTPopupVis(true);
- this.setGPTMode(GPTPopupMode.SUMMARY);
- this.setLoading(true);
-
- try {
- const res = await gptAPICall(this.selectedText, GPTCallType.SUMMARY);
- if (res) {
- this.setGPTPopupText(res);
- } else {
- this.setGPTPopupText('Something went wrong.');
- }
- } catch (err) {
- console.error(err);
- }
-
- this.setLoading(false);
- };
-
- /**
- * Makes a GPT call to edit selected text.
- * @returns nothing
- */
- gptEdit = async () => {
- if (!this.editorView) return;
- this.setHighlightRange(undefined);
- const state = this.editorView.state;
- const sel = state.selection;
- const fullText = state.doc.textBetween(0, this.editorView.state.doc.content.size, ' \n');
- const selectedText = state.doc.textBetween(sel.from, sel.to);
-
- this.setGPTPopupVis(true);
- this.setGPTMode(GPTPopupMode.EDIT);
- this.setLoading(true);
-
- try {
- let res = await gptAPICall(selectedText, GPTCallType.EDIT);
- // let res = await this.mockGPTCall();
- if (!res) return;
- res = res.trim();
- const resultText = fullText.slice(0, sel.from - 1) + res + fullText.slice(sel.to - 1);
-
- if (res) {
- this.setGPTPopupText(resultText);
- this.setHighlightRange([sel.from - 1, sel.from - 1 + res.length]);
- } else {
- this.setGPTPopupText('Something went wrong.');
- }
- } catch (err) {
- console.error(err);
- }
-
- this.setLoading(false);
- };
-
- /**
- * Replaces text suggestions from GPT.
- */
- replaceText = (replacement: string) => {
- if (!this.editorView || !this.textDoc) return;
- this.textDoc.text = replacement;
- };
-
- pointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(
- this,
- e,
- (e: PointerEvent) => {
- this.StartDrag(e, this._commentCont.current!);
- return true;
- },
- returnFalse,
- e => this.OnClick?.(e)
- );
- };
-
- audioDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, returnFalse, returnFalse, e => this.OnAudio?.(e));
- };
-
- cropDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(
- this,
- e,
- (e: PointerEvent) => {
- this.StartCropDrag(e, this._commentCont.current!);
- return true;
- },
- returnFalse,
- e => this.OnCrop?.(e)
- );
- };
-
- @action
- highlightClicked = (e: React.MouseEvent) => {
- this.Highlight(this.highlightColor, false, undefined, true);
- MapAnchorMenu.Instance.fadeOut(true);
- };
-
- @computed get highlighter() {
- return (
- <Group>
- <IconButton
- icon={<FontAwesomeIcon icon="highlighter" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />}
- tooltip={'Click to Highlight'}
- onClick={this.highlightClicked}
- colorPicker={this.highlightColor}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- <ColorPicker selectedColor={this.highlightColor} setFinalColor={this.changeHighlightColor} setSelectedColor={this.changeHighlightColor} size={Size.XSMALL} />
- </Group>
- );
- }
-
- @action changeHighlightColor = (color: string) => {
- const col: ColorState = {
- hex: color,
- hsl: { a: 0, h: 0, s: 0, l: 0, source: '' },
- hsv: { a: 0, h: 0, s: 0, v: 0, source: '' },
- rgb: { a: 0, r: 0, b: 0, g: 0, source: '' },
- oldHue: 0,
- source: '',
- };
- this.highlightColor = Utils.colorString(col);
- };
-
- /**
- * Returns whether the selected text can be summarized. The goal is to have
- * all selected text available to summarize but its only supported for pdf and web ATM.
- * @returns Whether the GPT icon for summarization should appear
- */
- canSummarize = (): boolean => {
- const docs = SelectionManager.Docs();
- if (docs.length > 0) {
- return docs.some(doc => doc.type === DocumentType.PDF || doc.type === DocumentType.WEB);
- }
- return false;
- };
-
- /**
- * Returns whether the selected text can be edited.
- * @returns Whether the GPT icon for summarization should appear
- */
- canEdit = (): boolean => {
- const docs = SelectionManager.Docs();
- if (docs.length > 0) {
- return docs.some(doc => doc.type === 'rtf');
- }
- return false;
- };
render() {
- const buttons =
- this.Status === 'marquee' ? (
- <>
- {this.highlighter}
- <IconButton
- tooltip="Drag to Place Annotation" //
- onPointerDown={this.pointerDown}
- icon={<FontAwesomeIcon icon="comment-alt" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
- {MapAnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
- <IconButton
- tooltip="Summarize with AI" //
- onPointerDown={this.gptSummarize}
- icon={<FontAwesomeIcon icon="comment-dots" size="lg" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- <GPTPopup
- key="gptpopup"
- visible={this.showGPTPopup}
- text={this.GPTpopupText}
- highlightRange={this.highlightRange}
- loading={this.loadingGPT}
- callSummaryApi={this.gptSummarize}
- callEditApi={this.gptEdit}
- replaceText={this.replaceText}
- mode={this.GPTMode}
- />
- {MapAnchorMenu.Instance.OnAudio === unimplementedFunction ? null : (
- <IconButton
- tooltip="Click to Record Annotation" //
- onPointerDown={this.audioDown}
- icon={<FontAwesomeIcon icon="microphone" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- {this.canEdit() && (
- <IconButton
- tooltip="AI edit suggestions" //
- onPointerDown={this.gptEdit}
- icon={<FontAwesomeIcon icon="pencil-alt" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- <Popup
- tooltip="Find document to link to selected text" //
- type={Type.PRIM}
- icon={<FontAwesomeIcon icon={'search'} />}
- popup={<LinkPopup key="popup" linkCreateAnchor={this.onMakeAnchor} />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- {MapAnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
- <IconButton
- tooltip="Click/Drag to create cropped image" //
- onPointerDown={this.cropDown}
- icon={<FontAwesomeIcon icon="image" />}
- color={StrCast(Doc.UserDoc().userColor)}
- />
- )}
- </>
- ) : (
+ const buttons =(
<>
- {this.Delete !== returnFalse && (
+ {(
<IconButton
- tooltip="Remove Link Anchor" //
+ tooltip="Delete Pin" //
onPointerDown={this.Delete}
icon={<FontAwesomeIcon icon="trash-alt" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.PinToPres !== returnFalse && (
+ {(
<IconButton
- tooltip="Pin to Presentation" //
- onPointerDown={this.PinToPres}
+ tooltip="Link Note to Pin" //
+ onPointerDown={this.LinkNote}
icon={<FontAwesomeIcon icon="map-pin" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.ShowTargetTrail !== returnFalse && (
+ {(
<IconButton
- tooltip="Show Linked Trail" //
- onPointerDown={this.ShowTargetTrail}
+ tooltip="Center on pin" //
+ onPointerDown={this.Center}
icon={<FontAwesomeIcon icon="taxi" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
)}
- {this.IsTargetToggler !== returnFalse && (
+ {/* {this.IsTargetToggler !== returnFalse && (
<Toggle
tooltip={'Make target visibility toggle on click'}
type={Type.PRIM}
@@ -384,10 +134,13 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
icon={<FontAwesomeIcon icon="thumbtack" />}
color={StrCast(Doc.UserDoc().userColor)}
/>
- )}
+ )} */}
</>
);
- return this.getElement(buttons);
+ return this.getElement(<div ref={MapAnchorMenu.top} style={{width:"100%", display:"flex"}}>
+ {buttons}
+ </div>
+ );
}
}