diff options
| author | bobzel <zzzman@gmail.com> | 2024-09-18 20:46:38 -0400 |
|---|---|---|
| committer | bobzel <zzzman@gmail.com> | 2024-09-18 20:46:38 -0400 |
| commit | d95730d904612640184ca6fdc00864b0c81b0c0c (patch) | |
| tree | 29176e9a4ea75fca8a146e8a49774fd1b1fb3fc9 /src/client/views/collections/CollectionCardDeckView.tsx | |
| parent | cf13604b06b8d8cf37f6e69f19a4092bf2c29d65 (diff) | |
lots of changes to fix dragging cards, integrate iconTags with other tags, sizing docs when selected to fit window,
Diffstat (limited to 'src/client/views/collections/CollectionCardDeckView.tsx')
| -rw-r--r-- | src/client/views/collections/CollectionCardDeckView.tsx | 152 |
1 files changed, 89 insertions, 63 deletions
diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index fced9fd37..1952cc707 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -21,6 +21,7 @@ import { DocumentView } from '../nodes/DocumentView'; import { GPTPopup, GPTPopupMode } from '../pdf/GPTPopup/GPTPopup'; import './CollectionCardDeckView.scss'; import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView'; +import { List } from '../../../fields/List'; enum cardSortings { Time = 'time', @@ -42,7 +43,6 @@ enum cardSortings { @observer export class CollectionCardView extends CollectionSubView() { private _dropDisposer?: DragManager.DragDropDisposer; - private _childDocumentWidth = 600; // target width of a Doc... private _disposers: { [key: string]: IReactionDisposer } = {}; private _textToDoc = new Map<string, Doc>(); @@ -77,6 +77,12 @@ export class CollectionCardView extends CollectionSubView() { this.setRegenerateCallback(); } + protected createDashEventsTarget = (ele: HTMLDivElement | null) => { + this._dropDisposer?.(); + if (ele) { + this._dropDisposer = DragManager.MakeDropTarget(ele, this.onInternalDrop.bind(this), this.layoutDoc); + } + }; /** * Callback to ensure gpt's text versions of the child docs are updated */ @@ -94,10 +100,7 @@ export class CollectionCardView extends CollectionSubView() { }; componentDidMount() { - this.Document.childFilters_boolean = 'OR'; - this.childDocsWithoutLinks.forEach(c => { - c[DocData].showIconTags = true; - }); + this.Document.childFilters_boolean = 'OR'; // bcz: really shouldn't be assigning to fields from within didMount -- this should be a default/override beahavior somehow // Reaction to cardSort changes this._disposers.sort = reaction( @@ -117,28 +120,24 @@ export class CollectionCardView extends CollectionSubView() { this._dropDisposer?.(); } - @computed get cardSort_customField() { - return StrCast(this.Document.cardSort_customField) as 'chat' | 'star' | 'idea' | 'like'; - } - @computed get cardSort() { return StrCast(this.Document.cardSort) as cardSortings; } /** - * how much to scale down the contents of the view so that everything will fit + * The child documents to be rendered-- either all of them except the Links or the docs in the currently active + * custom group */ - @computed get fitContentScale() { - const length = Math.min(this.childDocsWithoutLinks.length, this._maxRowCount); - return (this._childDocumentWidth * length) / this._props.PanelWidth(); + @computed get childDocsWithoutLinks() { + return (this.childDocList as Doc[]).filter(l => l.type !== DocumentType.LINK); } /** - * The child documents to be rendered-- either all of them except the Links or the docs in the currently active - * custom group + * how much to scale down the contents of the view so that everything will fit */ - @computed get childDocsWithoutLinks() { - return this.childDocs.filter(l => l.type !== DocumentType.LINK); + @computed get fitContentScale() { + const length = Math.min(this.childDocsWithoutLinks.length, this._maxRowCount); + return (this.childPanelWidth() * length) / this._props.PanelWidth(); } /** @@ -154,7 +153,7 @@ export class CollectionCardView extends CollectionSubView() { * Number of rows of cards to be rendered */ @computed get numRows() { - return Math.ceil(this.sortedDocs.length / 10); + return Math.ceil(this.sortedDocs.length / this._maxRowCount); } @action @@ -177,8 +176,7 @@ export class CollectionCardView extends CollectionSubView() { */ inactiveDocs = () => this.childDocsWithoutLinks.filter(d => !DocumentView.SelectedDocs().includes(d)); - panelWidth = () => this._childDocumentWidth; - panelHeight = (layout: Doc) => () => (this.panelWidth() * NumCast(layout._height)) / NumCast(layout._width); + childPanelWidth = () => NumCast(this.layoutDoc.childPanelWidth, this._props.PanelWidth() / 2); onChildDoubleClick = () => ScriptCast(this.layoutDoc.onChildDoubleClick); isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => !!this.isContentActive(); @@ -245,6 +243,7 @@ export class CollectionCardView extends CollectionSubView() { const currRow = Math.floor((mouseY - 100) / rowHeight); //rows start at 0 if (adjustedX < 0) { + console.log('DROP INDEX NO '); return 0; // Before the first column } @@ -259,6 +258,7 @@ export class CollectionCardView extends CollectionSubView() { index = Math.floor(adjustedX / cardWidth) + currRow * this._maxRowCount; } + console.log('DROP INDEX = ' + index); return index; }; @@ -281,20 +281,41 @@ export class CollectionCardView extends CollectionSubView() { }; /** + * Handles external drop of images/PDFs etc from outside Dash. + */ + onExternalDrop = async (e: React.DragEvent): Promise<void> => { + super.onExternalDrop(e, {}); + }; + + /** * Resets all the doc dragging vairables once a card is dropped * @param e * @param de drop event * @returns true if a card has been dropped, falls if not */ - onInternalDrop = undoable((e: Event, de: DragManager.DropEvent) => { - if (de.complete.docDragData) { - this._isACardBeingDragged = false; - this._docDraggedIndex = -1; - e.stopPropagation(); - return true; - } - return false; - }, ''); + onInternalDrop = undoable( + action((e: Event, de: DragManager.DropEvent) => { + if (de.complete.docDragData) { + this._isACardBeingDragged = false; + const dragIndex = this._docDraggedIndex; + if (dragIndex > -1) { + this._docDraggedIndex = -1; + const draggedDoc = DragManager.docsBeingDragged[0]; + const sorted = this.sortedDocs; + const originalIndex = sorted.findIndex(doc => doc === draggedDoc); + + this.Document.cardSort = ''; + sorted.splice(originalIndex, 1); + sorted.splice(dragIndex, 0, draggedDoc); + this.dataDoc[this.fieldKey] = new List<Doc>(sorted); + } + e.stopPropagation(); + return true; + } + return false; + }), + '' + ); @computed get sortedDocs() { return this.sort(this.childDocsWithoutLinks, this.cardSort, BoolCast(this.Document.cardSort_isDesc), this._docDraggedIndex); @@ -348,28 +369,29 @@ export class CollectionCardView extends CollectionSubView() { * @returns */ sort = (docs: Doc[], sortType: cardSortings, isDesc: boolean, dragIndex: number) => { - docs.sort((docA, docB) => { - const [typeA, typeB] = (() => { - switch (sortType) { - case cardSortings.Time: - return [DateCast(docA.author_date)?.date ?? Date.now(), DateCast(docB.author_date)?.date ?? Date.now()]; - case cardSortings.Color: { - const d1 = DashColor(StrCast(docA.backgroundColor)); - const d2 = DashColor(StrCast(docB.backgroundColor)); - return [d1.hsv().hue(), d2.hsv().hue()]; + sortType && + docs.sort((docA, docB) => { + const [typeA, typeB] = (() => { + switch (sortType) { + case cardSortings.Time: + return [DateCast(docA.author_date)?.date ?? Date.now(), DateCast(docB.author_date)?.date ?? Date.now()]; + case cardSortings.Color: { + const d1 = DashColor(StrCast(docA.backgroundColor)); + const d2 = DashColor(StrCast(docB.backgroundColor)); + return [d1.hsv().hue(), d2.hsv().hue()]; + } + case cardSortings.Tag: + return [this.tagValue(docA) ?? 9999, this.tagValue(docB) ?? 9999]; + case cardSortings.Chat: + return [NumCast(docA.chatIndex) ?? 9999, NumCast(docB.chatIndex) ?? 9999]; + default: + return [StrCast(docA.type), StrCast(docB.type)]; } - case cardSortings.Tag: - return [this.tagValue(docA) ?? 9999, this.tagValue(docB) ?? 9999]; - case cardSortings.Chat: - return [NumCast(docA.chatIndex) ?? 9999, NumCast(docB.chatIndex) ?? 9999]; - default: - return [StrCast(docA.type), StrCast(docB.type)]; - } - })(); + })(); - const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0; - return isDesc ? out : -out; - }); + const out = typeA < typeB ? -1 : typeA > typeB ? 1 : 0; + return isDesc ? out : -out; + }); if (dragIndex != -1) { const draggedDoc = DragManager.docsBeingDragged[0]; const originalIndex = docs.findIndex(doc => doc === draggedDoc); @@ -396,9 +418,11 @@ export class CollectionCardView extends CollectionSubView() { 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.panelWidth} - PanelHeight={this.panelHeight(doc)} + PanelWidth={this.childPanelWidth} + PanelHeight={() => this._props.PanelHeight() * this.fitContentScale} + 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} dontHideOnDrag /> ); @@ -415,18 +439,18 @@ export class CollectionCardView extends CollectionSubView() { // 13 - 3 = 10 const totalCards = this.sortedDocs.length; // if 9 or less - if (index < totalCards - (totalCards % 10)) { + if (index < totalCards - (totalCards % this._maxRowCount)) { return this._maxRowCount; } // (3) - return totalCards % 10; + return totalCards % this._maxRowCount; }; /** * Determines the index a card is in in a row * @param realIndex * @returns */ - overflowIndexCalc = (realIndex: number) => realIndex % 10; + overflowIndexCalc = (realIndex: number) => realIndex % this._maxRowCount; /** * Translates the cards in the second rows and beyond over to the right * @param realIndex @@ -434,7 +458,7 @@ export class CollectionCardView extends CollectionSubView() { * @param calcRowCards * @returns */ - translateOverflowX = (realIndex: number, calcRowCards: number) => (realIndex < this._maxRowCount ? 0 : (10 - calcRowCards) * (this.panelWidth() / 2)); + translateOverflowX = (realIndex: number, calcRowCards: number) => (realIndex < this._maxRowCount ? 0 : (this._maxRowCount - calcRowCards) * (this.childPanelWidth() / 2)); /** * Determines how far to translate a card in the y direction depending on its index, whether or not its being hovered, or if it's selected @@ -613,6 +637,9 @@ export class CollectionCardView extends CollectionSubView() { const rowCenterIndex = Math.min(this._maxRowCount, sortedDocs.length - rowIndex * this._maxRowCount) / 2; return (rowCenterIndex - indexInRow) * 100 - 50; }; + const aspect = NumCast(doc.height) / NumCast(doc.width, 1); + const vscale = ((this._props.PanelHeight() * .95) * this.fitContentScale) / (aspect * this.childPanelWidth()); + const hscale = 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]} @@ -629,13 +656,13 @@ export class CollectionCardView extends CollectionSubView() { ); }} style={{ - width: this.panelWidth(), + width: this.childPanelWidth(), height: 'max-content', transform: `translateY(${this.calculateTranslateY(this._hoveredNodeIndex === index, isSelected, realIndex, amCards, calcRowIndex)}px) - translateX(calc(${(isSelected ? translateIfSelected() : 0) + '% + ' + this.translateOverflowX(realIndex, amCards) + 'px'})) + translateX(calc(${isSelected ? translateIfSelected() : 0}% + ${this.translateOverflowX(realIndex, amCards)}px)) rotate(${!isSelected ? this.rotate(amCards, calcRowIndex) : 0}deg) - scale(${isSelected ? 2 : this._hoveredNodeIndex === index ? 1.05 : 1})`, - }} + scale(${isSelected ? `${Math.min(hscale, vscale) * 100}%` : this._hoveredNodeIndex === index ? 1.05 : 1})`, + }} // prettier-ignore onMouseEnter={() => this.setHoveredNodeIndex(index)}> {this.displayDoc(doc, childScreenToLocal)} </div> @@ -645,14 +672,13 @@ export class CollectionCardView extends CollectionSubView() { render() { const isEmpty = this.childDocsWithoutLinks.length === 0; - const transformValue = `scale(${1 / this.fitContentScale})`; - const heightValue = `${100 * this.fitContentScale}%`; return ( <div onPointerMove={e => this.onPointerMove(e)} className="collectionCardView-outer" ref={(ele: HTMLDivElement | null) => this.createDashEventsTarget(ele)} + onDrop={this.onExternalDrop.bind(this)} 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, @@ -660,8 +686,8 @@ export class CollectionCardView extends CollectionSubView() { <div className="card-wrapper" style={{ - ...(!isEmpty && { transform: transformValue }), - ...(!isEmpty && { height: heightValue }), + ...(!isEmpty && { transform: `scale(${1 / this.fitContentScale})` }), + ...(!isEmpty && { height: `${100 * this.fitContentScale}%` }), gridAutoRows: `${100 / this.numRows}%`, }} onMouseLeave={() => this.setHoveredNodeIndex(-1)}> |
