aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-09-25 12:28:18 -0400
committerbobzel <zzzman@gmail.com>2024-09-25 12:28:18 -0400
commit5736a5025f5948131710662e0c8a80dfd90e51a0 (patch)
treedc9790dadfc67309be89934b21d54e37b536b5a5 /src
parentac7f34fa5ee67900714121b700768ebb18b874d1 (diff)
parentecd8ed4e41940089ec31d9601afaa0d5932c6401 (diff)
merged with master. updated filtering in carousel view.
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts2
-rw-r--r--src/client/views/DocumentDecorations.tsx11
-rw-r--r--src/client/views/collections/CollectionCardDeckView.tsx83
-rw-r--r--src/client/views/collections/CollectionCarousel3DView.tsx35
-rw-r--r--src/client/views/collections/CollectionCarouselView.scss3
-rw-r--r--src/client/views/collections/CollectionCarouselView.tsx66
-rw-r--r--src/client/views/global/globalScripts.ts2
-rw-r--r--src/client/views/linking/LinkMenuItem.tsx2
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx1
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx1
-rw-r--r--src/client/views/nodes/IconTagBox.tsx2
-rw-r--r--src/fields/Doc.ts6
12 files changed, 133 insertions, 81 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index e72acf93f..3e7921a08 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -706,8 +706,6 @@ pie title Minerals in my tap water
{ title: "Fit All", icon: "object-group", toolTip: "Fit Docs to View (double click to make sticky)",btnType: ButtonType.ToggleButton, ignoreClick:true, expertMode: false, toolType:"viewAll", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}', onDoubleClick: '{ return showFreeform(this.toolType, _readOnly_, true);}'}}, // Only when floating document is selected in freeform
{ title: "Clusters", icon: "braille", toolTip: "Show Doc Clusters", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"clusters", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
{ title: "Cards", icon: "brain", toolTip: "Flashcards", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
- { title: "Arrange", icon:"arrow-down-short-wide",toolTip:"Auto Arrange", btnType: ButtonType.ToggleButton, ignoreClick: true, expertMode: false, toolType:"arrange", funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
-
]
}
static textTools():Button[] {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c3bcfdcca..fc4b1f0af 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import { IconButton } from 'browndash-components';
-import { action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { FaUndo } from 'react-icons/fa';
@@ -36,6 +36,7 @@ import { ImageBox } from './nodes/ImageBox';
import { OpenWhere, OpenWhereMod } from './nodes/OpenWhere';
import { FormattedTextBox } from './nodes/formattedText/FormattedTextBox';
import { TagsView } from './TagsView';
+import { setTime } from 'react-datepicker/dist/date_utils';
interface DocumentDecorationsProps {
PanelWidth: number;
@@ -643,7 +644,9 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
return this._rotCenter;
}
+ @observable forceRender = 0;
render() {
+ this.forceRender;
const { b, r, x, y } = this.Bounds;
const seldocview = DocumentView.Selected().lastElement();
if (SnappingManager.IsDragging || r - x < 1 || x === Number.MAX_VALUE || !seldocview || this._hidden || isNaN(r) || isNaN(b) || isNaN(x) || isNaN(y)) {
@@ -656,6 +659,12 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
return null;
}
+ if (seldocview && !seldocview?.ContentDiv?.getBoundingClientRect().width) {
+ setTimeout(action(() => this.forceRender++));
+ return null;
+ }
+ console.log('Renderedr');
+
// sharing
const acl = GetEffectiveAcl(!this._showLayoutAcl ? Doc.GetProto(seldocview.Document) : seldocview.Document);
const docShareMode = HierarchyMapping.get(acl)!.name;
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx
index 8a9cc46f6..66014a1e0 100644
--- a/src/client/views/collections/CollectionCardDeckView.tsx
+++ b/src/client/views/collections/CollectionCardDeckView.tsx
@@ -1,4 +1,4 @@
-import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, ObservableMap, action, computed, makeObservable, observable, reaction, trace } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { ClientUtils, DashColor, returnFalse, returnZero } from '../../../ClientUtils';
@@ -46,8 +46,9 @@ export class CollectionCardView extends CollectionSubView() {
private _dropDisposer?: DragManager.DragDropDisposer;
private _disposers: { [key: string]: IReactionDisposer } = {};
private _textToDoc = new Map<string, Doc>();
+ private _dropped = false; // indicate when a card doc has just moved;
- @observable _forceChildXf = false;
+ @observable _forceChildXf = 0;
@observable _hoveredNodeIndex = -1;
@observable _docRefs = new ObservableMap<Doc, DocumentView>();
@observable _maxRowCount = 10;
@@ -99,6 +100,7 @@ export class CollectionCardView extends CollectionSubView() {
};
componentDidMount() {
+ this._props.setContentViewBox?.(this);
// Reaction to cardSort changes
this._disposers.sort = reaction(
() => GPTPopup.Instance.visible,
@@ -110,6 +112,17 @@ export class CollectionCardView extends CollectionSubView() {
}
}
);
+ // if card deck moves, then the child doc views are hidden so their screen to local transforms will return empty rectangles
+ // when inquired from the dom (below in childScreenToLocal). When the doc is actually renders, we need to act like the
+ // dash data just changed and trigger a React involidation with the correct data (read from the dom).
+ this._disposers.child = reaction(
+ () => [this.Document.x, this.Document.y],
+ () => {
+ if (!Array.from(this._docRefs.values()).every(dv => dv.ContentDiv?.getBoundingClientRect().width)) {
+ setTimeout(action(() => this._forceChildXf++));
+ }
+ }
+ );
}
componentWillUnmount() {
@@ -174,6 +187,7 @@ export class CollectionCardView extends CollectionSubView() {
inactiveDocs = () => this.childDocsWithoutLinks.filter(d => !DocumentView.SelectedDocs().includes(d));
childPanelWidth = () => NumCast(this.layoutDoc.childPanelWidth, this._props.PanelWidth() / 2);
+ childPanelHeight = () => this._props.PanelHeight() * this.fitContentScale;
onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive();
isChildContentActive = () => !!this.isContentActive();
@@ -265,14 +279,7 @@ export class CollectionCardView extends CollectionSubView() {
@action
onPointerMove = (x: number, y: number) => {
- this._docDraggedIndex = -1;
- if (DragManager.docsBeingDragged.length) {
- const newIndex = this.findCardDropIndex(x, y);
-
- if (newIndex !== this._docDraggedIndex && newIndex != -1) {
- this._docDraggedIndex = newIndex;
- }
- }
+ this._docDraggedIndex = DragManager.docsBeingDragged.length ? this.findCardDropIndex(x, y) : -1;
};
/**
@@ -304,6 +311,7 @@ export class CollectionCardView extends CollectionSubView() {
if (de.complete.docDragData.removeDocument?.(draggedDoc)) {
this.dataDoc[this.fieldKey] = new List<Doc>(sorted);
}
+ this._dropped = true;
}
e.stopPropagation();
return true;
@@ -338,7 +346,8 @@ export class CollectionCardView extends CollectionSubView() {
* @param isDesc
* @returns
*/
- sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => {
+ sort = (docsIn: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => {
+ const docs = docsIn.slice(); // need make new object list since sort() modifies the incoming list which confuses mobx caching
sortType &&
docs.sort((docA, docB) => {
const [typeA, typeB] = (() => {
@@ -362,21 +371,21 @@ export class CollectionCardView extends CollectionSubView() {
const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0;
return isDesc ? out : -out;
});
- if (dragIndex != -1) {
+ if (dragIndex !== -1) {
const draggedDoc = DragManager.docsBeingDragged[0];
const originalIndex = docs.findIndex(doc => doc === draggedDoc);
originalIndex !== -1 && docs.splice(originalIndex, 1);
- docs.splice(dragIndex, 0, draggedDoc);
+ draggedDoc && docs.splice(dragIndex, 0, draggedDoc);
}
- return [...docs]; // need to spread docs into a new object list since sort() modifies the incoming list which confuses mobx caching
+ return docs;
};
displayDoc = (doc: Doc, screenToLocalTransform: () => Transform) => (
<DocumentView
{...this._props}
- ref={action((r: DocumentView) => r?.ContentDiv && this._docRefs.set(doc, r))}
+ ref={action((r: DocumentView) => (!r?.ContentDiv ? this._docRefs.delete(doc) : this._docRefs.set(doc, r)))}
Document={doc}
NativeWidth={returnZero}
NativeHeight={returnZero}
@@ -385,11 +394,12 @@ export class CollectionCardView extends CollectionSubView() {
renderDepth={this._props.renderDepth + 1}
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
+ containerViewPath={this.childContainerViewPath}
ScreenToLocalTransform={screenToLocalTransform} // makes sure the box wrapper thing is in the right spot
isContentActive={emptyFunction}
isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
PanelWidth={this.childPanelWidth}
- PanelHeight={() => this._props.PanelHeight() * this.fitContentScale}
+ PanelHeight={this.childPanelHeight}
dontCenter="y" // Don't center it vertically, because the grid it's in is already doing that and we don't want to do it twice.
dragAction={(this.Document.childDragAction ?? this._props.childDragAction) as dropActionType}
showTags={true}
@@ -591,7 +601,10 @@ export class CollectionCardView extends CollectionSubView() {
const isSelected = view?.ComponentView?.isAnyChildContentActive?.() || view?.IsSelected ? true : false;
const childScreenToLocal = () => {
+ // need to explicitly trigger an invalidation since we're reading everything from the Dom
this._forceChildXf;
+ this._props.ScreenToLocalTransform();
+
const dref = this._docRefs.get(doc);
const { translateX, translateY, scale } = ClientUtils.GetScreenTransform(dref?.ContentDiv);
return new Transform(-translateX + (dref?.centeringX || 0) * scale,
@@ -606,25 +619,30 @@ export class CollectionCardView extends CollectionSubView() {
return (rowCenterIndex - indexInRow) * 100 - 50;
};
const aspect = NumCast(doc.height) / NumCast(doc.width, 1);
- const vscale = Math.min((this._props.PanelHeight() * 0.95 * this.fitContentScale) / (aspect * this.childPanelWidth()),
- (this._props.PanelHeight() - 80) / (aspect * (this._props.PanelWidth() / 10))); // prettier-ignore
+ const vscale = Math.max(1,Math.min((this._props.PanelHeight() * 0.95 * this.fitContentScale) / (aspect * this.childPanelWidth()),
+ (this._props.PanelHeight() - 80) / (aspect * (this._props.PanelWidth() / 10)))); // prettier-ignore
const hscale = Math.min(this.sortedDocs.length, this._maxRowCount) / 2; // bcz: hack - the grid is divided evenly into maxRowCount cells, so the max scaling would be maxRowCount -- but making things that wide is ugly, so cap it off at half the window size
return (
<div
key={doc[Id]}
className={`card-item${isSelected ? '-active' : anySelected ? '-inactive' : ''}`}
- onPointerUp={() => {
- if (DocumentView.SelectedDocs().includes(doc)) return;
- // this turns off documentDecorations during a transition, then turns them back on afterward.
- SnappingManager.SetIsResizing(doc[Id]);
- setTimeout(
- action(() => {
- SnappingManager.SetIsResizing(undefined);
- this._forceChildXf = !this._forceChildXf;
- }),
- 900
- );
- }}
+ onPointerUp={action(() => {
+ // if a card doc has just moved, or a card is selected and in front, then ignore this event
+ if (DocumentView.SelectedDocs().includes(doc) || this._dropped) {
+ this._dropped = false;
+ } else {
+ // otherwise, turn off documentDecorations becase we're in a selection transition and want to avoid artifacts.
+ // Turn them back on when the animation has completed and the render and backend structures are in synch
+ SnappingManager.SetIsResizing(doc[Id]);
+ setTimeout(
+ action(() => {
+ SnappingManager.SetIsResizing(undefined);
+ this._forceChildXf++;
+ }),
+ 600
+ );
+ }
+ })}
style={{
width: this.childPanelWidth(),
height: 'max-content',
@@ -633,7 +651,7 @@ export class CollectionCardView extends CollectionSubView() {
rotate(${!isSelected ? this.rotate(amCards, calcRowIndex) : 0}deg)
scale(${isSelected ? `${Math.min(hscale, vscale) * 100}%` : this._hoveredNodeIndex === index ? 1.05 : 1})`,
}} // prettier-ignore
- onMouseEnter={() => this.setHoveredNodeIndex(index)}>
+ onPointerEnter={() => !SnappingManager.IsDragging && this.setHoveredNodeIndex(index)}>
{this.displayDoc(doc, childScreenToLocal)}
</div>
);
@@ -647,7 +665,8 @@ export class CollectionCardView extends CollectionSubView() {
<div
className="collectionCardView-outer"
ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)}
- onPointerMove={e => this.onPointerMove(e.clientX, e.clientY)}
+ onPointerLeave={action(() => (this._docDraggedIndex = -1))}
+ onPointerMove={e => this.onPointerMove(...this._props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY))}
onDrop={this.onExternalDrop.bind(this)}
style={{
background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
diff --git a/src/client/views/collections/CollectionCarousel3DView.tsx b/src/client/views/collections/CollectionCarousel3DView.tsx
index 54cc02825..139aebb02 100644
--- a/src/client/views/collections/CollectionCarousel3DView.tsx
+++ b/src/client/views/collections/CollectionCarousel3DView.tsx
@@ -14,6 +14,7 @@ import { DocumentView } from '../nodes/DocumentView';
import { FocusViewOptions } from '../nodes/FocusViewOptions';
import './CollectionCarousel3DView.scss';
import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+import { Transform } from '../../util/Transform';
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { CAROUSEL3D_CENTER_SCALE, CAROUSEL3D_SIDE_SCALE, CAROUSEL3D_TOP } = require('../global/globalCssVariables.module.scss');
@@ -46,15 +47,32 @@ export class CollectionCarousel3DView extends CollectionSubView() {
}
centerScale = Number(CAROUSEL3D_CENTER_SCALE);
+ sideScale = Number(CAROUSEL3D_SIDE_SCALE);
panelWidth = () => this._props.PanelWidth() / 3;
- panelHeight = () => this._props.PanelHeight() * Number(CAROUSEL3D_SIDE_SCALE);
+ panelHeight = () => this._props.PanelHeight() * this.sideScale;
onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick);
isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive();
isChildContentActive = () => !!this.isContentActive();
- childScreenToLocal = () =>
- this._props // document's left is the panel shifted by the doc's index * panelWidth/#docs. But it scales by centerScale around its center, so it's left moves left by the distance of the left from the center (panelwidth/2) * the scale delta (centerScale-1)
- .ScreenToLocalTransform() // the top behaves the same way ecept it's shifted by the 'top' amount specified for the panel in css and then by the scale factor.
- .translate(-this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, -((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2)
+ childScreenLeftToLocal = () =>
+ this._props
+ .ScreenToLocalTransform()
+ .scale(this._props.NativeDimScaling?.() || 1)
+ .translate(-(this.panelWidth() - this.panelWidth() * this.sideScale) / 2, -(this.panelHeight() - this.panelHeight() * this.sideScale) / 2 - (Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight())
+ .scale(1 / this.sideScale);
+ childScreenRightToLocal = () =>
+ this._props
+ .ScreenToLocalTransform()
+ .scale(this._props.NativeDimScaling?.() || 1)
+ .translate(-2 * this.panelWidth() - (this.panelWidth() - this.panelWidth() * this.sideScale) / 2, -(this.panelHeight() - this.panelHeight() * this.sideScale) / 2 - (Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight())
+ .scale(1 / this.sideScale);
+ childCenterScreenToLocal = () =>
+ this._props
+ .ScreenToLocalTransform()
+ .scale(this._props.NativeDimScaling?.() || 1)
+ .translate(
+ -this.panelWidth() + ((this.centerScale - 1) * this.panelWidth()) / 2, // Focused Doc is shifted right by 1/3 panel width then left by increased size percent of center * 1/2 * panel width / 3
+ -((Number(CAROUSEL3D_TOP) / 100) * this._props.PanelHeight()) + ((this.centerScale - 1) * this.panelHeight()) / 2
+ ) // top is top margin % of panelHeight - increased size percent of center * panelHeight / 2
.scale(1 / this.centerScale);
focus = (anchor: Doc, options: FocusViewOptions): Opt<number> => {
@@ -66,9 +84,10 @@ export class CollectionCarousel3DView extends CollectionSubView() {
index !== -1 && (this.layoutDoc._carousel_index = index);
return undefined;
};
+
@computed get content() {
const currentIndex = NumCast(this.layoutDoc._carousel_index);
- const displayDoc = (childPair: { layout: Doc; data: Doc }) => (
+ const displayDoc = (childPair: { layout: Doc; data: Doc }, dxf: () => Transform) => (
<DocumentView
// eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
@@ -84,7 +103,7 @@ export class CollectionCarousel3DView extends CollectionSubView() {
LayoutTemplate={this._props.childLayoutTemplate}
LayoutTemplateString={this._props.childLayoutString}
focus={this.focus}
- ScreenToLocalTransform={this.childScreenToLocal}
+ ScreenToLocalTransform={dxf}
isContentActive={this.isChildContentActive}
isDocumentActive={this._props.childDocumentsActive?.() || this.Document._childDocumentsActive ? this._props.isDocumentActive : this.isContentActive}
PanelWidth={this.panelWidth}
@@ -94,7 +113,7 @@ export class CollectionCarousel3DView extends CollectionSubView() {
return this.carouselItems.map((childPair, index) => (
<div key={childPair.layout[Id]} className={`collectionCarousel3DView-item${index === currentIndex ? '-active' : ''} ${index}`} style={{ width: this.panelWidth() }}>
- {displayDoc(childPair)}
+ {displayDoc(childPair, index < currentIndex ? this.childScreenLeftToLocal : index === currentIndex ? this.childCenterScreenToLocal : this.childScreenRightToLocal)}
</div>
));
}
diff --git a/src/client/views/collections/CollectionCarouselView.scss b/src/client/views/collections/CollectionCarouselView.scss
index c40f471d6..af617254a 100644
--- a/src/client/views/collections/CollectionCarouselView.scss
+++ b/src/client/views/collections/CollectionCarouselView.scss
@@ -85,7 +85,6 @@
.carouselView-quiz {
position: relative;
display: flex;
- flex-direction: column;
height: 20px;
align-items: center;
margin: auto;
@@ -127,7 +126,7 @@
align-items: center;
display: flex;
top: 2px;
- right: 2px;
+ left: 2px;
width: 30;
border-radius: 5px;
color: rgba(255, 255, 255, 0.5);
diff --git a/src/client/views/collections/CollectionCarouselView.tsx b/src/client/views/collections/CollectionCarouselView.tsx
index e0cee2126..43ab4462b 100644
--- a/src/client/views/collections/CollectionCarouselView.tsx
+++ b/src/client/views/collections/CollectionCarouselView.tsx
@@ -63,7 +63,7 @@ export class CollectionCarouselView extends CollectionSubView() {
@computed get practiceMessage() {
const cardCount = this.carouselItems.length;
if (this.practiceMode) {
- if (!Doc.hasDocFilter(this.layoutDoc, 'tags', this.starField) && !cardCount) {
+ if (!Doc.hasDocFilter(this.layoutDoc, 'tags', Doc.FilterAny) && !cardCount) {
return 'Finished! Click here to view all flashcards.';
}
}
@@ -73,8 +73,8 @@ export class CollectionCarouselView extends CollectionSubView() {
@computed get filterMessage() {
const cardCount = this.carouselItems.length;
if (!this.practiceMessage) {
- if (Doc.hasDocFilter(this.layoutDoc, 'tags', this.starField) && !cardCount) {
- return 'No starred items. Click here to view all flash cards.';
+ if (Doc.hasDocFilter(this.layoutDoc, 'tags', Doc.FilterAny) && !cardCount) {
+ return 'No tagged items. Click here to view all flash cards.';
}
if (this.practiceMode) {
if (!cardCount) return 'No flashcards to show! Click here to leave practice mode';
@@ -168,6 +168,8 @@ export class CollectionCarouselView extends CollectionSubView() {
? false
: undefined;
+ childScreenToLocalXf = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1);
+
renderDoc = (doc: Doc, showCaptions: boolean, overlayFunc?: (r: DocumentView | null) => void) => {
return (
<DocumentView
@@ -177,8 +179,10 @@ export class CollectionCarouselView extends CollectionSubView() {
NativeWidth={returnZero}
NativeHeight={returnZero}
fitWidth={undefined}
+ showTags={true}
containerViewPath={this.childContainerViewPath}
setContentViewBox={undefined}
+ ScreenToLocalTransform={this.childScreenToLocalXf}
onDoubleClickScript={this.onContentDoubleClick}
onClickScript={this.onContentClick}
isDocumentActive={this._props.childDocumentsActive?.() ? this._props.isDocumentActive : this._props.isContentActive}
@@ -273,11 +277,6 @@ export class CollectionCarouselView extends CollectionSubView() {
return (
<>
<div>
- <Tooltip title="star">
- <div key="star" className="carouselView-star" onClick={this.toggleStar}>
- <FontAwesomeIcon icon="star" color={TagItem.docHasTag(this.carouselItems?.[this.carouselIndex], this.starField) ? 'yellow' : 'gray'} size="1x" />
- </div>
- </Tooltip>
{/* <Tooltip title="add new flashcard to pile">
<div key="add" className="carouselView-add" onClick={this.addFlashcard}>
<FontAwesomeIcon icon="plus" color={this.carouselItems?.[NumCast(this.layoutDoc._carousel_index)].layout[this.starField] ? 'yellow' : 'gray'} size="1x" />
@@ -310,12 +309,13 @@ export class CollectionCarouselView extends CollectionSubView() {
togglePracticeMode = (mode: practiceMode) => this.setPracticeMode(mode === this.practiceMode ? undefined : mode);
toggleFilterMode = () => Doc.setDocFilter(this.Document, 'tags', this.starField, 'check', true);
- setColor = (mode: practiceMode | cardMode, which: string) => { return which === mode ? 'white' : 'light gray'}; //prettier-ignore
+ setColor = (mode: practiceMode | cardMode, which: string) => (which === mode ? 'white' : 'light gray');
@computed get menu() {
const curDoc = this.carouselItems?.[this.carouselIndex];
return (
<div className="carouselView-menu">
+ {/* NOTE: this should really show the same filter as in the workspace View menu, not just something hardwire for 'star' */}
<Tooltip title={Doc.hasDocFilter(this.Document, 'tags', this.starField) ? 'Show all cards' : 'Show only starred cards'}>
<div key="back" className="carouselView-starFilter" onClick={e => this.toggleFilterMode()}>
<FontAwesomeIcon icon="filter" color={Doc.hasDocFilter(this.Document, 'tags', this.starField) ? 'white' : 'lightgray'} size="1x" />
@@ -339,27 +339,33 @@ export class CollectionCarouselView extends CollectionSubView() {
render() {
return (
- <div
- className="collectionCarouselView-outer"
- ref={this.createDashEventsTarget}
- style={{
- background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
- color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
- }}>
- {!this.practiceMessage && !this.filterMessage ? (
- this.content
- ) : (
- <p
- className="message"
- onClick={e => {
- if (this.filterMessage || this.practiceMessage) {
- this.setPracticeMode(undefined);
- Doc.setDocFilter(this.layoutDoc, 'tags', this.starField, 'remove');
- }
- }}>
- {this.filterMessage || this.practiceMessage}
- </p>
- )}
+ <div>
+ <div
+ className="collectionCarouselView-outer"
+ ref={this.createDashEventsTarget}
+ style={{
+ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) as string,
+ color: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) as string,
+ width: `calc(100% - ${NumCast(this.layoutDoc._xMargin)}px)`,
+ height: `calc(100% - ${NumCast(this.layoutDoc._yMargin)}px)`,
+ left: NumCast(this.layoutDoc._xMargin),
+ top: NumCast(this.layoutDoc._yMargin),
+ }}>
+ {!this.practiceMessage && !this.filterMessage ? (
+ this.content
+ ) : (
+ <p
+ className="message"
+ onClick={e => {
+ if (this.filterMessage || this.practiceMessage) {
+ this.setPracticeMode(undefined);
+ Doc.setDocFilter(this.layoutDoc, 'tags', Doc.FilterAny, 'remove');
+ }
+ }}>
+ {this.filterMessage || this.practiceMessage}
+ </p>
+ )}
+ </div>
{!this.Document._chromeHidden ? this.menu : null}
{!this.Document._chromeHidden ? this.buttons : null}
</div>
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 588073568..47cc07ce1 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -143,7 +143,7 @@ ScriptingGlobals.add(function showFreeform(attr: 'hcenter' | 'vcenter' | 'grid'
}
// prettier-ignore
- const map: Map<'flashcards' | 'hcenter' | 'vcenter' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'chat' | 'up' | 'down' | 'pile' | 'toggle-chat' | 'tag',
+ const map: Map<'flashcards' | 'hcenter' | 'vcenter' | 'grid' | 'snaplines' | 'clusters' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'chat' | 'up' | 'down' | 'pile' | 'toggle-chat' | 'tag',
{
waitForRender?: boolean;
checkResult: (doc: Doc) => boolean;
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index f54d8311d..b24fca8e2 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -90,7 +90,7 @@ export class LinkMenuItem extends ObservableReactComponent<LinkMenuItemProps> {
moveEv => {
const dragData = new DragManager.DocumentDragData([this._props.linkDoc], dropActionType.embed);
dragData.dropPropertiesToRemove = ['hidden'];
- DragManager.StartDocumentDrag([this._editRef.current!], dragData, moveEv.x, moveEv.y);
+ DragManager.StartDocumentDrag([this._editRef.current!], dragData, moveEv.x, moveEv.y, undefined, e => (this._props.linkDoc._layout_isSvg = true));
return true;
},
emptyFunction,
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 9d9535abd..5ca4d048e 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -638,6 +638,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<FieldViewProps>()
<DocumentView
// eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
+ showTags={undefined}
fitWidth={undefined}
NativeHeight={returnZero}
NativeWidth={returnZero}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index afc160297..9aa000ba7 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -129,6 +129,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
'childContentPointerEvents',
'LayoutTemplateString',
'LayoutTemplate',
+ 'showTags',
'layoutFieldKey',
'dontCenter',
'DataTransition',
diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx
index 8faf8ffa5..ddabd61e1 100644
--- a/src/client/views/nodes/IconTagBox.tsx
+++ b/src/client/views/nodes/IconTagBox.tsx
@@ -67,7 +67,7 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> {
render() {
const buttons = Doc.MyFilterHotKeys
.map(key => ({ key, tag: StrCast(key.toolType) }))
- .filter(({ tag }) => this._props.IsEditing || TagItem.docHasTag(this.View.Document, tag) || (DocumentView.Selected.length === 1 && this.View.IsSelected))
+ .filter(({ tag }) => this._props.IsEditing || TagItem.docHasTag(this.View.Document, tag) || (DocumentView.Selected().length === 1 && this.View.IsSelected))
.map(({ key, tag }) => (
<Tooltip key={tag} title={<div className="dash-tooltip">Click to add/remove this card from the {tag} group</div>}>
<button
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 0dd9a9fc8..0f1609711 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1371,7 +1371,7 @@ export namespace Doc {
if (!container) return;
const filterField = '_' + (fieldPrefix ? fieldPrefix + '_' : '') + 'childFilters';
const childFilters = StrListCast(container[filterField]);
- return childFilters.some(filter => filter.split(FilterSep)[0] === key && (value === undefined || filter.split(FilterSep)[1] === value));
+ return childFilters.some(filter => filter.split(FilterSep)[0] === key && (value === undefined || value === Doc.FilterAny || filter.split(FilterSep)[1] === value));
}
// filters document in a container collection:
@@ -1384,8 +1384,8 @@ export namespace Doc {
runInAction(() => {
for (let i = 0; i < childFilters.length; i++) {
const fields = childFilters[i].split(FilterSep); // split key:value:modifier
- if (fields[0] === key && (fields[1] === value?.toString() || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) {
- if (fields[2] === modifiers && modifiers && fields[1] === value?.toString()) {
+ if (fields[0] === key && (fields[1] === value?.toString() || value === Doc.FilterAny || modifiers === 'match' || (fields[2] === 'match' && modifiers === 'remove'))) {
+ if (fields[2] === modifiers && modifiers && (fields[1] === value?.toString() || value === Doc.FilterAny)) {
// eslint-disable-next-line no-param-reassign
if (toggle) modifiers = 'remove';
else return;