diff options
-rw-r--r-- | src/client/documents/Documents.ts | 1 | ||||
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 18 | ||||
-rw-r--r-- | src/client/util/SelectionManager.ts | 1 | ||||
-rw-r--r-- | src/client/views/MainView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionCardDeckView.scss | 27 | ||||
-rw-r--r-- | src/client/views/collections/CollectionCardDeckView.tsx | 111 | ||||
-rw-r--r-- | src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/global/globalScripts.ts | 21 |
8 files changed, 163 insertions, 21 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 77cc5f51e..df69e215a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -500,6 +500,7 @@ export class DocumentOptions { userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)'); cardSort?: STRt = new StrInfo('way cards are sorted in deck view'); + customSortCount?: NUMt = new NumInfo('number of custom sorts the user has created'); // card_sort_time?: BOOLt = new BoolInfo('whether sorting cards in deck view by time'); // card_sort_type?: BOOLt = new BoolInfo('whether sorting cards in deck view by type'); // card_sort_color?: BOOLt = new BoolInfo('whether sorting cards in deck view by color'); diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 767d6c635..59560dd78 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -9,7 +9,7 @@ import { PrefetchProxy } from "../../fields/Proxy"; import { RichTextField } from "../../fields/RichTextField"; import { listSpec } from "../../fields/Schema"; import { ScriptField } from "../../fields/ScriptField"; -import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types"; +import { Cast, DateCast, DocCast, StrCast, NumCast } from "../../fields/Types"; import { WebField, nullAudio } from "../../fields/URLField"; import { SetCachedGroups, SharingPermissions } from "../../fields/util"; import { GestureUtils } from "../../pen-gestures/GestureUtils"; @@ -34,6 +34,9 @@ import { SnappingManager } from "./SnappingManager"; import { UndoManager } from "./UndoManager"; import { LabelBox } from "../views/nodes/LabelBox"; import { ImageBox } from "../views/nodes/ImageBox"; +import { CollectionFreeFormView } from "../views/collections/collectionFreeForm"; +import { CollectionCardView } from "../views/collections/CollectionCardDeckView"; +import { SelectionManager } from "./SelectionManager"; interface Button { // DocumentOptions fields a button can set @@ -712,12 +715,23 @@ pie title Minerals in my tap water ] } static cardTools(): Button[] { + + + // if (view != undefined){ + // for (let i=0; i< NumCast(view.layoutDoc.customSortCount); i++){ + // customs.push( + // { title: "Custom " + i, icon:"robot", toolTip:"Custom sort option " + i, btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}} + // ) + + // } + // } return [ { title: "Time", icon:"hourglass-half", toolTip:"Sort by most recent document creation", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"time", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Type", icon:"eye", toolTip:"Sort by document type", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"docType", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Color", icon:"palette", toolTip:"Sort by document color", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"color", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, { title: "Links", icon:"link", toolTip:"Sort by its links", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"links", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, - + { title: "Create", icon:"plus", toolTip:"Create new custom groupings!", btnType: ButtonType.ToggleButton, expertMode: false, toolType:"custom", funcs: {}, scripts: { onClick: '{ return showFreeform(this.toolType, _readOnly_);}'}}, + // ...customs ] } diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 36b926053..d507e35ad 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -68,6 +68,7 @@ export class SelectionManager { public static IsSelected = (doc?: Doc) => Array.from(doc?.[DocViews] ?? []).some(dv => dv?.IsSelected); public static get Views() { return this.Instance.SelectedViews; } // prettier-ignore public static get SelectedSchemaDoc() { return this.Instance.SelectedSchemaDocument; } // prettier-ignore + public static get Docs() { return this.Instance.SelectedViews.map(dv => dv.Document).filter(doc => doc?._type_collection !== CollectionViewType.Docking); } // prettier-ignore } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index abdb5abef..a5882dcf3 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -526,7 +526,8 @@ export class MainView extends ObservableReactComponent<{}> { fa.faArrowsUpToLine, fa.faArrowsDownToLine, fa.faPalette, - fa.faHourglassHalf + fa.faHourglassHalf, + fa.faRobot ] ); } diff --git a/src/client/views/collections/CollectionCardDeckView.scss b/src/client/views/collections/CollectionCardDeckView.scss index aafc3b556..222a1d226 100644 --- a/src/client/views/collections/CollectionCardDeckView.scss +++ b/src/client/views/collections/CollectionCardDeckView.scss @@ -10,7 +10,7 @@ .card-wrapper { display: grid; - grid-template-columns: repeat(10, 1fr); /* Creates 10 columns, adjust number as needed */ + grid-template-columns: repeat(10, 1fr); // width: 100%; position: absolute; @@ -21,6 +21,31 @@ transition: transform 0.3s cubic-bezier(0.455, 0.03, 0.515, 0.955); } +.card-button-container { + display: flex; + padding: 3px; + // width: 300px; + background-color: rgb(218, 218, 218); /* Background color of the container */ + border-radius: 50px; /* Rounds the corners of the container */ + transform: translateY(-50px); + // box-shadow: 0 4px 8px rgba(0,0,0,0.1); /* Optional: Adds shadow for depth */ + align-items: center; /* Centers buttons vertically */ + justify-content: start;/* Centers buttons horizontally */ +} + +button { + width: 35px; + height: 35px; + border-radius: 50%; + background-color: $dark-gray; + // border-color: $medium-blue; + margin: 5px; // transform: translateY(-50px); +} + +// button:hover { +// transform: translateY(-50px); +// } + // .card-wrapper::after { // content: ""; // width: 100%; /* Forces wrapping */ diff --git a/src/client/views/collections/CollectionCardDeckView.tsx b/src/client/views/collections/CollectionCardDeckView.tsx index bda72b2d6..bf26ad4b5 100644 --- a/src/client/views/collections/CollectionCardDeckView.tsx +++ b/src/client/views/collections/CollectionCardDeckView.tsx @@ -37,7 +37,7 @@ export class CollectionCardView extends CollectionSubView() { translateHover = (index: number): number => { if (this.hoveredNodeIndex == index && !this.isSelected(index)) { - return -50 * this.fitContentScale; + return -50; } return 0; }; @@ -109,6 +109,10 @@ export class CollectionCardView extends CollectionSubView() { isContentActive = () => this._props.isSelected() || this._props.isContentActive() || this._props.isAnyChildContentActive(); isChildContentActive = () => (this.isContentActive() ? true : false); + + + + rotate = (amCards: number, index: number) => { // console.log(amCards + "wtf") const possRotate = -30 + index * (30 / ((amCards - (amCards % 2)) / 2)); @@ -163,7 +167,7 @@ export class CollectionCardView extends CollectionSubView() { // }; translateSelected = (index: number): number => { - if (this.isSelected(index)) { + // if (this.isSelected(index)) { const middleOfPanel = this._props.PanelWidth() / 2; const scaledNodeWidth = this.panelWidth() * 1.25; @@ -173,12 +177,12 @@ export class CollectionCardView extends CollectionSubView() { const scaledNodeCenter = nodeLeftEdge + scaledNodeWidth / 2; // Calculate the translation needed to align the scaled node's center with the panel's center - const translation = middleOfPanel - scaledNodeCenter; + const translation = middleOfPanel - scaledNodeCenter - scaledNodeWidth - (scaledNodeWidth /4); return translation; - } + // } - return 0; + // return 0; }; @computed get sortedDocsType() { @@ -197,15 +201,20 @@ export class CollectionCardView extends CollectionSubView() { return this.sort(sorted, "type", desc) case "color": return this.sort(sorted, "color", desc) - case "links": - console.log("hi") + // case "links": + // console.log("hi") - let links = LinkManager.Instance.getAllRelatedLinks(this.myChildLayoutPairs[0].layout) + // let links = LinkManager.Instance.getAllRelatedLinks(this.myChildLayoutPairs[0].layout) - console.log(links) + // console.log(links) // } + case "custom": + console.log("hiiiii") + return this.sort(sorted, "custom", desc) + + default: docs = this.myChildLayoutPairs return {docs} @@ -254,6 +263,14 @@ export class CollectionCardView extends CollectionSubView() { typeB = this.hexToHsv(StrCast(docB.layout.backgroundColor)) ?? ''; // If docB.type is undefined, use an empty string break + case "custom": + typeA = this.customGroupDictionary.get(docs.indexOf(docA)) ?? '' + // console.log(typeA + "A") + typeB = this.customGroupDictionary.get(docs.indexOf(docB)) ?? '' + // console.log(typeB + 'b') + break + + default: typeA = docA.layout.type ?? ''; // If docA.type is undefined, use an empty string typeB = docB.layout.type ?? ''; // If docB.type is undefined, use an empty string @@ -341,10 +358,24 @@ export class CollectionCardView extends CollectionSubView() { } return (10 - calcRowCards) * (this.panelWidth()/2) + } + + calculateTranslateY(isHovered: boolean, isSelected: boolean, realIndex: number, amCards: number, calcRowIndex: number) { + let trans = 0; + if (isHovered) { + trans += this.translateHover(realIndex); + } + + trans += this.translateY(amCards, calcRowIndex, realIndex); + + if (isSelected) { + trans = 50 * this.fitContentScale; + } + return trans } @computed get contentSorted() { @@ -357,6 +388,7 @@ export class CollectionCardView extends CollectionSubView() { const isHovered = this.hoveredNodeIndex === index; + const childPairIndex = this.myChildLayoutPairs.indexOf(childPair) const realIndex = this.sortedDocsType.docs.filter(d => !SelectionManager.IsSelected(d.layout)).indexOf(childPair); const calcRowIndex = this.overflowIndexCalc(realIndex) @@ -379,21 +411,72 @@ export class CollectionCardView extends CollectionSubView() { height: this.panelHeight(childPair.layout)(), transform: ` rotate(${!isSelected ? this.rotate(amCards, calcRowIndex) : 0}deg) - translateY(${isHovered ? this.translateHover(realIndex) : isSelected ? 50 * this.fitContentScale : this.translateY(amCards, calcRowIndex, realIndex)}px) - translateX(${isSelected ? (this._props.PanelWidth() / 2) * this.fitContentScale - this.childDocumentWidth : this.translateOverflowX(realIndex, amCards)}px) + translateY(${this.calculateTranslateY(isHovered, isSelected, realIndex, amCards, calcRowIndex)}px) + translateX(${isSelected ? this.translateSelected(calcRowIndex) : this.translateOverflowX(realIndex, amCards)}px) scale(${isSelected ? 1.25 : 1}) `, }} - onMouseEnter={() => this.setHoveredNodeIndex(index)}> + onMouseEnter={() => this.setHoveredNodeIndex(index)} + + > {this.displayDoc(childPair, childScreenToLocal)} - {/* <circle r="45" cx="50" cy="50" fill="red" /> */} + {this._props.Document.cardSort == 'custom' ? this.renderButtons(childPairIndex) : ''} </div> ); }); } + @observable amGroups = 0 + @observable customGroupDictionary = new Map< + number, number>(); + + + @action toggleButton(childPairIndex: number, buttonID: number) { + + this.customGroupDictionary.set(childPairIndex, buttonID); + } + + renderButtons (childPairIndex: number) { + const buttons = []; // Array to hold the button elements + + let amButtons = 4 + + if (this.amGroups > 4){ + amButtons = this.amGroups + } + + let activeButtonIndex = this.customGroupDictionary.get(childPairIndex) + + for (let i = 0; i < amButtons; i++) { + const isActive = activeButtonIndex == i + + buttons.push( + <button key={i} + style = {{backgroundColor: `${isActive ? "#4476f7" : "#323232"}`}} + onClick={() => this.toggleButton(childPairIndex, i)} > + </button>); + } + + const totalWidth = amButtons * 35 + (amButtons * 2* 5) + 6; + return ( + <div className="card-button-container" style={{ width: `${totalWidth}px` }}> + {buttons} + </div> + ); + } + + + + + + + + + + + // @computed get content() { @@ -450,7 +533,7 @@ export class CollectionCardView extends CollectionSubView() { let translate = 0 - if (this.inactiveDocs().length != this.myChildLayoutPairs.length) { + if (this.inactiveDocs().length != this.myChildLayoutPairs.length && this.inactiveDocs().length < 10) { translate += this.panelWidth() / 2; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 2d05b5490..11193f496 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -2010,4 +2010,4 @@ ScriptingGlobals.add(function datavizFromSchema(doc: Doc) { SchemaCSVPopUp.Instance.setVisible(true); } }); -}); +});
\ No newline at end of file diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts index 526315802..9056917fe 100644 --- a/src/client/views/global/globalScripts.ts +++ b/src/client/views/global/globalScripts.ts @@ -105,10 +105,12 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) { selected ? selected.CollectionFreeFormDocumentView?.float() : console.log('[FontIconBox.tsx] toggleOverlay failed'); }); -ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links', checkResult?: boolean, persist?: boolean) { + + +ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom' | 'create', checkResult?: boolean, persist?: boolean, customNumber?: number) { const selected = SelectionManager.Docs.lastElement(); // prettier-ignore - const map: Map<'flashcards' | 'center' |'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([ + const map: Map<'flashcards' | 'center' |'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll' | 'fitOnce' | 'time' | 'docType' | 'color' | 'links' | 'custom' | 'create', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc, dv:DocumentView) => void;}> = new Map([ ['grid', { checkResult: (doc:Doc) => BoolCast(doc?._freeform_backgroundGrid, false), setDoc: (doc:Doc,dv:DocumentView) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid, @@ -156,6 +158,21 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'center' | 'grid setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "links", }], + ['custom', { + checkResult: (doc:Doc) => StrCast(doc?.cardSort), + setDoc: (doc:Doc,dv:DocumentView) => doc.cardSort = "custom", + }], + + //in an ideal world lol + + + // ['create', { + // checkResult: (doc:Doc) => NumCast(doc?.customSortCount), + // setDoc: (doc:Doc,dv:DocumentView) => doc.customSortCount = NumCast(doc.customSortCount) + 1, + // }], + + + ]); if (checkResult) { |