diff options
author | Sam Wilkins <samwilkins333@gmail.com> | 2019-07-17 13:03:26 -0400 |
---|---|---|
committer | Sam Wilkins <samwilkins333@gmail.com> | 2019-07-17 13:03:26 -0400 |
commit | df389f16a7730081b2afff5e6c03022f5da79b10 (patch) | |
tree | 89689212399ea80ae99cccfb5e0a858f45e82ee4 | |
parent | 2e745fca1bf2cea9fe3518bf85590ad2d871afe0 (diff) | |
parent | 2f9aadfce9a1d8c26457bc56b1b095ae625be77b (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | src/client/views/nodes/ImageBox.tsx | 67 | ||||
-rw-r--r-- | src/client/views/search/SearchBox.tsx | 2 | ||||
-rw-r--r-- | src/client/views/search/SearchItem.tsx | 4 |
4 files changed, 66 insertions, 8 deletions
diff --git a/package.json b/package.json index 7407a719f..2cec44473 100644 --- a/package.json +++ b/package.json @@ -129,6 +129,7 @@ "font-awesome": "^4.7.0", "formidable": "^1.2.1", "golden-layout": "^1.5.9", + "howler": "^2.1.2", "html-to-image": "^0.1.0", "i": "^0.3.6", "image-data-uri": "^2.0.0", diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx index 4c5ad7a7d..a3e098fd8 100644 --- a/src/client/views/nodes/ImageBox.tsx +++ b/src/client/views/nodes/ImageBox.tsx @@ -1,6 +1,6 @@ import { library } from '@fortawesome/fontawesome-svg-core'; -import { faImage } from '@fortawesome/free-solid-svg-icons'; -import { action, observable, computed } from 'mobx'; +import { faImage, faFileAudio } from '@fortawesome/free-solid-svg-icons'; +import { action, observable, computed, runInAction } from 'mobx'; import { observer } from "mobx-react"; import Lightbox from 'react-image-lightbox'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app @@ -8,7 +8,7 @@ import { Doc, HeightSym, WidthSym, DocListCast } from '../../../new_fields/Doc'; import { List } from '../../../new_fields/List'; import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema'; import { Cast, FieldValue, NumCast, StrCast, BoolCast } from '../../../new_fields/Types'; -import { ImageField } from '../../../new_fields/URLField'; +import { ImageField, AudioField } from '../../../new_fields/URLField'; import { Utils } from '../../../Utils'; import { DragManager } from '../../util/DragManager'; import { undoBatch } from '../../util/UndoManager'; @@ -23,11 +23,15 @@ import React = require("react"); import { RouteStore } from '../../../server/RouteStore'; import { Docs } from '../../documents/Documents'; import { DocServer } from '../../DocServer'; +import { Font } from '@react-pdf/renderer'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; var requestImageSize = require('../../util/request-image-size'); var path = require('path'); +const { Howl, Howler } = require('howler'); library.add(faImage); +library.add(faFileAudio); export const pageSchema = createSchema({ @@ -177,10 +181,11 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD audioAnnos.push(audioDoc); } }; + runInAction(() => self._audioState = 2); recorder.start(); setTimeout(() => { recorder.stop(); - + runInAction(() => self._audioState = 0); gumStream.getAudioTracks()[0].stop(); }, 5000); }); @@ -272,6 +277,46 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD }); } + @observable _audioState = 0; + + @action + onPointerEnter = () => { + let self = this; + let audioAnnos = DocListCast(this.extensionDoc.audioAnnotations); + if (audioAnnos.length && this._audioState === 0) { + audioAnnos.map(anno => anno.data instanceof AudioField && new Howl({ + src: [anno.data.url.href], + autoplay: true, + loop: false, + volume: 0.5, + onend: function () { + runInAction(() => self._audioState = 0); + } + })); + this._audioState = 1; + } + // else { + // if (this._audioState === 0) { + // this._audioState = 1; + // new Howl({ + // src: ["https://www.kozco.com/tech/piano2-CoolEdit.mp3"], + // autoplay: true, + // loop: false, + // volume: 0.5, + // onend: function () { + // runInAction(() => self._audioState = 0); + // } + // }); + // } + // } + } + + @action + audioDown = () => { + this.recordAudioAnnotation(); + } + + render() { // let transform = this.props.ScreenToLocalTransform().inverse(); let pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50; @@ -282,7 +327,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD let id = (this.props as any).id; // bcz: used to set id = "isExpander" in templates.tsx let nativeWidth = FieldValue(this.Document.nativeWidth, pw); let nativeHeight = FieldValue(this.Document.nativeHeight, 0); - let paths: string[] = ["http://www.cs.brown.edu/~bcz/noImage.png"]; + let paths: string[] = [window.origin + RouteStore.corsProxy + "/" + "http://www.cs.brown.edu/~bcz/noImage.png"]; // this._curSuffix = ""; // if (w > 20) { Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey); @@ -305,6 +350,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD return ( <div id={id} className={`imageBox-cont${interactive}`} style={{ background: "transparent" }} + onPointerEnter={this.onPointerEnter} onPointerDown={this.onPointerDown} onDrop={this.onDrop} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}> <img id={id} @@ -316,6 +362,17 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD ref={this._imgRef} onError={this.onError} /> {paths.length > 1 ? this.dots(paths) : (null)} + <div onPointerDown={this.audioDown} style={{ + display: DocListCast(this.extensionDoc.audioAnnotations).length ? "inline" : "inline", + width: nativeWidth * 0.1, + height: nativeWidth * 0.1, + position: "absolute", + top: 0, + left: 0, + }}> + <FontAwesomeIcon + style={{ width: "100%", height: "100%", color: [DocListCast(this.extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={faFileAudio} size="sm" /> + </div> {/* {this.lightbox(paths)} */} </div>); } diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx index 8399605fb..16c44225a 100644 --- a/src/client/views/search/SearchBox.tsx +++ b/src/client/views/search/SearchBox.tsx @@ -145,7 +145,7 @@ export class SearchBox extends React.Component { const highlighting = res.highlighting || {}; const highlightList = res.docs.map(doc => highlighting[doc[Id]]); - const docs = await Promise.all(res.docs.map(doc => Cast(doc.extendsDoc, Doc, doc as any))); + const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc)); const highlights: typeof res.highlighting = {}; docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]); let filteredDocs = FilterBox.Instance.filterDocsByType(docs); diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx index 26f00e03e..a995140e2 100644 --- a/src/client/views/search/SearchItem.tsx +++ b/src/client/views/search/SearchItem.tsx @@ -101,8 +101,8 @@ export class SearchItem extends React.Component<SearchItemProps> { onClick = () => { // I dont think this is the best functionality because clicking the name of the collection does that. Change it back if you'd like - // DocumentManager.Instance.jumpToDocument(this.props.doc, false); - CollectionDockingView.Instance.AddRightSplit(this.props.doc, undefined); + DocumentManager.Instance.jumpToDocument(this.props.doc, false); + // CollectionDockingView.Instance.AddRightSplit(this.props.doc, undefined); } @observable _useIcons = true; @observable _displayDim = 50; |