aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/ComparisonBox.scss15
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx92
-rw-r--r--src/client/views/nodes/FieldView.tsx1
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss6
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
5 files changed, 86 insertions, 44 deletions
diff --git a/src/client/views/nodes/ComparisonBox.scss b/src/client/views/nodes/ComparisonBox.scss
index b7307f3a3..8156c50f6 100644
--- a/src/client/views/nodes/ComparisonBox.scss
+++ b/src/client/views/nodes/ComparisonBox.scss
@@ -296,3 +296,18 @@
}
}
}
+.comparisonBox-bottomMenu {
+ transform-origin: bottom right;
+ width: max-content;
+ justify-content: space-between;
+ height: max-content;
+ position: absolute;
+ bottom: 0;
+ right: 2;
+ flex-direction: row-reverse;
+ display: flex;
+ cursor: pointer;
+ .comparisonBox-button {
+ padding-right: 8px;
+ }
+}
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index ef66c2b11..81e223028 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -68,7 +68,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
return (
<Tooltip title={<div className="dash-tooltip">flip</div>}>
<div
- className="formattedTextBox-alternateButton"
+ className="comparisonBox-alternateButton ccomparisonBox-button"
onPointerDown={e =>
setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, () => {
if (!this.revealOp || this.revealOp === 'flip') {
@@ -81,42 +81,74 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
color: this.revealOp === 'hover' ? 'black' : this._frontSide ? 'black' : 'white',
display: 'inline-block',
}}>
- <div key="alternate" className="formattedTextBox-flip">
- <FontAwesomeIcon icon="turn-up" size="1x" />
- </div>
+ <FontAwesomeIcon icon="turn-up" size="xl" />
</div>
</Tooltip>
);
}
+ _sideBtnWidth = 30;
+ /**
+ * How much the content of the view is being scaled based on its nesting and its fit-to-width settings
+ */
+ @computed get contentScaling() {
+ return this.ScreenToLocalBoxXf().Scale * (this._props.NativeDimScaling?.() ?? 1);
+ }
+ /**
+ * The maximum size a UI widget can be scaled so that it won't be bigger in screen pixels than its normal 35 pixel size.
+ */
+ @computed get maxWidgetScale() {
+ const maxWidgetSize = Math.min(this._sideBtnWidth * this.contentScaling, 0.25 * Math.min(NumCast(this.Document.width), NumCast(this.Document.height)));
+ return Math.max(maxWidgetSize / this._sideBtnWidth, 1);
+ }
+ /**
+ * How much to reactively scale a UI element so that it is as big as it can be (up to its normal 35pixel size) without being too big for the Doc content
+ */
+ @computed get uiBtnScaleTransform() {
+ return this.maxWidgetScale * Math.min(1, this.contentScaling);
+ }
+
@computed get flashcardMenu() {
return (
- <div>
- <Tooltip
- title={this._frontSide ? <div className="dash-tooltip">Flip to front side to use GPT</div> : <div className="dash-tooltip">Ask GPT to create an answer on the back side of the flashcard based on your question on the front</div>}>
- <div style={{ position: 'absolute', bottom: '3px', right: '50px', cursor: 'pointer' }} onPointerDown={() => (!this._frontSide ? this.findImageTags() : null)}>
- <FontAwesomeIcon icon="lightbulb" size="xl" />
- </div>
- </Tooltip>
- {DocCast(this.Document.embedContainer)?.type_collection === CollectionViewType.Carousel ? null : (
- <div>
- <Tooltip title={<div>Create a flashcard pile</div>}>
- <div style={{ position: 'absolute', bottom: '3px', right: '74px', cursor: 'pointer' }} onPointerDown={() => this.createFlashcardPile([this.Document], false)}>
- <FontAwesomeIcon icon="folder-plus" size="xl" />
- </div>
- </Tooltip>
- <Tooltip title={<div className="dash-tooltip">Create new flashcard stack based on text</div>}>
- <div style={{ position: 'absolute', bottom: '3px', right: '104px', cursor: 'pointer' }} onClick={() => this.gptFlashcardPile()}>
- <FontAwesomeIcon icon="layer-group" size="xl" />
+ <div className="comparisonBox-bottomMenu" style={{ transform: `scale(${this.uiBtnScaleTransform})` }}>
+ {this.overlayAlternateIcon}
+ {!this._props.isContentActive() ? null : (
+ <>
+ {' '}
+ {!this._frontSide ? null : (
+ <Tooltip
+ title={
+ <div className="dash-tooltip">{
+ !this._frontSide ? "Flip to front side to use GPT":
+ "Ask GPT to create an answer on the back side of the flashcard based on your question on the front"}
+ </div> // prettier-ignore
+ }>
+ <div className="comparisonBox-button" onPointerDown={() => (this._frontSide ? this.findImageTags() : null)}>
+ <FontAwesomeIcon icon="lightbulb" size="xl" />
+ </div>
+ </Tooltip>
+ )}
+ {DocCast(this.Document.embedContainer)?.type_collection === CollectionViewType.Carousel ? null : (
+ <>
+ <Tooltip title={<div>Create a flashcard pile</div>}>
+ <div className="comparisonBox-button" onPointerDown={() => this.createFlashcardPile([this.Document], false)}>
+ <FontAwesomeIcon icon="folder-plus" size="xl" />
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Create new flashcard stack based on text</div>}>
+ <div className="comparisonBox-button" onClick={this.gptFlashcardPile}>
+ <FontAwesomeIcon icon="layer-group" size="xl" />
+ </div>
+ </Tooltip>
+ </>
+ )}
+ <Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
+ <div className="comparisonBox-button" onClick={this.handleHover}>
+ <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="hand-point-up" size="xl" />
</div>
</Tooltip>
- </div>
+ </>
)}
- <Tooltip title={<div className="dash-tooltip">Hover to reveal</div>}>
- <div style={{ position: 'absolute', bottom: '3px', right: '25px', cursor: 'pointer' }} onClick={() => this.handleHover()}>
- <FontAwesomeIcon color={this.revealOp === 'hover' ? 'blue' : 'black'} icon="hand-point-up" size="xl" />
- </div>
- </Tooltip>
</div>
);
}
@@ -478,7 +510,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
this._loading = false;
return;
}
- this.flipFlashcard();
}
try {
console.log(queryText);
@@ -655,6 +686,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
childActiveFunc = () => this._childActive;
+ contentScreenToLocalXf = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1);
render() {
const clearButton = (which: string) => (
<Tooltip title={<div className="dash-tooltip">remove</div>}>
@@ -687,6 +719,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
removeDocument={whichSlot.endsWith('1') ? this.remDoc1 : this.remDoc2}
NativeWidth={returnZero}
NativeHeight={returnZero}
+ ScreenToLocalTransform={this.contentScreenToLocalXf}
isContentActive={this.childActiveFunc}
isDocumentActive={returnFalse}
dontSelect={returnTrue}
@@ -808,8 +841,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<ReactLoading type="spin" height={30} width={30} color={'blue'} />
</div>
) : null}
- {this._props.isContentActive() ? this.flashcardMenu : null}
- {this.overlayAlternateIcon}
+ {this.flashcardMenu}
</div>
);
}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 170966471..c81631baa 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -51,6 +51,7 @@ export interface FieldViewSharedProps {
LayoutTemplate?: () => Opt<Doc>;
renderDepth: number;
scriptContext?: unknown; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
+ screenXPadding?: () => number; // padding in screen space coordinates (used by text box to reflow around UI buttons in carouselView)
xPadding?: number;
yPadding?: number;
dontRegisterView?: boolean;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index d6f13d9ee..f1ae1151f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -101,12 +101,6 @@ audiotag:hover {
height: 22;
cursor: default;
}
-.formattedTextBox-flip {
- align-items: center;
- position: absolute;
- right: 2px;
- bottom: 4px;
-}
.formattedTextBox-outer {
position: relative;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c89737e1e..93153b453 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -763,10 +763,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
);
};
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
- const localDelta = this._props
- .ScreenToLocalTransform()
- .scale(this._props.NativeDimScaling?.() || 1)
- .transformDirection(delta[0], delta[1]);
+ const localDelta = this.DocumentView?.().screenToViewTransform().transformDirection(delta[0], delta[1]) ?? delta;
const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.layout_sidebarWidthPercent.replace('%', ''))) / 100;
const width = NumCast(this.layoutDoc._width) + localDelta[0];
this.layoutDoc._layout_sidebarWidthPercent = Math.max(0, (sidebarWidth + localDelta[0]) / width) * 100 + '%';
@@ -1264,7 +1261,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
this._cachedLinks = Doc.Links(this.Document);
this._disposers.breakupDictation = reaction(() => Doc.RecordingEvent, this.breakupDictation);
this._disposers.layout_autoHeight = reaction(
- () => ({ autoHeight: this.layout_autoHeight, fontSize: this.fontSize, css: this.Document[DocCss] }),
+ () => ({ autoHeight: this.layout_autoHeight, fontSize: this.fontSize, css: this.Document[DocCss], xMargin: this.Document.xMargin, yMargin: this.Document.yMargin }),
autoHeight => setTimeout(() => autoHeight && this.tryUpdateScrollHeight())
);
this._disposers.highlights = reaction(
@@ -2088,8 +2085,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB
const scale = this._props.NativeDimScaling?.() || 1;
const rounded = StrCast(this.layoutDoc.layout_borderRounding) === '100%' ? '-rounded' : '';
setTimeout(() => !this._props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide);
- const paddingX = Math.max(this._props.xPadding ?? 0, NumCast(this.layoutDoc._xMargin));
- const paddingY = Math.max(this._props.yPadding ?? 0, NumCast(this.layoutDoc._yMargin));
+
+ const scrSize = (which: number, view = this._props.docViewPath().slice(-which)[0]) =>
+ [view._props.PanelWidth() / view.screenToLocalScale(), view._props.PanelHeight() / view.screenToLocalScale()]; // prettier-ignore
+ const scrMargin = [Math.max(0, (scrSize(2)[0] - scrSize(1)[0]) / 2), Math.max(0, (scrSize(2)[1] - scrSize(1)[1]) / 2)];
+ const paddingX = Math.max(NumCast(this.layoutDoc._xMargin), this._props.xPadding ?? 0, 0, ((this._props.screenXPadding?.() ?? 0) - scrMargin[0]) * this.ScreenToLocalBoxXf().Scale);
+ const paddingY = Math.max(NumCast(this.layoutDoc._yMargin), 0, ((this._props.yPadding ?? 0) - scrMargin[1]) * this.ScreenToLocalBoxXf().Scale);
const styleFromLayout = styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._header_height}px' >
return styleFromLayout?.height === '0px' ? null : (
<div
@@ -2176,7 +2177,6 @@ Docs.Prototypes.TemplateMap.set(DocumentType.RTF, {
_layout_nativeDimEditable: true,
_layout_reflowVertical: true,
_layout_reflowHorizontal: true,
- _layout_noSidebar: true,
defaultDoubleClick: 'ignore',
systemIcon: 'BsFileEarmarkTextFill',
},