aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json6
-rw-r--r--package.json1
-rw-r--r--src/client/views/collections/collectionFreeForm/ImageLabelBox.scss23
-rw-r--r--src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx60
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx9
6 files changed, 86 insertions, 15 deletions
diff --git a/package-lock.json b/package-lock.json
index 9b3904ff7..6cd2ab605 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -136,6 +136,7 @@
"js-datepicker": "^5.18.2",
"jsonschema": "^1.4.1",
"jszip": "^3.10.1",
+ "ldrs": "^1.0.2",
"lodash": "^4.17.21",
"mapbox-gl": "^3.0.1",
"markdown-it": "^14.1.0",
@@ -23613,6 +23614,11 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/ldrs": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/ldrs/-/ldrs-1.0.2.tgz",
+ "integrity": "sha512-sYJmivdkIiHrUEqTrEWccBoLdaENpzbzkABI5rk8rRxTXrg9i2xVuDvUUuhOhJY3RmQyaoxs046pM1DCRdcIpg=="
+ },
"node_modules/leac": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
diff --git a/package.json b/package.json
index ed05c4f45..bbd2a4c46 100644
--- a/package.json
+++ b/package.json
@@ -221,6 +221,7 @@
"js-datepicker": "^5.18.2",
"jsonschema": "^1.4.1",
"jszip": "^3.10.1",
+ "ldrs": "^1.0.2",
"lodash": "^4.17.21",
"mapbox-gl": "^3.0.1",
"markdown-it": "^14.1.0",
diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss
index d0c12814c..5f2ce4e14 100644
--- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss
+++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.scss
@@ -1,3 +1,18 @@
+.image-box-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ font-size: 10px;
+ line-height: 1;
+ background: none;
+ z-index: 1000;
+ padding: 0px;
+ overflow: auto;
+ cursor: default;
+}
+
.image-label-list {
display: flex;
flex-direction: column;
@@ -16,6 +31,7 @@
text-align: center; // Centers the text of the paragraph
font-size: large;
vertical-align: middle;
+ margin-left: 10px;
}
.IconButton {
@@ -24,3 +40,10 @@
}
}
}
+
+.image-information {
+ display: flex;
+ flex-direction: column;
+ //align-items: center;
+ width: 100%;
+}
diff --git a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
index 1c0035f0d..83ae69cfb 100644
--- a/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
+++ b/src/client/views/collections/collectionFreeForm/ImageLabelBox.tsx
@@ -12,6 +12,11 @@ import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
import './ImageLabelBox.scss';
import { MainView } from '../../MainView';
import { MarqueeView } from './MarqueeView';
+import 'ldrs/ring';
+import { ring } from 'ldrs';
+import { SnappingManager } from '../../../util/SnappingManager';
+import { ImageCast } from '../../../../fields/Types';
+import { DocData } from '../../../../fields/DocSymbols';
@observer
export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
@@ -24,12 +29,14 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable _loading: boolean = true;
@observable _currentLabel: string = '';
@observable _labelGroups: string[] = [];
+ @observable _selectedImages: Doc[] = [];
+ @observable _displayImageInformation: boolean = false;
constructor(props: any) {
super(props);
makeObservable(this);
ImageLabelBox.Instance = this;
-
+ ring.register();
console.log('Image Box Has Been Initialized');
}
@@ -77,14 +84,32 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._loading = false;
};
+ @action
+ setSelectedImages = (selected: Doc[]) => {
+ this._selectedImages = selected;
+ };
+
render() {
if (this._loading) {
- return <div className="searchBox-container">Loading...</div>;
+ return (
+ <div className="image-box-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}>
+ <l-ring size="60" color="white" />
+ </div>
+ );
}
return (
- <div className="searchBox-container">
- <div className="searchBox-bar">
+ <div className="searchBox-container" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}>
+ <div className="searchBox-bar" style={{ pointerEvents: 'all', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}>
+ <IconButton
+ tooltip={'See image information'}
+ onPointerDown={() => {
+ this._displayImageInformation = !this._displayImageInformation;
+ }}
+ icon={this._displayImageInformation ? <FontAwesomeIcon icon="caret-up" /> : <FontAwesomeIcon icon="caret-down" />}
+ color={MarqueeOptionsMenu.Instance.userColor}
+ style={{ width: '19px' }}
+ />
<input
defaultValue=""
autoComplete="off"
@@ -93,7 +118,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
// e.stopPropagation();
// }}
type="text"
- placeholder="Input a group to put images into..."
+ placeholder="Input labels for image groupings..."
aria-label="label-input"
id="new-label"
className="searchBox-input"
@@ -101,7 +126,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
ref={this._inputRef}
/>
<IconButton
- tooltip={'Add group'}
+ tooltip={'Add a label'}
onPointerDown={() => {
const input = document.getElementById('new-label') as HTMLInputElement;
const newLabel = input.value;
@@ -113,11 +138,7 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
color={MarqueeOptionsMenu.Instance.userColor}
style={{ width: '19px' }}
/>
- {this._labelGroups.length > 0 ? (
- <IconButton tooltip={'Group Images'} onPointerDown={this.groupImages} icon={<FontAwesomeIcon icon="object-group" />} color={MarqueeOptionsMenu.Instance.userColor} style={{ width: '19px' }} />
- ) : (
- <div></div>
- )}
+ {this._labelGroups.length > 0 ? <IconButton tooltip={'Group Images'} onPointerDown={this.groupImages} icon={<FontAwesomeIcon icon="object-group" />} color={Colors.MEDIUM_BLUE} style={{ width: '19px' }} /> : <div></div>}
</div>
<div>
<div className="image-label-list">
@@ -139,6 +160,23 @@ export class ImageLabelBox extends ViewBoxBaseComponent<FieldViewProps>() {
})}
</div>
</div>
+ {this._displayImageInformation ? (
+ <div className="image-information">
+ {this._selectedImages.map(doc => {
+ const [name, type] = ImageCast(doc[Doc.LayoutFieldKey(doc)]).url.href.split('.');
+ return (
+ <div>
+ <img src={`${name}_o.${type}`}></img>
+ {(doc[DocData].data_labels as string).split('\n').map(label => {
+ return <div className="image-label">{label}</div>;
+ })}
+ </div>
+ );
+ })}
+ </div>
+ ) : (
+ <div></div>
+ )}
</div>
);
}
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index f02cd9d45..b94a22d04 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -39,7 +39,7 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
<IconButton tooltip="Summarize Documents" onPointerDown={this.summarize} icon={<FontAwesomeIcon icon="compress-arrows-alt" />} color={this.userColor} />
<IconButton tooltip="Delete Documents" onPointerDown={this.delete} icon={<FontAwesomeIcon icon="trash-alt" />} color={this.userColor} />
<IconButton tooltip="Pin selected region" onPointerDown={this.pinWithView} icon={<FontAwesomeIcon icon="map-pin" />} color={this.userColor} />
- <IconButton tooltip="Classify Images" onPointerDown={this.classifyImages} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
+ <IconButton tooltip="Classify and Sort Images" onPointerDown={this.classifyImages} icon={<FontAwesomeIcon icon="object-group" />} color={this.userColor} />
</>
);
return this.getElement(buttons);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index bb5a2a66e..f98883bff 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -456,6 +456,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
}
this._selectedDocs = this.marqueeSelect(false, DocumentType.IMG); // Get the selected documents from the marquee select.
+ ImageLabelBox.Instance!.setSelectedImages(this._selectedDocs);
const imageInfos = this._selectedDocs.map(async doc => {
if (!doc[DocData].data_labels) {
@@ -478,7 +479,7 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
}); // Add the labels as fields to each image.
ImageLabelBox.Instance!.endLoading();
- console.log('Complete!');
+ console.log(this._selectedDocs);
});
/**
@@ -502,8 +503,10 @@ export class MarqueeView extends ObservableReactComponent<SubCollectionViewProps
{ label: '', similarityScore: 0, }); // prettier-ignore
doc[DocData].data_label = mostSimilarLabelCollect; // The label most similar to the image's contents.
});
- this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view.
- this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'.
+ if (this._selectedDocs) {
+ this._props.Document._type_collection = CollectionViewType.Time; // Change the collection view to a Time view.
+ this._props.Document.pivotField = 'data_label'; // Sets the pivot to be the 'data_label'.
+ }
});
@undoBatch