diff --git a/README.md b/README.md
index 57a2d28..154d94b 100755
--- a/README.md
+++ b/README.md
@@ -15,30 +15,24 @@ Disclaimer: This is not an officially supported Google product.
3. Install bower
``` shell
-npm install -g bower
+npm install
```
-4. Install dependencies
-
-``` shell
-bower install
-```
-
-5. Populate config files
+4. Populate config files
Rename `config_sample.yaml` to `config.yaml`
(this file can be left blank for most users)
- Rename `app/js/config_sample.js` to `app/js/config.js`
+ Rename `app/js/config_sample.ts` to `app/js/config.ts`
Fill in values for `window.__directConfig.stagingDomain` and `window.__directConfig.productionDomain` if you intend to use staging and production environments. Otherwise, they can be left as empty strings.
-6. Run a local instance
+5. Run a local instance
``` shell
-dev_appserver.py .
+npm run serve
```
-7. View the server at http://localhost:8080/
+6. View the server at http://localhost:8080/
diff --git a/app/js/config.ts b/app/js/config.ts
deleted file mode 100644
index 5285805..0000000
--- a/app/js/config.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-(function (window) {
- window.__directConfig = window.__directConfig || {};
-
- window.__directConfig.stagingDomain = 'staging.example.com';
- window.__directConfig.productionDomain = 'example.com';
-
-}(this));
-
diff --git a/app/js/config_sample.ts b/app/js/config_sample.ts
deleted file mode 100644
index 94c930f..0000000
--- a/app/js/config_sample.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-(function (window) {
- window.__directConfig = window.__directConfig || {};
-
- window.__directConfig.stagingDomain = 'staging.example.com';
- window.__directConfig.productionDomain = 'example.com';
-
-}(this));
diff --git a/app/js/app.ts b/app/ts/app.ts
similarity index 97%
rename from app/js/app.ts
rename to app/ts/app.ts
index df1001a..74079e2 100755
--- a/app/js/app.ts
+++ b/app/ts/app.ts
@@ -20,11 +20,9 @@ if (window) {
Object.assign(config, window.__directConfig);
}
-declare const gapi;
-declare const google;
declare const angular;
-const app = angular.module("spec", [
+export var app = angular.module("spec", [
"ngRoute",
"ngResource",
"ngMaterial",
diff --git a/app/js/baseCtrl.ts b/app/ts/baseCtrl.ts
similarity index 98%
rename from app/js/baseCtrl.ts
rename to app/ts/baseCtrl.ts
index 85afe36..09eaa02 100755
--- a/app/js/baseCtrl.ts
+++ b/app/ts/baseCtrl.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
app.controller(
"baseCtrl",
function ($scope, $http, $window, $location, $mdDialog, Spec) {
diff --git a/app/js/canvasDirectives.ts b/app/ts/canvasDirectives.ts
similarity index 59%
rename from app/js/canvasDirectives.ts
rename to app/ts/canvasDirectives.ts
index d9ddee2..634639c 100755
--- a/app/js/canvasDirectives.ts
+++ b/app/ts/canvasDirectives.ts
@@ -12,12 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// @ts-nocheck
+import { app } from "./app.js";
+
+declare const angular;
/**
* Spec Canvas Visuals to render bezier curves and other elements
*/
-app.directive('specCanvas', function ($timeout) {
+app.directive("specCanvas", function ($timeout) {
// Bezier Curve Drawing
// Basic Curves:
@@ -27,24 +29,24 @@ app.directive('specCanvas', function ($timeout) {
// Turns hex to RGB then adds an alpha channel while outputting to CSS format
var lighten = function (hex) {
- hex = hex.replace(/[^0-9A-F]/gi, '');
+ hex = hex.replace(/[^0-9A-F]/gi, "");
var bigint = parseInt(hex, 16);
var r = (bigint >> 16) & 255;
var g = (bigint >> 8) & 255;
var b = bigint & 255;
- return 'rgba(' + r + ',' + g + ',' + b + ',0.15)';
- }
+ return "rgba(" + r + "," + g + "," + b + ",0.15)";
+ };
// Draws the base bar and begin and end circles
var drawBar = function (ctx, w, h) {
// ctx.fillRect(0, h-10, 2, 10); // Left Bar (debug)
- ctx.fillRect(5, h - 6, w - 10, 2); // Bottom Bar
+ ctx.fillRect(5, h - 6, w - 10, 2); // Bottom Bar
// ctx.fillRect(w-2, h-10, 2, 10); // Right Bar (debug)
// Circle Params
- var radius = 5; // Arc radius
- var startAngle = 0; // Starting point on circle
+ var radius = 5; // Arc radius
+ var startAngle = 0; // Starting point on circle
var endAngle = Math.PI * 2; // End point on circle
// Left Circle
@@ -56,16 +58,14 @@ app.directive('specCanvas', function ($timeout) {
ctx.beginPath();
ctx.arc(w - 5, h - 5, radius, startAngle, endAngle);
ctx.fill();
-
- }
+ };
var drawDiamond = function (ctx, w, h) {
-
// translate
ctx.translate(0, 7);
// rotate
- ctx.rotate(45 * Math.PI / 180);
+ ctx.rotate((45 * Math.PI) / 180);
// draw diamond
ctx.fillRect(12.15, 5, 7.5, 7.5);
@@ -73,7 +73,7 @@ app.directive('specCanvas', function ($timeout) {
// reset
ctx.setTransform(1, 0, 0, 1, 0, 0);
- }
+ };
// Renders the curve on the given canvas
var render = function (wrap, canvas, spec, totalDuration) {
@@ -86,26 +86,29 @@ app.directive('specCanvas', function ($timeout) {
// Set Canvas Positioning and rudimentary prevention of invalid input
// TODO: better error checking
- if (+spec.duration + +spec.delay > +totalDuration ||
- (+spec.delay < 0 || +spec.duration > +totalDuration)) {
- console.warn('Duration or Delay are invalid!');
+ if (
+ +spec.duration + +spec.delay > +totalDuration ||
+ +spec.delay < 0 ||
+ +spec.duration > +totalDuration
+ ) {
+ console.warn("Duration or Delay are invalid!");
return;
}
- var duration = spec.duration / totalDuration * 100;
- var delay = spec.delay / totalDuration * 100;
+ var duration = (spec.duration / totalDuration) * 100;
+ var delay = (spec.delay / totalDuration) * 100;
wrap.css({
- width: duration + '%',
- marginLeft: delay + '%'
+ width: duration + "%",
+ marginLeft: delay + "%",
});
var wrapWidth = wrap.width();
canvas.css({
width: wrapWidth + 10,
- marginLeft: '-5px',
- marginRight: '-5px'
+ marginLeft: "-5px",
+ marginRight: "-5px",
});
// Set Canvas Width / Height
@@ -113,14 +116,13 @@ app.directive('specCanvas', function ($timeout) {
var ch = canvas.height();
canvas.attr({
width: cw,
- height: ch
+ height: ch,
});
// Setup & Reset
- var ctx = canvas.get(0).getContext('2d');
+ var ctx = canvas.get(0).getContext("2d");
ctx.clearRect(0, 0, cw, ch);
-
// check duration
if (duration === 0) {
ctx.fillStyle = baseColor;
@@ -133,56 +135,84 @@ app.directive('specCanvas', function ($timeout) {
// http://jsfiddle.net/andershaig/54AsL/
ctx.fillStyle = lightColor;
switch (curve) {
- case 'curve':
+ case "curve":
ctx.beginPath();
ctx.moveTo(5, ch - 5);
- ctx.bezierCurveTo(5, ch - 5, cw / 2, ((ch - 5) * -1), cw - 5, ch - 5);
+ ctx.bezierCurveTo(5, ch - 5, cw / 2, (ch - 5) * -1, cw - 5, ch - 5);
ctx.fill();
break;
- case 'quantum':
+ case "quantum":
inValue = 0.8;
outValue = 0.4;
ctx.beginPath();
ctx.moveTo(5, ch - 5);
- ctx.bezierCurveTo((cw * outValue) + 5, ch - 5, ((1 - inValue) * cw) - 5, 0, cw - 5, 0);
+ ctx.bezierCurveTo(
+ cw * outValue + 5,
+ ch - 5,
+ (1 - inValue) * cw - 5,
+ 0,
+ cw - 5,
+ 0
+ );
ctx.lineTo(cw - 5, ch - 5);
ctx.fill();
break;
- case 'incoming':
+ case "incoming":
inValue = 0.8;
outValue = 0;
ctx.beginPath();
ctx.moveTo(5, ch - 5);
- ctx.bezierCurveTo((cw * outValue) + 5, ch - 5, ((1 - inValue) * cw) - 5, 0, cw - 5, 0);
+ ctx.bezierCurveTo(
+ cw * outValue + 5,
+ ch - 5,
+ (1 - inValue) * cw - 5,
+ 0,
+ cw - 5,
+ 0
+ );
ctx.lineTo(cw - 5, ch - 5);
ctx.fill();
break;
- case 'outgoing':
+ case "outgoing":
inValue = 0;
outValue = 0.4;
ctx.beginPath();
ctx.moveTo(5, ch - 5);
- ctx.bezierCurveTo((cw * outValue) + 5, ch - 5, ((1 - inValue) * cw) - 5, 0, cw - 5, 0);
+ ctx.bezierCurveTo(
+ cw * outValue + 5,
+ ch - 5,
+ (1 - inValue) * cw - 5,
+ 0,
+ cw - 5,
+ 0
+ );
ctx.lineTo(cw - 5, ch - 5);
ctx.fill();
break;
- case 'linear':
+ case "linear":
ctx.beginPath();
ctx.moveTo(5, ch - 5);
ctx.lineTo(cw - 5, 0);
ctx.lineTo(cw - 5, ch - 5);
ctx.fill();
break;
- case 'custom':
+ case "custom":
inValue = spec.easingCustomIncoming / 100;
outValue = spec.easingCustomOutgoing / 100;
ctx.beginPath();
ctx.moveTo(5, ch - 5);
- ctx.bezierCurveTo((cw * outValue) + 5, ch - 5, ((1 - inValue) * cw) - 5, 0, cw - 5, 0);
+ ctx.bezierCurveTo(
+ cw * outValue + 5,
+ ch - 5,
+ (1 - inValue) * cw - 5,
+ 0,
+ cw - 5,
+ 0
+ );
ctx.lineTo(cw - 5, ch - 5);
ctx.fill();
break;
- case 'none':
+ case "none":
ctx.fillRect(5, 0, cw - 10, ch - 5);
break;
default:
@@ -192,22 +222,26 @@ app.directive('specCanvas', function ($timeout) {
// Bar
ctx.fillStyle = baseColor;
drawBar(ctx, cw, ch);
- }
+ };
return {
- restrict: 'A',
+ restrict: "A",
scope: {
- specCanvas: '=',
- duration: '='
+ specCanvas: "=",
+ duration: "=",
},
link: function (scope, element, attrs) {
var wrap = angular.element(element[0]);
- var canvas = angular.element(element.find('canvas')[0]);
+ var canvas = angular.element(element.find("canvas")[0]);
// Watch Changes
- scope.$watch('specCanvas', function (newValue, oldValue) {
- render(wrap, canvas, scope.specCanvas, scope.duration);
- }, true);
+ scope.$watch(
+ "specCanvas",
+ function (newValue, oldValue) {
+ render(wrap, canvas, scope.specCanvas, scope.duration);
+ },
+ true
+ );
// Window Width Changes
$(window).resize(function () {
@@ -215,19 +249,19 @@ app.directive('specCanvas', function ($timeout) {
});
// Watch for controller to request redraw
- scope.$on('refreshCanvas', function () {
+ scope.$on("refreshCanvas", function () {
$timeout(function () {
render(wrap, canvas, scope.specCanvas, scope.duration);
}, 0);
});
- }
- }
+ },
+ };
});
/**
* Grid Background
*/
-app.directive('specGrid', function ($timeout) {
+app.directive("specGrid", function ($timeout) {
var render = function (canvas, spec) {
var ms = spec.duration || 300;
var minorMs = spec.divisions.minor || 15;
@@ -238,22 +272,24 @@ app.directive('specGrid', function ($timeout) {
var ch = canvas.parent().height();
canvas.attr({
width: cw,
- height: ch
+ height: ch,
});
spec.canvas.width = cw;
// Setup & Reset
- var ctx = canvas.get(0).getContext('2d');
+ var ctx = canvas.get(0).getContext("2d");
ctx.clearRect(0, 0, cw, ch);
// Generate Grid
- var minorDivisions = spec.divisions.minorCount = ms / minorMs;
- var minorGap = spec.divisions.minorGap = cw / minorDivisions;
+ var minorDivisions = (spec.divisions.minorCount = ms / minorMs);
+ var minorGap = (spec.divisions.minorGap = cw / minorDivisions);
ctx.beginPath();
- for (var x = 0.5 + minorGap; x <= cw; x += minorGap) { // Adding the gap skips the initial line at 0
+ for (var x = 0.5 + minorGap; x <= cw; x += minorGap) {
+ // Adding the gap skips the initial line at 0
var xr = Math.round(x);
+ var nx;
if (xr >= x) {
nx = xr - 0.5;
@@ -264,15 +300,16 @@ app.directive('specGrid', function ($timeout) {
ctx.lineTo(nx, ch);
}
- ctx.strokeStyle = '#EEEEEE';
+ ctx.strokeStyle = "#EEEEEE";
ctx.lineWidth = 1;
ctx.stroke();
- var majorDivisions = spec.divisions.majorCount = ms / majorMs;
- var majorGap = spec.divisions.majorGap = cw / majorDivisions;
+ var majorDivisions = (spec.divisions.majorCount = ms / majorMs);
+ var majorGap = (spec.divisions.majorGap = cw / majorDivisions);
ctx.beginPath();
- for (var x = majorGap; x < cw; x += majorGap) { // Adding the gap skips the initial line at 0
+ for (var x = majorGap; x < cw; x += majorGap) {
+ // Adding the gap skips the initial line at 0
var xr = Math.round(x);
ctx.moveTo(xr, 0);
@@ -287,25 +324,29 @@ app.directive('specGrid', function ($timeout) {
ctx.moveTo(cw - 1, 0);
ctx.lineTo(cw - 1, ch);
- ctx.strokeStyle = '#DDDDDD';
+ ctx.strokeStyle = "#DDDDDD";
ctx.lineWidth = 2;
ctx.stroke();
- }
+ };
return {
- restrict: 'A',
+ restrict: "A",
scope: {
- specGrid: '='
+ specGrid: "=",
},
link: function (scope, element, attrs) {
var canvas = angular.element(element[0]);
// Watch Changes
- scope.$watch('specGrid', function (newValue, oldValue) {
- if (scope.specGrid && scope.specGrid !== undefined) {
- render(canvas, scope.specGrid);
- }
- }, true);
+ scope.$watch(
+ "specGrid",
+ function (newValue, oldValue) {
+ if (scope.specGrid && scope.specGrid !== undefined) {
+ render(canvas, scope.specGrid);
+ }
+ },
+ true
+ );
// Window Width Changes
$(window).resize(function () {
@@ -315,22 +356,22 @@ app.directive('specGrid', function ($timeout) {
});
// Watch for controller to request redraw
- scope.$on('refreshCanvas', function (type) {
+ scope.$on("refreshCanvas", function (type) {
$timeout(function () {
if (scope.specGrid && scope.specGrid !== undefined) {
render(canvas, scope.specGrid);
}
}, 0);
});
- }
- }
+ },
+ };
});
/**
* Drawable Canvas to add new items
* (goes away once drawn and renders using specCanvas' render method)
*/
-app.directive('specDraw', function ($timeout, $document) {
+app.directive("specDraw", function ($timeout, $document) {
var render = function (canvas, spec) {
var ms = spec.duration || 300;
var minorMs = spec.divisions.minor || 15;
@@ -341,24 +382,26 @@ app.directive('specDraw', function ($timeout, $document) {
var ch = canvas.parent().height();
canvas.attr({
width: cw,
- height: ch
+ height: ch,
});
// Setup & Reset
- var ctx = canvas.get(0).getContext('2d');
+ var ctx = canvas.get(0).getContext("2d");
ctx.clearRect(0, 0, cw, ch);
// Add Background
- ctx.fillStyle = '#F8EFF9';
+ ctx.fillStyle = "#F8EFF9";
ctx.fillRect(0, 0, cw, ch);
// Generate Grid
- var minorDivisions = spec.divisions.minorCount = ms / minorMs;
- var minorGap = spec.divisions.minorGap = cw / minorDivisions;
+ var minorDivisions = (spec.divisions.minorCount = ms / minorMs);
+ var minorGap = (spec.divisions.minorGap = cw / minorDivisions);
ctx.beginPath();
- for (var x = 0.5 + minorGap; x <= cw; x += minorGap) { // Adding the gap skips the initial line at 0
+ for (var x = 0.5 + minorGap; x <= cw; x += minorGap) {
+ // Adding the gap skips the initial line at 0
var xr = Math.round(x);
+ var nx;
if (xr >= x) {
nx = xr - 0.5;
@@ -369,15 +412,16 @@ app.directive('specDraw', function ($timeout, $document) {
ctx.lineTo(nx, ch);
}
- ctx.strokeStyle = '#E9E0EB';
+ ctx.strokeStyle = "#E9E0EB";
ctx.lineWidth = 1;
ctx.stroke();
- var majorDivisions = spec.divisions.majorCount = ms / majorMs;
- var majorGap = spec.divisions.majorGap = cw / majorDivisions;
+ var majorDivisions = (spec.divisions.majorCount = ms / majorMs);
+ var majorGap = (spec.divisions.majorGap = cw / majorDivisions);
ctx.beginPath();
- for (var x = majorGap; x < cw; x += majorGap) { // Adding the gap skips the initial line at 0
+ for (var x = majorGap; x < cw; x += majorGap) {
+ // Adding the gap skips the initial line at 0
var xr = Math.round(x);
ctx.moveTo(xr, 0);
@@ -394,42 +438,42 @@ app.directive('specDraw', function ($timeout, $document) {
ctx.lineTo(cw - 1, ch);
}
- ctx.strokeStyle = '#E9E0EB';
+ ctx.strokeStyle = "#E9E0EB";
ctx.lineWidth = 2;
ctx.stroke();
- }
+ };
var renderCircle = function (canvas, x) {
- var ctx = canvas.get(0).getContext('2d');
+ var ctx = canvas.get(0).getContext("2d");
ctx.beginPath();
- var y = 30; // y coordinate
- var radius = 5; // Arc radius
- var startAngle = 0; // Starting point on circle
+ var y = 30; // y coordinate
+ var radius = 5; // Arc radius
+ var startAngle = 0; // Starting point on circle
var endAngle = Math.PI * 2; // End point on circle
ctx.arc(x, y, radius, startAngle, endAngle);
- ctx.fillStyle = '#CE93D8';
+ ctx.fillStyle = "#CE93D8";
ctx.fill();
- }
+ };
var renderLine = function (canvas, from, to) {
- var ctx = canvas.get(0).getContext('2d');
+ var ctx = canvas.get(0).getContext("2d");
ctx.beginPath();
ctx.moveTo(from, 30);
ctx.lineTo(to, 30);
- ctx.strokeStyle = '#CE93D8';
+ ctx.strokeStyle = "#CE93D8";
ctx.lineWidth = 2;
ctx.stroke();
- }
+ };
return {
- restrict: 'A',
+ restrict: "A",
scope: {
- specDraw: '=',
- completeFn: '&',
- position: '='
+ specDraw: "=",
+ completeFn: "&",
+ position: "=",
},
link: function (scope, element, attrs) {
var addSpecRow = function (delay, duration) {
@@ -438,60 +482,65 @@ app.directive('specDraw', function ($timeout, $document) {
delayFrames: Math.round(delay / (1000 / scope.specDraw.fps)),
duration: duration, // ms
durationFrames: Math.round(duration / (1000 / scope.specDraw.fps)),
- color: '#737373',
+ color: "#737373",
properties: null,
easing: {
- label: '80% Incoming, 40% Outgoing',
- value: 'quantum',
+ label: "80% Incoming, 40% Outgoing",
+ value: "quantum",
},
easingCustomIncoming: 0,
easingCustomOutgoing: 0,
tag: {
- label: 'None',
- value: 'none'
+ label: "None",
+ value: "none",
},
customTag: null,
comment: null,
- }
+ };
- clearCanvas();
+ clearCanvas(() => {});
scope.$apply(function () {
scope.specDraw.rows.splice(scope.position + 1, 0, row);
});
scope.completeFn();
- }
+ };
var canvas = angular.element(element[0]);
- var creation = {
+ var creation: {
+ startX: number | null;
+ endX: number | null;
+ delay: number | null;
+ duration: number | null;
+ } = {
startX: null,
endX: null,
delay: null,
- duration: null
- }
+ duration: null,
+ };
var getLeft = function (el) {
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var left = rect.left + (window.pageXOffset || docEl.scrollLeft || 0);
return left;
- }
+ };
var getTop = function (el) {
var rect = el.getBoundingClientRect();
var docEl = document.documentElement;
var top = rect.top + (window.pageYOffset || docEl.scrollTop || 0);
return top;
- }
+ };
- element.on('mouseover', function (event) {
+ element.on("mouseover", function (event) {
event.preventDefault();
- $document.on('mousemove', mousemove);
- $document.on('mousedown', mousedown);
- $document.on('mouseup', mouseup);
+ $document.on("mousemove", mousemove);
+ $document.on("mousedown", mousedown);
+ $document.on("mouseup", mouseup);
});
var inBounds = function (event) {
@@ -502,18 +551,21 @@ app.directive('specDraw', function ($timeout, $document) {
var padding = 20;
- if ((offsetLeft > padding || offsetLeft < -canvas.width() - padding) ||
- (offsetTop > padding || offsetTop < -canvas.height() - padding)) {
+ if (
+ offsetLeft > padding ||
+ offsetLeft < -canvas.width() - padding ||
+ offsetTop > padding ||
+ offsetTop < -canvas.height() - padding
+ ) {
return false;
}
return true;
- }
+ };
var mousemove = function (event) {
-
if (!inBounds(event)) {
- clearCanvas();
+ clearCanvas(() => {});
return;
}
@@ -531,19 +583,19 @@ app.directive('specDraw', function ($timeout, $document) {
if (creation.startX !== null) {
// Render initial dot + line
- renderLine(canvas, creation.startX, snappedX)
+ renderLine(canvas, creation.startX, snappedX);
renderCircle(canvas, creation.startX);
renderCircle(canvas, snappedX);
} else {
// Render hover dot only
renderCircle(canvas, snappedX);
}
- }
+ };
var addPoint = function (point, ms) {
if (creation.startX !== null) {
// numMinorDivisions * minor ms - delay = duration for second click
- creation.duration = ms - creation.delay;
+ if (creation.delay) creation.duration = ms - creation.delay;
creation.endX = point;
// Finalize Row
@@ -553,7 +605,7 @@ app.directive('specDraw', function ($timeout, $document) {
creation.delay = ms;
creation.startX = point;
}
- }
+ };
var mousedown = function (event) {
var x = event.pageX;
@@ -567,7 +619,7 @@ app.directive('specDraw', function ($timeout, $document) {
var snappedMs = numMinorDivisions * ms;
addPoint(snappedX, snappedMs);
- }
+ };
var mouseup = function (event) {
var x = event.pageX;
@@ -584,29 +636,33 @@ app.directive('specDraw', function ($timeout, $document) {
if (creation.startX && snappedX !== creation.startX) {
addPoint(snappedX, snappedMs);
}
- }
+ };
var clearCanvas = function (event) {
creation = {
startX: null,
endX: null,
delay: null,
- duration: null
- }
+ duration: null,
+ };
// Clear canvas except for grid
render(canvas, scope.specDraw);
- $document.off('mousemove', mousemove);
- $document.off('mousedown', mousedown);
- }
+ $document.off("mousemove", mousemove);
+ $document.off("mousedown", mousedown);
+ };
// Watch Changes
- scope.$watch('specDraw', function (newValue, oldValue) {
- if (scope.specDraw && scope.specDraw !== undefined) {
- render(canvas, scope.specDraw);
- }
- }, true);
+ scope.$watch(
+ "specDraw",
+ function (newValue, oldValue) {
+ if (scope.specDraw && scope.specDraw !== undefined) {
+ render(canvas, scope.specDraw);
+ }
+ },
+ true
+ );
// Window Width Changes
$(window).resize(function () {
@@ -616,81 +672,90 @@ app.directive('specDraw', function ($timeout, $document) {
});
// Watch for controller to request redraw
- scope.$on('refreshCanvas', function (type) {
+ scope.$on("refreshCanvas", function (type) {
$timeout(function () {
if (scope.specDraw && scope.specDraw !== undefined) {
render(canvas, scope.specDraw);
}
}, 0);
});
- }
- }
+ },
+ };
});
/**
* Popup & Popup Tip Position
*/
-app.directive('specTip', function () {
+app.directive("specTip", function () {
var render = function (tip, spec, totalDuration) {
var duration = spec.duration / totalDuration;
var delay = spec.delay / totalDuration;
- var containerWidth = $('.spec-item-wrap').width();
- var offset = delay + (duration / 2);
- var pixelOffset = offset * containerWidth;
+ var containerWidth = $(".spec-item-wrap").width();
+ var offset = delay + duration / 2;
+ if (containerWidth) {
+ var pixelOffset = offset * containerWidth;
- var centerPoint = pixelOffset - 10; // 10 for tip width
+ var centerPoint = pixelOffset - 10; // 10 for tip width
- tip.css({
- left: centerPoint
- });
- }
+ tip.css({
+ left: centerPoint,
+ });
+ }
+ };
return {
- restrict: 'A',
+ restrict: "A",
scope: {
- specTip: '=',
- duration: '='
+ specTip: "=",
+ duration: "=",
},
link: function (scope, element, attrs) {
var tip = angular.element(element[0]);
// Watch Changes
- scope.$watch('specTip', function (newValue, oldValue) {
- render(tip, scope.specTip, scope.duration);
- }, true);
+ scope.$watch(
+ "specTip",
+ function (newValue, oldValue) {
+ render(tip, scope.specTip, scope.duration);
+ },
+ true
+ );
// Window Width Changes
$(window).resize(function () {
render(tip, scope.specTip, scope.duration);
});
- }
- }
+ },
+ };
});
/**
* Spec Item Resizing
*/
-app.directive('resizer', function ($document) {
+app.directive("resizer", function ($document) {
return {
- restrict: 'A',
+ restrict: "A",
scope: {
- resizerItem: '=',
- resizerSpec: '='
+ resizerItem: "=",
+ resizerSpec: "=",
},
link: function (scope, element, attrs) {
-
- var initial = {
+ var initial: {
+ x: number | null;
+ delay: number | null;
+ duration: number | null;
+ } = {
x: null,
delay: null,
- duration: null
+ duration: null,
};
- element.on('mousedown', function (event) {
+ element.on("mousedown", function (event) {
event.preventDefault();
- $document.on('mousemove', mousemove);
- $document.on('mouseup', mouseup);
- $document.on('contextmenu', mouseup); // cancel on right clicks
+ $document.on("mousemove", mousemove);
+ $document.on("mouseup", mouseup);
+ $document.on("contextmenu", mouseup); // cancel on right clicks
});
var mousemove = function (event) {
@@ -716,90 +781,101 @@ app.directive('resizer', function ($document) {
var mdGap = scope.resizerSpec.canvas.width / mdCount;
var x = event.pageX;
- var dx = x - initial.x;
-
- if (attrs.resizer == 'left') {
- // Handle left resizer
-
- // Snap to minor divisions
- var changeInDivisions = Math.round(dx / mdGap);
-
- // If x increases, reduce delay and add to width
- // If x decreases, add to delay and reduce width
- var changeInMs = changeInDivisions * md;
-
- var newDelay = initial.delay + changeInMs;
- var newDuration = initial.duration - changeInMs;
-
- // Cannot increase if delay + width = 100%
- if (newDelay + newDuration > duration) {
- newDelay = item.delay;
- newDuration = item.duration;
+ if (initial.x) {
+ var dx = x - initial.x;
+
+ if (attrs.resizer == "left") {
+ // Handle left resizer
+
+ // Snap to minor divisions
+ var changeInDivisions = Math.round(dx / mdGap);
+
+ // If x increases, reduce delay and add to width
+ // If x decreases, add to delay and reduce width
+ var changeInMs = changeInDivisions * md;
+
+ if (initial.delay && initial.duration) {
+ var newDelay = initial.delay + changeInMs;
+ var newDuration = initial.duration - changeInMs;
+
+ // Cannot increase if delay + width = 100%
+ if (newDelay + newDuration > duration) {
+ newDelay = item.delay;
+ newDuration = item.duration;
+ }
+
+ // Cannot reduce if width is less than 1 minor division
+ if (newDuration < md) {
+ newDelay = item.delay;
+ newDuration = md;
+ }
+
+ // Cannot increase if delay is 0 (all the way on the left)
+ if (newDelay < 0) {
+ newDelay = 0;
+ newDuration = item.duration;
+ }
+
+ // Apply new width
+ scope.$apply(function () {
+ item.delay = newDelay;
+ item.delayFrames = Math.round(
+ newDelay / (1000 / scope.resizerSpec.fps)
+ );
+ item.duration = newDuration;
+ item.durationFrames = Math.round(
+ newDuration / (1000 / scope.resizerSpec.fps)
+ );
+ });
+ }
+ } else if (attrs.resizer == "right") {
+ // Handle right resizer
+
+ // Snap to minor divisions
+ var changeInDivisions = Math.round(dx / mdGap);
+
+ // If x increases, add to width
+ // If x decreases, reduce width
+ var changeInMs = changeInDivisions * md;
+
+ if (initial.duration) {
+ var newDuration = initial.duration + changeInMs;
+
+ // Cannot increase if delay + width = 100%
+ if (item.delay + newDuration > duration) {
+ newDuration = duration - item.delay;
+ }
+
+ // Cannot reduce if width is less than 1 minor division
+ if (newDuration < md) {
+ newDuration = md;
+ }
+
+ // Apply new width
+ scope.$apply(function () {
+ item.duration = newDuration;
+ item.durationFrames = Math.round(
+ newDuration / (1000 / scope.resizerSpec.fps)
+ );
+ });
+ }
}
-
- // Cannot reduce if width is less than 1 minor division
- if (newDuration < md) {
- newDelay = item.delay;
- newDuration = md;
- }
-
- // Cannot increase if delay is 0 (all the way on the left)
- if (newDelay < 0) {
- newDelay = 0;
- newDuration = item.duration;
- }
-
- // Apply new width
- scope.$apply(function () {
- item.delay = newDelay;
- item.delayFrames = Math.round(newDelay / (1000 / scope.resizerSpec.fps));
- item.duration = newDuration;
- item.durationFrames = Math.round(newDuration / (1000 / scope.resizerSpec.fps));
- });
- } else if (attrs.resizer == 'right') {
- // Handle right resizer
-
- // Snap to minor divisions
- var changeInDivisions = Math.round(dx / mdGap);
-
- // If x increases, add to width
- // If x decreases, reduce width
- var changeInMs = changeInDivisions * md;
-
- var newDuration = initial.duration + changeInMs;
-
- // Cannot increase if delay + width = 100%
- if (item.delay + newDuration > duration) {
- newDuration = duration - item.delay;
- }
-
- // Cannot reduce if width is less than 1 minor division
- if (newDuration < md) {
- newDuration = md;
- }
-
- // Apply new width
- scope.$apply(function () {
- item.duration = newDuration;
- item.durationFrames = Math.round(newDuration / (1000 / scope.resizerSpec.fps));
- });
}
- }
+ };
var mouseup = function () {
initial = {
x: null,
delay: null,
- duration: null
+ duration: null,
};
scope.$parent.setResizingRow(null);
- $document.unbind('mousemove', mousemove);
- $document.unbind('mouseup', mouseup);
- $document.unbind('contextmenu', mouseup);
- }
-
- }
- }
+ $document.unbind("mousemove", mousemove);
+ $document.unbind("mouseup", mouseup);
+ $document.unbind("contextmenu", mouseup);
+ };
+ },
+ };
});
diff --git a/app/ts/config.ts b/app/ts/config.ts
new file mode 100644
index 0000000..fc32876
--- /dev/null
+++ b/app/ts/config.ts
@@ -0,0 +1,9 @@
+(function (window) {
+ window.__directConfig = window.__directConfig || {};
+
+ window.__directConfig.stagingDomain = "staging.example.com";
+ window.__directConfig.productionDomain = "example.com";
+})(
+ // @ts-ignore
+ this
+);
diff --git a/app/ts/config_sample.ts b/app/ts/config_sample.ts
new file mode 100644
index 0000000..fc32876
--- /dev/null
+++ b/app/ts/config_sample.ts
@@ -0,0 +1,9 @@
+(function (window) {
+ window.__directConfig = window.__directConfig || {};
+
+ window.__directConfig.stagingDomain = "staging.example.com";
+ window.__directConfig.productionDomain = "example.com";
+})(
+ // @ts-ignore
+ this
+);
diff --git a/app/js/filters.ts b/app/ts/filters.ts
similarity index 95%
rename from app/js/filters.ts
rename to app/ts/filters.ts
index 074a4e9..d436231 100755
--- a/app/js/filters.ts
+++ b/app/ts/filters.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
app.filter("nl2br", [
"$sce",
function ($sce) {
diff --git a/app/js/gapi.ts b/app/ts/gapi.ts
similarity index 98%
rename from app/js/gapi.ts
rename to app/ts/gapi.ts
index 382536c..556f7cb 100644
--- a/app/js/gapi.ts
+++ b/app/ts/gapi.ts
@@ -16,6 +16,10 @@
These API keys are Javascript API keys that must be included client side.
We have an HTTP referrer whitelist server-side to prevent quota misuse.
*/
+
+declare const gapi;
+declare const google;
+
var developerKey = "AIzaSyAwMg3spfEqfQyCUR1OXfyCAse3GzxpxJM";
var clientId =
"103309234391-nak808obap92p3i1cslqi1oubsfnub1m.apps.googleusercontent.com";
diff --git a/app/js/groupCtrl.ts b/app/ts/groupCtrl.ts
similarity index 96%
rename from app/js/groupCtrl.ts
rename to app/ts/groupCtrl.ts
index c21856b..e5086b9 100755
--- a/app/js/groupCtrl.ts
+++ b/app/ts/groupCtrl.ts
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
+declare const angular;
+
app.controller(
"groupCtrl",
function ($scope, $routeParams, Spec, projectListService) {
diff --git a/app/js/projectListService.ts b/app/ts/projectListService.ts
similarity index 95%
rename from app/js/projectListService.ts
rename to app/ts/projectListService.ts
index 359432d..35dabfa 100644
--- a/app/js/projectListService.ts
+++ b/app/ts/projectListService.ts
@@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
app.service("projectListService", function () {
// multispec selection
-
+ // @ts-ignore
this.toggleSelected = function ($scope, item) {
var idx = $scope.selected.indexOf(item);
if (idx > -1) {
@@ -23,11 +25,11 @@ app.service("projectListService", function () {
$scope.selected.push(item);
}
};
-
+ // @ts-ignore
this.isSelected = function ($scope, item) {
return $scope.selected.indexOf(item) > -1;
};
-
+ // @ts-ignore
this.selectedToRouteParam = function ($scope) {
return $scope.selected
.map(function (spec) {
@@ -37,7 +39,7 @@ app.service("projectListService", function () {
};
// project list construction
-
+ // @ts-ignore
this.addProject = function ($scope, spec) {
var i = $scope.projectGroups.length;
var projectAdded = false;
@@ -62,12 +64,12 @@ app.service("projectListService", function () {
projects: [],
handle: spec.group,
};
-
+ // @ts-ignore
grp.projects.push(spec);
$scope.projectGroups.push(grp);
}
};
-
+ // @ts-ignore
this.deleteProject = function ($scope, project) {
for (var i = 0; i < $scope.projectGroups.length; i++) {
if (
diff --git a/app/js/sidebarCtrl.ts b/app/ts/sidebarCtrl.ts
similarity index 94%
rename from app/js/sidebarCtrl.ts
rename to app/ts/sidebarCtrl.ts
index d868a42..db497ab 100755
--- a/app/js/sidebarCtrl.ts
+++ b/app/ts/sidebarCtrl.ts
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
+declare const angular;
+
app.controller("sidebarCtrl", function ($scope, Spec, projectListService) {
// Project Listing for Sidebar
diff --git a/app/js/specCtrl.ts b/app/ts/specCtrl.ts
similarity index 99%
rename from app/js/specCtrl.ts
rename to app/ts/specCtrl.ts
index 98145d8..854dc11 100755
--- a/app/js/specCtrl.ts
+++ b/app/ts/specCtrl.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
app.controller("specCtrl", function ($scope, $routeParams, $sce, $location) {
// Initial Config
$scope.uiState = {
diff --git a/app/js/specDirectives.ts b/app/ts/specDirectives.ts
similarity index 95%
rename from app/js/specDirectives.ts
rename to app/ts/specDirectives.ts
index e42b054..41638f3 100644
--- a/app/js/specDirectives.ts
+++ b/app/ts/specDirectives.ts
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// @ts-nocheck
+import { app } from "./app.js";
/*
* initializes wrapperElem for specTabCtrl scope
@@ -127,7 +127,9 @@ app.directive("scrubbable", function () {
var updateTimestamp = function () {
// request angular to update value for video.currentTime in UI
scope.$apply();
- }.throttle(); // rate limit this event to one / 100ms (to prevent ui lag)
+ }
+ // @ts-ignore
+ .throttle(); // rate limit this event to one / 100ms (to prevent ui lag)
video.addEventListener("seeking", function () {
window.requestAnimationFrame(onTimeUpdate);
@@ -140,6 +142,7 @@ app.directive("scrubbable", function () {
var constrainScrubberX = function (x) {
var gridWidth = $(gridContainment).find(".spec-grid").width();
var durationX = secondsToX(video.duration);
+ // @ts-ignore
var maxAllowedX = Math.min(durationX, gridWidth);
x = Math.min(x, maxAllowedX);
x = Math.max(x, 0);
@@ -165,11 +168,14 @@ app.directive("scrubbable", function () {
video.currentTime = timestampSeconds;
window.requestAnimationFrame(onTimeUpdate);
}
- }.throttle(); // rate limit this event to one / 100ms (to prevent ui lag)
+ }
+ // @ts-ignore
+ .throttle(); // rate limit this event to one / 100ms (to prevent ui lag)
// listen to mouse events on the scrub handle
$(gridContainment).one("mouseover", ".spec-grid-scrubber", function () {
var scrubber = $(this);
+ // @ts-ignore
scrubber.draggable({
axis: "x",
cursorAt: { left: 0 },
diff --git a/app/js/specResource.ts b/app/ts/specResource.ts
similarity index 96%
rename from app/js/specResource.ts
rename to app/ts/specResource.ts
index a6ca2bc..e80cf36 100755
--- a/app/js/specResource.ts
+++ b/app/ts/specResource.ts
@@ -12,9 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// @ts-nocheck
+import { app } from "./app.js";
app.provider("Spec", function () {
+ // @ts-ignore
this.$get = [
"$resource",
"envService",
@@ -22,6 +23,7 @@ app.provider("Spec", function () {
"$timeout",
function ($resource, envService, localStorageService, $timeout) {
if (envService.is("production")) {
+ // @ts-ignore
var Spec = $resource(
"/api/spec/:id",
{},
@@ -33,6 +35,7 @@ app.provider("Spec", function () {
);
} else {
// not on a production environment, return mocked Spec with localStorage
+ // @ts-ignore
var Spec = {
query: function (params, callback) {
console.log("localstorage query");
@@ -55,6 +58,7 @@ app.provider("Spec", function () {
});
if (isMatch) {
flat.group = spec.group; // return group name
+ // @ts-ignore
specs.push(flat);
}
});
diff --git a/app/js/specTabCtrl.ts b/app/ts/specTabCtrl.ts
similarity index 99%
rename from app/js/specTabCtrl.ts
rename to app/ts/specTabCtrl.ts
index 2b7f7a9..257bc50 100755
--- a/app/js/specTabCtrl.ts
+++ b/app/ts/specTabCtrl.ts
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
app.controller(
"specTabCtrl",
function ($scope, $location, $filter, $sce, Spec, storageService) {
diff --git a/app/js/storageService.ts b/app/ts/storageService.ts
similarity index 98%
rename from app/js/storageService.ts
rename to app/ts/storageService.ts
index 9d56d80..4a242a8 100644
--- a/app/js/storageService.ts
+++ b/app/ts/storageService.ts
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
+declare const angular;
+
app.service(
"storageService",
function storageService($timeout, $location, Spec) {
diff --git a/app/js/userCtrl.ts b/app/ts/userCtrl.ts
similarity index 96%
rename from app/js/userCtrl.ts
rename to app/ts/userCtrl.ts
index 1a69dbe..4b06526 100755
--- a/app/js/userCtrl.ts
+++ b/app/ts/userCtrl.ts
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import { app } from "./app.js";
+
+declare const angular;
+
app.controller(
"userCtrl",
function ($scope, $routeParams, Spec, projectListService) {
diff --git a/package-lock.json b/package-lock.json
index d66485e..18e3e2f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,21 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@types/jquery": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz",
+ "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==",
+ "dev": true,
+ "requires": {
+ "@types/sizzle": "*"
+ }
+ },
+ "@types/sizzle": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
+ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
+ "dev": true
+ },
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
diff --git a/package.json b/package.json
index f79e5e5..579e7a5 100644
--- a/package.json
+++ b/package.json
@@ -4,8 +4,10 @@
"description": "Direct is a tool that helps motion designers provide clear, precise motion direction for engineers.",
"private": true,
"main": "index.js",
+ "type": "module",
"scripts": {
- "serve": "tsc && sudo dev_appserver.py .",
+ "ts": "tsc",
+ "serve": "npm run ts && sudo dev_appserver.py .",
"setup": "bower install"
},
"dependencies": {
@@ -23,6 +25,7 @@
"js-throttle-debounce": "^0.1.1"
},
"devDependencies": {
+ "@types/jquery": "^3.5.5",
"bower": "^1.8.0",
"json-server": "^0.9.6",
"rimraf": "^2.6.2",
@@ -42,4 +45,4 @@
"url": "https://github.com/rodydavis/direct/issues"
},
"homepage": "https://github.com/rodydavis/direct#readme"
-}
+}
\ No newline at end of file
diff --git a/templates/index.html b/templates/index.html
index a6555a5..1b2f4b8 100755
--- a/templates/index.html
+++ b/templates/index.html
@@ -41,21 +41,22 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+