aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormehekj <mehek.jethani@gmail.com>2022-06-15 13:11:16 -0400
committermehekj <mehek.jethani@gmail.com>2022-06-15 13:11:16 -0400
commitbf3f88f5236a6ebda4ca3b6dc246f98ff404a360 (patch)
treeab4431735124bc4847993e39084f79d69d97c69f /src
parent4b6a199e1508ff853ce29a3298e202ae7fbe43dd (diff)
ui fixes and thumbnails upload in parallel
Diffstat (limited to 'src')
-rw-r--r--src/client/views/AudioWaveform.scss2
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.scss13
-rw-r--r--src/client/views/collections/CollectionStackedTimeline.tsx19
-rw-r--r--src/client/views/nodes/AudioBox.tsx6
-rw-r--r--src/client/views/nodes/VideoBox.tsx40
5 files changed, 38 insertions, 42 deletions
diff --git a/src/client/views/AudioWaveform.scss b/src/client/views/AudioWaveform.scss
index e20434a25..6cbd1759a 100644
--- a/src/client/views/AudioWaveform.scss
+++ b/src/client/views/AudioWaveform.scss
@@ -1,7 +1,7 @@
.audioWaveform {
position: relative;
width: 100%;
- height: 100%;
+ height: 200%;
overflow: hidden;
z-index: -1000;
bottom: 0;
diff --git a/src/client/views/collections/CollectionStackedTimeline.scss b/src/client/views/collections/CollectionStackedTimeline.scss
index 580cbccda..f9cf5cd4e 100644
--- a/src/client/views/collections/CollectionStackedTimeline.scss
+++ b/src/client/views/collections/CollectionStackedTimeline.scss
@@ -6,7 +6,6 @@
overflow-y: hidden;
border: none;
background-color: $white;
- border: 2px solid $dark-gray;
border-width: 0 2px 0 2px;
&:hover {
@@ -16,7 +15,7 @@
}
}
-.timeline-container:hover + .videoBox-thumbnail {
+.timeline-container:hover + .timeline-hoverUI {
display: block;
}
@@ -29,6 +28,7 @@
background: $off-white;
z-index: 1000;
height: 100%;
+ overflow: hidden;
.collectionStackedTimeline-trim-shade {
position: absolute;
@@ -127,10 +127,17 @@
}
}
-.videoBox-thumbnail {
+.timeline-hoverUI {
position: absolute;
z-index: 10000;
transform: translate(-50%, 100%);
height: 100%;
display: none;
+
+ .hoverTime {
+ color: $dark-gray;
+ text-align: center;
+ transform: translate(0, -17px);
+ font-weight: bold;
+ }
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index 2b78f5764..850aa5dbe 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -326,13 +326,13 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
const rect = this._timeline?.getBoundingClientRect();
const clientX = e.clientX;
if (rect) {
- this._hoverTime = Math.min(this.toTimeline(clientX - rect.x, rect.width), this.clipEnd);
+ this._hoverTime = this.toTimeline(clientX - rect.x, rect.width);
if (this.dataDoc.thumbnails) {
const nearest = Math.floor(this._hoverTime / this.props.rawDuration * VideoBox.numThumbnails);
const thumbnails = Cast(this.dataDoc.thumbnails, listSpec("string"), []);
- const src = new ImageField(thumbnails[nearest]).url.href.replace(".png", "_s.png");
- this._thumbnail = src;
- console.log(src);
+ const imgField = thumbnails && thumbnails.length > 0 ? new ImageField(thumbnails[nearest]) : new ImageField("");
+ const src = imgField && imgField.url.href ? imgField.url.href.replace(".png", "_s.png") : "";
+ this._thumbnail = src ? src : undefined;
}
}
}
@@ -576,7 +576,7 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
dictationHeight = () => (this.props.PanelHeight() * (100 - this.dictationHeightPercent)) / 100;
@computed get timelineContentHeight() { return this.props.PanelHeight() * this.dictationHeightPercent / 100; }
- @computed get timelineContentWidth() { return this.props.PanelWidth() * this.zoomFactor - 4; } // subtract size of container border
+ @computed get timelineContentWidth() { return this.props.PanelWidth() * this.zoomFactor; } // subtract size of container border
dictationScreenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, -this.timelineContentHeight);
@@ -723,12 +723,12 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
/>
{/* {this.renderDictation} */}
- <div
+ { /* check time to prevent weird div overflow */ this._hoverTime < this.clipDuration && <div
className="collectionStackedTimeline-hover"
style={{
left: `${((this._hoverTime - this.clipStart) / this.clipDuration) * 100}%`,
}}
- />
+ />}
<div
className="collectionStackedTimeline-current"
@@ -772,7 +772,10 @@ export class CollectionStackedTimeline extends CollectionSubView<CollectionStack
)}
</div>
</div>
- {this._thumbnail && <img className="videoBox-thumbnail" style={{ left: `calc(${((this._hoverTime - this.clipStart) / this.clipDuration) * 100}%` }} src={this._thumbnail} />}
+ <div className="timeline-hoverUI" style={{ left: `calc(${((this._hoverTime - this.clipStart) / this.clipDuration) * 100}%` }}>
+ {this._thumbnail && <img className="videoBox-thumbnail" src={this._thumbnail} />}
+ <div className="hoverTime">{formatTime(this._hoverTime)}</div>
+ </div>
</div >);
}
}
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 59c37753a..1d06f368f 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -581,7 +581,9 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<div className="timecode-current">
{this.timeline && formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode) - NumCast(this.timeline.clipStart)))}
</div>
- {!this.miniPlayer &&
+ {this.miniPlayer ?
+ <div>/</div>
+ :
<div className="bottom-controls-middle">
<FontAwesomeIcon icon="search-plus" />
<input type="range" step="0.1" min="1" max="5" value={this.timeline?._zoomFactor}
@@ -591,8 +593,6 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
/>
</div>}
- {this.miniPlayer && <div>/</div>}
-
<div className="timecode-duration">
{this.timeline && formatTime(Math.round(this.timeline.clipDuration))}
</div>
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 80ff19519..ef3b0d105 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -32,18 +32,6 @@ import { Image } from "wikijs";
import { List } from "../../../fields/List";
const path = require('path');
-
-//TODO mj: one option for doing thumbnail previews of video in timeline?
-/**
- * 1. set vref in videobox
- * 2. when vref is set immediately process video to extract ~50 thumbnails
- * (^^ would make more sense to do this when video is initially uploaded)
- * 3. upload each file to server using convertDataURI and save list of URLs as field on doc
- * 4. in CST onHover, set hover time
- * 5. use hover time to figure out index of nearest thumbnail
- * 6. get URL of image and use source to paint canvas accordingly
- */
-
/**
* VideoBox
* Main component: VideoBox.tsx
@@ -375,12 +363,13 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// extracts video thumbnails and saves them as field of doc
getVideoThumbnails = () => {
- this.layoutDoc.cloneO
const video = document.createElement('video');
- const thumbnails: string[] = [];
+ const thumbnailPromises: Promise<any>[] = [];
+
video.onloadedmetadata = () => {
video.currentTime = 0;
};
+
video.onseeked = () => {
const canvas = document.createElement('canvas');
canvas.height = video.videoHeight;
@@ -391,18 +380,15 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const retitled = StrCast(this.rootDoc.title).replace(/[ -\.:]/g, "");
const encodedFilename = encodeURIComponent("thumbnail" + retitled + "_" + video.currentTime.toString().replace(/\./, "_"));
const filename = basename(encodedFilename);
- VideoBox.convertDataUri(imgUrl, filename).then((returnedFilename: string) => {
- returnedFilename && thumbnails.push(returnedFilename);
- const newTime = video.currentTime + video.duration / VideoBox.numThumbnails;
- if (newTime < video.duration) {
- video.currentTime = newTime;
- console.log(thumbnails.length);
- }
- else {
- this.dataDoc.thumbnails = new List<string>(thumbnails);
- }
- });
- };
+ thumbnailPromises.push(VideoBox.convertDataUri(imgUrl, filename));
+ const newTime = video.currentTime + video.duration / (VideoBox.numThumbnails - 1);
+ if (newTime < video.duration) {
+ video.currentTime = newTime;
+ }
+ else {
+ Promise.all(thumbnailPromises).then(thumbnails => { this.dataDoc.thumbnails = new List<string>(thumbnails); });
+ }
+ }
const field = Cast(this.dataDoc[this.fieldKey], VideoField);
field && (video.src = field.url.href);
@@ -421,7 +407,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._disposers.reactionDisposer = reaction(() => NumCast(this.layoutDoc._currentTimecode),
time => !this._playing && (vref.currentTime = time), { fireImmediately: true });
- !this.dataDoc.thumbnails && this.getVideoThumbnails();
+ (!this.dataDoc.thumbnails || this.dataDoc.thumbnails.length != VideoBox.numThumbnails) && this.getVideoThumbnails();
}
}