aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts4
-rw-r--r--src/client/views/InkingCanvas.tsx11
-rw-r--r--src/client/views/InkingControl.tsx1
-rw-r--r--src/client/views/InkingStroke.tsx18
-rw-r--r--src/client/views/nodes/AudioBox.tsx21
-rw-r--r--src/client/views/nodes/VideoBox.tsx2
-rw-r--r--src/new_fields/InkField.ts4
-rw-r--r--src/server/authentication/models/current_user_utils.ts1
8 files changed, 38 insertions, 24 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 316efe44c..5ae4ca82a 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -334,9 +334,7 @@ export namespace Docs {
let dataDoc = MakeDataDelegate(proto, protoProps, data);
let viewDoc = Doc.MakeDelegate(dataDoc, delegId);
- AudioBox.ActiveRecordings.map(d => {
- DocUtils.MakeLink({ doc: viewDoc }, { doc: d }, "audio link", "link to audio: " + d.title);
- });
+ AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: viewDoc }, { doc: d }, "audio link", "link to audio: " + d.title));
return Doc.assign(viewDoc, delegateProps);
}
diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx
index 920ebaedd..0037b95d0 100644
--- a/src/client/views/InkingCanvas.tsx
+++ b/src/client/views/InkingCanvas.tsx
@@ -78,7 +78,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
this.previousState = new Map(this.inkData);
- if (InkingControl.Instance.selectedTool !== InkTool.Eraser) {
+ if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) {
// start the new line, saves a uuid to represent the field of the stroke
this._currentStrokeId = Utils.GenerateGuid();
const data = this.inkData;
@@ -87,7 +87,8 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
color: InkingControl.Instance.selectedColor,
width: InkingControl.Instance.selectedWidth,
tool: InkingControl.Instance.selectedTool,
- displayTimecode: NumCast(this.props.Document.currentTimecode, -1)
+ displayTimecode: NumCast(this.props.Document.currentTimecode, -1),
+ creationTime: new Date().getTime()
});
this.inkData = data;
}
@@ -120,7 +121,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
onPointerMove = (e: PointerEvent): void => {
e.stopPropagation();
e.preventDefault();
- if (InkingControl.Instance.selectedTool !== InkTool.Eraser) {
+ if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) {
let data = this.inkData; // add points to new line as it is being drawn
let strokeData = data.get(this._currentStrokeId);
if (strokeData) {
@@ -161,6 +162,7 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
color={strokeData.color}
width={strokeData.width}
tool={strokeData.tool}
+ creationTime={strokeData.creationTime}
deleteCallback={this.removeLine} />);
}
return paths;
@@ -181,7 +183,8 @@ export class InkingCanvas extends React.Component<InkCanvasProps> {
render() {
let svgCanvasStyle = InkingControl.Instance.selectedTool !== InkTool.None && !this.props.Document.isBackground ? "canSelect" : "noSelect";
- let cursor = svgCanvasStyle === "canSelect" ? (InkingControl.Instance.selectedTool === InkTool.Eraser ? "pointer" : "default") : undefined;
+ let cursor = svgCanvasStyle === "canSelect" ? (InkingControl.Instance.selectedTool === InkTool.Eraser ||
+ InkingControl.Instance.selectedTool === InkTool.Scrubber ? "pointer" : "default") : undefined;
return (
<div className="inkingCanvas">
<div className={`inkingCanvas-${svgCanvasStyle}`} onPointerDown={this.onPointerDown} style={{ cursor: cursor }} />
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index 105adc03d..75faa9641 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -126,6 +126,7 @@ export class InkingControl {
Scripting.addGlobal(function activatePen(pen: any, width: any, color: any) { InkingControl.Instance.switchTool(pen ? InkTool.Pen : InkTool.None); InkingControl.Instance.switchWidth(width); InkingControl.Instance.updateSelectedColor(color); });
Scripting.addGlobal(function activateBrush(pen: any, width: any, color: any) { InkingControl.Instance.switchTool(pen ? InkTool.Highlighter : InkTool.None); InkingControl.Instance.switchWidth(width); InkingControl.Instance.updateSelectedColor(color); });
Scripting.addGlobal(function activateEraser(pen: any) { return InkingControl.Instance.switchTool(pen ? InkTool.Eraser : InkTool.None); });
+Scripting.addGlobal(function activateScrubber(pen: any) { return InkingControl.Instance.switchTool(pen ? InkTool.Scrubber : InkTool.None); });
Scripting.addGlobal(function deactivateInk() { return InkingControl.Instance.switchTool(InkTool.None); });
Scripting.addGlobal(function setInkWidth(width: any) { return InkingControl.Instance.switchWidth(width); });
Scripting.addGlobal(function setInkColor(color: any) { return InkingControl.Instance.updateSelectedColor(color); }); \ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index b8d428d31..7bbf71482 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -1,9 +1,10 @@
import { observer } from "mobx-react";
-import { observable, trace } from "mobx";
+import { observable, trace, runInAction } from "mobx";
import { InkingControl } from "./InkingControl";
import React = require("react");
import { InkTool } from "../../new_fields/InkField";
import "./InkingStroke.scss";
+import { AudioBox } from "./nodes/AudioBox";
interface StrokeProps {
@@ -15,6 +16,7 @@ interface StrokeProps {
color: string;
width: string;
tool: InkTool;
+ creationTime: number;
deleteCallback: (index: string) => void;
}
@@ -31,6 +33,11 @@ export class InkingStroke extends React.Component<StrokeProps> {
e.stopPropagation();
e.preventDefault();
}
+ if (InkingControl.Instance.selectedTool === InkTool.Scrubber && e.buttons === 1) {
+ runInAction(() => AudioBox.ScrubTime = this.props.creationTime);
+ e.stopPropagation();
+ e.preventDefault();
+ }
}
parseData = (line: Array<{ x: number, y: number }>): string => {
@@ -55,10 +62,9 @@ export class InkingStroke extends React.Component<StrokeProps> {
let pathlength = this.props.count; // bcz: this is needed to force reactions to the line's data changes
let marker = this.props.tool === InkTool.Highlighter ? "-marker" : "";
- let pointerEvents: any = InkingControl.Instance.selectedTool === InkTool.Eraser ? "all" : "none";
- return (
- <path className={`inkingStroke${marker}`} d={pathData} style={{ ...pathStyle, pointerEvents: pointerEvents }} strokeLinejoin="round" strokeLinecap="round"
- onPointerOver={this.deleteStroke} onPointerDown={this.deleteStroke} />
- );
+ let pointerEvents: any = InkingControl.Instance.selectedTool === InkTool.Eraser ||
+ InkingControl.Instance.selectedTool === InkTool.Scrubber ? "all" : "none";
+ return (<path className={`inkingStroke${marker}`} d={pathData} style={{ ...pathStyle, pointerEvents: pointerEvents }}
+ strokeLinejoin="round" strokeLinecap="round" onPointerOver={this.deleteStroke} onPointerDown={this.deleteStroke} />);
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 55b472726..62ec683da 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -38,11 +38,13 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
_linkPlayDisposer: IReactionDisposer | undefined;
_reactionDisposer: IReactionDisposer | undefined;
+ _scrubbingDisposer: IReactionDisposer | undefined;
_ele: HTMLAudioElement | null = null;
_recorder: any;
_lastUpdate = 0;
@observable private _audioState = 0;
+ @observable public static ScrubTime = 0;
public static ActiveRecordings: Doc[] = [];
componentDidMount() {
@@ -53,7 +55,9 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
const la1 = l.anchor1 as Doc;
const la2 = l.anchor2 as Doc;
if (l[Id] === scrollLinkId && la1 && la2) {
- setTimeout(() => this.playFrom(Doc.AreProtosEqual(la1, this.dataDoc) ? la2 : la1), 250);
+ let doc = Doc.AreProtosEqual(la1, this.dataDoc) ? la2 : la1;
+ let seek = DateCast(la1.creationTime);
+ setTimeout(() => this.playFrom(seek.date.getTime()), 250);
}
});
scrollLinkId && (this.layoutDoc.scrollLinkID = undefined);
@@ -61,8 +65,9 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
selected => {
let sel = selected.length ? selected[0].props.Document : undefined;
- this.Document.playOnSelect && sel && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(sel);
+ this.Document.playOnSelect && sel && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(DateCast(sel.creationTime).date.getTime());
});
+ this._scrubbingDisposer = reaction(() => AudioBox.ScrubTime, time => this.Document.playOnSelect && this.playFrom(time));
}
updateHighlights = () => {
@@ -86,14 +91,13 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
}
}
- playFrom = (sel: Doc) => {
+ playFrom = (seek: number) => {
const extensionDoc = this.extensionDoc;
let start = extensionDoc && DateCast(extensionDoc.recordingStart);
- let seek = sel && DateCast(sel.creationDate);
- if (this._ele && start && seek) {
- if (sel) {
- let delta = (seek.date.getTime() - start.date.getTime()) / 1000;
- if (start && seek && delta > 0 && delta < this._ele.duration) {
+ if (this._ele && start) {
+ if (seek) {
+ let delta = (seek - start.date.getTime()) / 1000;
+ if (start && delta > 0 && delta < this._ele.duration) {
this._ele.currentTime = delta;
this._ele.play();
this._lastUpdate = delta;
@@ -110,6 +114,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
componentWillUnmount() {
this._reactionDisposer && this._reactionDisposer();
this._linkPlayDisposer && this._linkPlayDisposer();
+ this._scrubbingDisposer && this._scrubbingDisposer();
}
recordAudioAnnotation = () => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 48a699e58..53baea4ae 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -301,7 +301,6 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
this._isResetClick = 0;
document.addEventListener("pointermove", this.onResetMove, true);
document.addEventListener("pointerup", this.onResetUp, true);
- InkingControl.Instance.switchTool(InkTool.Eraser);
}
onResetMove = (e: PointerEvent) => {
@@ -314,7 +313,6 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
onResetUp = (e: PointerEvent) => {
document.removeEventListener("pointermove", this.onResetMove, true);
document.removeEventListener("pointerup", this.onResetUp, true);
- InkingControl.Instance.switchTool(InkTool.None);
this._isResetClick < 10 && (this.Document.currentTimecode = 0);
}
diff --git a/src/new_fields/InkField.ts b/src/new_fields/InkField.ts
index e381d0218..d94834e91 100644
--- a/src/new_fields/InkField.ts
+++ b/src/new_fields/InkField.ts
@@ -8,7 +8,8 @@ export enum InkTool {
None,
Pen,
Highlighter,
- Eraser
+ Eraser,
+ Scrubber
}
export interface StrokeData {
@@ -17,6 +18,7 @@ export interface StrokeData {
width: string;
tool: InkTool;
displayTimecode: number;
+ creationTime: number;
}
export type InkData = Map<string, StrokeData>;
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 477b36ea4..95ebe3cb6 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -58,6 +58,7 @@ export class CurrentUserUtils {
{ title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc },
{ title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", unchecked: `!sameDocs(this.activePen.pen, this)`, activePen: doc },
{ title: "use eraser", icon: "eraser", click: 'activateEraser(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', unchecked: `!sameDocs(this.activePen.pen, this)`, backgroundColor: "pink", activePen: doc },
+ { title: "use scrubber", icon: "eraser", click: 'activateScrubber(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this);', unchecked: `!sameDocs(this.activePen.pen, this)`, backgroundColor: "green", activePen: doc },
{ title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', unchecked: `!sameDocs(this.activePen.pen, this) && this.activePen.pen !== undefined`, backgroundColor: "white", activePen: doc },
];
return docProtoData.map(data => Docs.Create.FontIconDocument({