React/Redux - publish component #323
10 changed files with 1089 additions and 237 deletions
|
@ -1,46 +1,3 @@
|
||||||
|
|
||||||
function drop_handler(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
// if dropped items aren't files, reject them
|
|
||||||
var dt = event.dataTransfer;
|
|
||||||
if (dt.items) {
|
|
||||||
if (dt.items[0].kind == 'file') {
|
|
||||||
var droppedFile = dt.items[0].getAsFile();
|
|
||||||
publishFileFunctions.previewAndStageFile(droppedFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragover_handler(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragend_handler(event) {
|
|
||||||
var dt = event.dataTransfer;
|
|
||||||
if (dt.items) {
|
|
||||||
for (var i = 0; i < dt.items.length; i++) {
|
|
||||||
dt.items.remove(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
event.dataTransfer.clearData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragenter_handler(event) {
|
|
||||||
var thisDropzone = document.getElementById(event.target.id);
|
|
||||||
thisDropzone.setAttribute('class', 'dropzone dropzone--drag-over row row--margined row--padded row--tall flex-container--column flex-container--center-center');
|
|
||||||
thisDropzone.firstElementChild.setAttribute('class', 'hidden');
|
|
||||||
thisDropzone.lastElementChild.setAttribute('class', '');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function dragexit_handler(event) {
|
|
||||||
var thisDropzone = document.getElementById(event.target.id);
|
|
||||||
thisDropzone.setAttribute('class', 'dropzone row row--tall row--margined row--padded flex-container--column flex-container--center-center');
|
|
||||||
thisDropzone.firstElementChild.setAttribute('class', '');
|
|
||||||
thisDropzone.lastElementChild.setAttribute('class', 'hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
function preview_onmouseenter_handler () {
|
function preview_onmouseenter_handler () {
|
||||||
document.getElementById('asset-preview-dropzone-instructions').setAttribute('class', 'flex-container--column flex-container--center-center position-absolute');
|
document.getElementById('asset-preview-dropzone-instructions').setAttribute('class', 'flex-container--column flex-container--center-center position-absolute');
|
||||||
document.getElementById('asset-preview').style.opacity = 0.2;
|
document.getElementById('asset-preview').style.opacity = 0.2;
|
||||||
|
|
|
@ -1,68 +1,16 @@
|
||||||
var stagedFiles = null;
|
var stagedFiles = null;
|
||||||
|
|
||||||
const publishFileFunctions = {
|
const publishFileFunctions = {
|
||||||
triggerFileChooser: function (fileInputId) {
|
|
||||||
document.getElementById(fileInputId).click();
|
|
||||||
},
|
|
||||||
cancelPublish: function () {
|
cancelPublish: function () {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
},
|
},
|
||||||
previewAndStageFile: function (selectedFile) {
|
|
||||||
const fileSelectionInputError = document.getElementById('input-error-file-selection');
|
|
||||||
// When a file is selected for publish, validate that file and
|
|
||||||
// stage it so it will be ready when the publish button is clicked
|
|
||||||
try {
|
|
||||||
validationFunctions.validateFile(selectedFile); // validate the file's name, type, and size
|
|
||||||
} catch (error) {
|
|
||||||
validationFunctions.showError(fileSelectionInputError, error.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// set image preview, if an image was provided
|
|
||||||
this.setImagePreview(selectedFile);
|
|
||||||
// hide the primary drop zone
|
|
||||||
this.hidePrimaryDropzone();
|
|
||||||
// set the name input value to the image name if none is set yet
|
|
||||||
this.updateClaimNameInputWithFileName(selectedFile);
|
|
||||||
// store the selected file for upload
|
|
||||||
stagedFiles = [selectedFile];
|
|
||||||
},
|
|
||||||
hidePrimaryDropzone: function () {
|
hidePrimaryDropzone: function () {
|
||||||
const primaryDropzone = document.getElementById('primary-dropzone');
|
const primaryDropzone = document.getElementById('primary-dropzone');
|
||||||
const publishForm = document.getElementById('publish-form');
|
const publishForm = document.getElementById('publish-form');
|
||||||
primaryDropzone.setAttribute('class', 'hidden');
|
primaryDropzone.setAttribute('class', 'hidden');
|
||||||
publishForm.setAttribute('class', 'row')
|
publishForm.setAttribute('class', 'row')
|
||||||
},
|
},
|
||||||
updateClaimNameInputWithFileName: function (selectedFile) {
|
|
||||||
const nameInput = document.getElementById('claim-name-input');
|
|
||||||
if (nameInput.value === "") {
|
|
||||||
var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.'))
|
|
||||||
nameInput.value = validationFunctions.cleanseClaimName(filename);
|
|
||||||
validationFunctions.checkClaimName(nameInput.value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
setImagePreview: function (selectedFile) {
|
|
||||||
const assetPreview = document.getElementById('asset-preview-target');
|
|
||||||
const thumbnailInput = document.getElementById('claim-thumbnail-input');
|
|
||||||
const thumbnailInputTool = document.getElementById('publish-thumbnail');
|
|
||||||
if (selectedFile.type !== 'video/mp4') {
|
|
||||||
const previewReader = new FileReader();
|
|
||||||
if (selectedFile.type === 'image/gif') {
|
|
||||||
assetPreview.innerHTML = `<p>loading preview...</p>`
|
|
||||||
}
|
|
||||||
previewReader.readAsDataURL(selectedFile);
|
|
||||||
previewReader.onloadend = function () {
|
|
||||||
assetPreview.innerHTML = '<img id="asset-preview" src="' + previewReader.result + '" alt="image preview"/>';
|
|
||||||
};
|
|
||||||
// clear & hide the thumbnail selection input
|
|
||||||
thumbnailInput.value = '';
|
|
||||||
thumbnailInputTool.hidden = true;
|
|
||||||
} else {
|
|
||||||
assetPreview.innerHTML = `<img id="asset-preview" src="/assets/img/video_thumb_default.png"/>`;
|
|
||||||
// clear & show the thumbnail selection input
|
|
||||||
thumbnailInput.value = '';
|
|
||||||
thumbnailInputTool.hidden = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
returnNullOrChannel: function () {
|
returnNullOrChannel: function () {
|
||||||
const channelRadio = document.getElementById('channel-radio');
|
const channelRadio = document.getElementById('channel-radio');
|
||||||
if (channelRadio.checked) {
|
if (channelRadio.checked) {
|
||||||
|
|
|
@ -257,6 +257,21 @@ process.umask = function() { return 0; };
|
||||||
/* 1 */
|
/* 1 */
|
||||||
/***/ (function(module, exports, __webpack_require__) {
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
/* WEBPACK VAR INJECTION */(function(process) {
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
module.exports = __webpack_require__(15);
|
||||||
|
} else {
|
||||||
|
module.exports = __webpack_require__(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 2 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,7 +311,7 @@ emptyFunction.thatReturnsArgument = function (arg) {
|
||||||
module.exports = emptyFunction;
|
module.exports = emptyFunction;
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 2 */
|
/* 3 */
|
||||||
/***/ (function(module, exports, __webpack_require__) {
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -393,7 +408,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) {
|
||||||
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 3 */
|
/* 4 */
|
||||||
/***/ (function(module, exports, __webpack_require__) {
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
@ -416,21 +431,6 @@ if (process.env.NODE_ENV !== 'production') {
|
||||||
module.exports = emptyObject;
|
module.exports = emptyObject;
|
||||||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
|
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
|
||||||
|
|
||||||
/***/ }),
|
|
||||||
/* 4 */
|
|
||||||
/***/ (function(module, exports, __webpack_require__) {
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
/* WEBPACK VAR INJECTION */(function(process) {
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
|
||||||
module.exports = __webpack_require__(15);
|
|
||||||
} else {
|
|
||||||
module.exports = __webpack_require__(16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0)))
|
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 5 */
|
/* 5 */
|
||||||
/***/ (function(module, exports, __webpack_require__) {
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
@ -506,7 +506,7 @@ module.exports = invariant;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var emptyFunction = __webpack_require__(1);
|
var emptyFunction = __webpack_require__(2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to invariant but only logs a warning if the condition is not met.
|
* Similar to invariant but only logs a warning if the condition is not met.
|
||||||
|
@ -682,7 +682,7 @@ module.exports = ExecutionEnvironment;
|
||||||
* @typechecks
|
* @typechecks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var emptyFunction = __webpack_require__(1);
|
var emptyFunction = __webpack_require__(2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upstream version of event listener. Does not take into account specific
|
* Upstream version of event listener. Does not take into account specific
|
||||||
|
@ -942,7 +942,7 @@ module.exports = focusNode;
|
||||||
|
|
||||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
var _react = __webpack_require__(4);
|
var _react = __webpack_require__(1);
|
||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
@ -950,40 +950,107 @@ var _reactDom = __webpack_require__(18);
|
||||||
|
|
||||||
var _reactDom2 = _interopRequireDefault(_reactDom);
|
var _reactDom2 = _interopRequireDefault(_reactDom);
|
||||||
|
|
||||||
|
var _dropzone = __webpack_require__(27);
|
||||||
|
|
||||||
|
var _dropzone2 = _interopRequireDefault(_dropzone);
|
||||||
|
|
||||||
|
var _publishDetails = __webpack_require__(28);
|
||||||
|
|
||||||
|
var _publishDetails2 = _interopRequireDefault(_publishDetails);
|
||||||
|
|
||||||
|
var _publishStatus = __webpack_require__(29);
|
||||||
|
|
||||||
|
var _publishStatus2 = _interopRequireDefault(_publishStatus);
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||||
|
|
||||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
var App = function (_React$Component) {
|
var DROPZONE = 'DROPZONE';
|
||||||
_inherits(App, _React$Component);
|
var DETAILS = 'DETAILS';
|
||||||
|
var STATUS = 'STATUS';
|
||||||
|
|
||||||
function App() {
|
var Uploader = function (_React$Component) {
|
||||||
_classCallCheck(this, App);
|
_inherits(Uploader, _React$Component);
|
||||||
|
|
||||||
return _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).apply(this, arguments));
|
function Uploader(props) {
|
||||||
|
_classCallCheck(this, Uploader);
|
||||||
|
|
||||||
|
var _this = _possibleConstructorReturn(this, (Uploader.__proto__ || Object.getPrototypeOf(Uploader)).call(this, props));
|
||||||
|
|
||||||
|
_this.state = {
|
||||||
|
showComponent: DROPZONE, // DROPZONE, DETAILS, or PUBLISHING
|
||||||
|
file: null,
|
||||||
|
title: '',
|
||||||
|
channel: '',
|
||||||
|
url: '',
|
||||||
|
thumbnail: '',
|
||||||
|
description: '',
|
||||||
|
license: '',
|
||||||
|
nsfw: ''
|
||||||
|
};
|
||||||
|
// bind class methods with `this`
|
||||||
|
_this.updateUploaderState = _this.updateUploaderState.bind(_this);
|
||||||
|
_this.showComponent = _this.showComponent.bind(_this);
|
||||||
|
_this.stageFileAndShowDetails = _this.stageFileAndShowDetails.bind(_this);
|
||||||
|
return _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_createClass(App, [{
|
_createClass(Uploader, [{
|
||||||
|
key: 'updateUploaderState',
|
||||||
|
value: function updateUploaderState(name, value) {
|
||||||
|
console.log('updateUploaderState ' + name + ' ' + value);
|
||||||
|
this.setState(_defineProperty({}, name, value));
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'showComponent',
|
||||||
|
value: function showComponent(component) {
|
||||||
|
this.setState({ showComponent: component });
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'stageFileAndShowDetails',
|
||||||
|
value: function stageFileAndShowDetails(selectedFile) {
|
||||||
|
console.log('stageFileAndShowDetails', selectedFile);
|
||||||
|
// store the selected file for upload
|
||||||
|
this.setState({ 'file': selectedFile });
|
||||||
|
// hide the dropzone and show the details
|
||||||
|
this.showComponent(DETAILS);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
return _react2.default.createElement(
|
return _react2.default.createElement(
|
||||||
'h1',
|
'div',
|
||||||
null,
|
null,
|
||||||
'Hello, I am a react app'
|
this.state.showComponent === DROPZONE && _react2.default.createElement(_dropzone2.default, { stageFileAndShowDetails: this.stageFileAndShowDetails }),
|
||||||
|
this.state.showComponent === DETAILS && _react2.default.createElement(_publishDetails2.default, {
|
||||||
|
updateUploaderState: this.updateUploaderState,
|
||||||
|
file: this.state.file,
|
||||||
|
title: this.state.title,
|
||||||
|
channel: this.state.channel,
|
||||||
|
url: this.state.url,
|
||||||
|
thumbnail: this.state.thumbnail,
|
||||||
|
description: this.state.description,
|
||||||
|
license: this.state.license,
|
||||||
|
nsfw: this.state.nsfw
|
||||||
|
}),
|
||||||
|
this.state.showComponent === STATUS && _react2.default.createElement(_publishStatus2.default, null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return App;
|
return Uploader;
|
||||||
}(_react2.default.Component);
|
}(_react2.default.Component);
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
_reactDom2.default.render(_react2.default.createElement(App, null), document.getElementById('react-app'));
|
_reactDom2.default.render(_react2.default.createElement(Uploader, null), document.getElementById('react-uploader'));
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 15 */
|
/* 15 */
|
||||||
|
@ -999,7 +1066,7 @@ _reactDom2.default.render(_react2.default.createElement(App, null), document.get
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var m=__webpack_require__(2),n=__webpack_require__(3),p=__webpack_require__(1),q="function"===typeof Symbol&&Symbol["for"],r=q?Symbol["for"]("react.element"):60103,t=q?Symbol["for"]("react.call"):60104,u=q?Symbol["for"]("react.return"):60105,v=q?Symbol["for"]("react.portal"):60106,w=q?Symbol["for"]("react.fragment"):60107,x="function"===typeof Symbol&&Symbol.iterator;
|
var m=__webpack_require__(3),n=__webpack_require__(4),p=__webpack_require__(2),q="function"===typeof Symbol&&Symbol["for"],r=q?Symbol["for"]("react.element"):60103,t=q?Symbol["for"]("react.call"):60104,u=q?Symbol["for"]("react.return"):60105,v=q?Symbol["for"]("react.portal"):60106,w=q?Symbol["for"]("react.fragment"):60107,x="function"===typeof Symbol&&Symbol.iterator;
|
||||||
function y(a){for(var b=arguments.length-1,e="Minified React error #"+a+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant\x3d"+a,c=0;c<b;c++)e+="\x26args[]\x3d"+encodeURIComponent(arguments[c+1]);b=Error(e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");b.name="Invariant Violation";b.framesToPop=1;throw b;}
|
function y(a){for(var b=arguments.length-1,e="Minified React error #"+a+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant\x3d"+a,c=0;c<b;c++)e+="\x26args[]\x3d"+encodeURIComponent(arguments[c+1]);b=Error(e+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");b.name="Invariant Violation";b.framesToPop=1;throw b;}
|
||||||
var z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};function A(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}A.prototype.isReactComponent={};A.prototype.setState=function(a,b){"object"!==typeof a&&"function"!==typeof a&&null!=a?y("85"):void 0;this.updater.enqueueSetState(this,a,b,"setState")};A.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};
|
var z={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}};function A(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}A.prototype.isReactComponent={};A.prototype.setState=function(a,b){"object"!==typeof a&&"function"!==typeof a&&null!=a?y("85"):void 0;this.updater.enqueueSetState(this,a,b,"setState")};A.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate")};
|
||||||
function B(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}function C(){}C.prototype=A.prototype;var D=B.prototype=new C;D.constructor=B;m(D,A.prototype);D.isPureReactComponent=!0;function E(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}var F=E.prototype=new C;F.constructor=E;m(F,A.prototype);F.unstable_isAsyncReactComponent=!0;F.render=function(){return this.props.children};var G={current:null},H=Object.prototype.hasOwnProperty,I={key:!0,ref:!0,__self:!0,__source:!0};
|
function B(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}function C(){}C.prototype=A.prototype;var D=B.prototype=new C;D.constructor=B;m(D,A.prototype);D.isPureReactComponent=!0;function E(a,b,e){this.props=a;this.context=b;this.refs=n;this.updater=e||z}var F=E.prototype=new C;F.constructor=E;m(F,A.prototype);F.unstable_isAsyncReactComponent=!0;F.render=function(){return this.props.children};var G={current:null},H=Object.prototype.hasOwnProperty,I={key:!0,ref:!0,__self:!0,__source:!0};
|
||||||
|
@ -1035,11 +1102,11 @@ if (process.env.NODE_ENV !== "production") {
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var _assign = __webpack_require__(2);
|
var _assign = __webpack_require__(3);
|
||||||
var emptyObject = __webpack_require__(3);
|
var emptyObject = __webpack_require__(4);
|
||||||
var invariant = __webpack_require__(5);
|
var invariant = __webpack_require__(5);
|
||||||
var warning = __webpack_require__(6);
|
var warning = __webpack_require__(6);
|
||||||
var emptyFunction = __webpack_require__(1);
|
var emptyFunction = __webpack_require__(2);
|
||||||
var checkPropTypes = __webpack_require__(7);
|
var checkPropTypes = __webpack_require__(7);
|
||||||
|
|
||||||
// TODO: this is special because it gets imported during build.
|
// TODO: this is special because it gets imported during build.
|
||||||
|
@ -2460,7 +2527,7 @@ if (process.env.NODE_ENV === 'production') {
|
||||||
/*
|
/*
|
||||||
Modernizr 3.0.0pre (Custom Build) | MIT
|
Modernizr 3.0.0pre (Custom Build) | MIT
|
||||||
*/
|
*/
|
||||||
var aa=__webpack_require__(4),l=__webpack_require__(8),B=__webpack_require__(2),C=__webpack_require__(1),ba=__webpack_require__(9),da=__webpack_require__(10),ea=__webpack_require__(11),fa=__webpack_require__(12),ia=__webpack_require__(13),D=__webpack_require__(3);
|
var aa=__webpack_require__(1),l=__webpack_require__(8),B=__webpack_require__(3),C=__webpack_require__(2),ba=__webpack_require__(9),da=__webpack_require__(10),ea=__webpack_require__(11),fa=__webpack_require__(12),ia=__webpack_require__(13),D=__webpack_require__(4);
|
||||||
function E(a){for(var b=arguments.length-1,c="Minified React error #"+a+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant\x3d"+a,d=0;d<b;d++)c+="\x26args[]\x3d"+encodeURIComponent(arguments[d+1]);b=Error(c+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");b.name="Invariant Violation";b.framesToPop=1;throw b;}aa?void 0:E("227");
|
function E(a){for(var b=arguments.length-1,c="Minified React error #"+a+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant\x3d"+a,d=0;d<b;d++)c+="\x26args[]\x3d"+encodeURIComponent(arguments[d+1]);b=Error(c+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.");b.name="Invariant Violation";b.framesToPop=1;throw b;}aa?void 0:E("227");
|
||||||
var oa={children:!0,dangerouslySetInnerHTML:!0,defaultValue:!0,defaultChecked:!0,innerHTML:!0,suppressContentEditableWarning:!0,suppressHydrationWarning:!0,style:!0};function pa(a,b){return(a&b)===b}
|
var oa={children:!0,dangerouslySetInnerHTML:!0,defaultValue:!0,defaultChecked:!0,innerHTML:!0,suppressContentEditableWarning:!0,suppressHydrationWarning:!0,style:!0};function pa(a,b){return(a&b)===b}
|
||||||
var ta={MUST_USE_PROPERTY:1,HAS_BOOLEAN_VALUE:4,HAS_NUMERIC_VALUE:8,HAS_POSITIVE_NUMERIC_VALUE:24,HAS_OVERLOADED_BOOLEAN_VALUE:32,HAS_STRING_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(a){var b=ta,c=a.Properties||{},d=a.DOMAttributeNamespaces||{},e=a.DOMAttributeNames||{};a=a.DOMMutationMethods||{};for(var f in c){ua.hasOwnProperty(f)?E("48",f):void 0;var g=f.toLowerCase(),h=c[f];g={attributeName:g,attributeNamespace:null,propertyName:f,mutationMethod:null,mustUseProperty:pa(h,b.MUST_USE_PROPERTY),
|
var ta={MUST_USE_PROPERTY:1,HAS_BOOLEAN_VALUE:4,HAS_NUMERIC_VALUE:8,HAS_POSITIVE_NUMERIC_VALUE:24,HAS_OVERLOADED_BOOLEAN_VALUE:32,HAS_STRING_BOOLEAN_VALUE:64,injectDOMPropertyConfig:function(a){var b=ta,c=a.Properties||{},d=a.DOMAttributeNamespaces||{},e=a.DOMAttributeNames||{};a=a.DOMMutationMethods||{};for(var f in c){ua.hasOwnProperty(f)?E("48",f):void 0;var g=f.toLowerCase(),h=c[f];g={attributeName:g,attributeNamespace:null,propertyName:f,mutationMethod:null,mustUseProperty:pa(h,b.MUST_USE_PROPERTY),
|
||||||
|
@ -2757,18 +2824,18 @@ if (process.env.NODE_ENV !== "production") {
|
||||||
(function() {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = __webpack_require__(4);
|
var React = __webpack_require__(1);
|
||||||
var invariant = __webpack_require__(5);
|
var invariant = __webpack_require__(5);
|
||||||
var warning = __webpack_require__(6);
|
var warning = __webpack_require__(6);
|
||||||
var ExecutionEnvironment = __webpack_require__(8);
|
var ExecutionEnvironment = __webpack_require__(8);
|
||||||
var _assign = __webpack_require__(2);
|
var _assign = __webpack_require__(3);
|
||||||
var emptyFunction = __webpack_require__(1);
|
var emptyFunction = __webpack_require__(2);
|
||||||
var EventListener = __webpack_require__(9);
|
var EventListener = __webpack_require__(9);
|
||||||
var getActiveElement = __webpack_require__(10);
|
var getActiveElement = __webpack_require__(10);
|
||||||
var shallowEqual = __webpack_require__(11);
|
var shallowEqual = __webpack_require__(11);
|
||||||
var containsNode = __webpack_require__(12);
|
var containsNode = __webpack_require__(12);
|
||||||
var focusNode = __webpack_require__(13);
|
var focusNode = __webpack_require__(13);
|
||||||
var emptyObject = __webpack_require__(3);
|
var emptyObject = __webpack_require__(4);
|
||||||
var checkPropTypes = __webpack_require__(7);
|
var checkPropTypes = __webpack_require__(7);
|
||||||
var hyphenateStyleName = __webpack_require__(23);
|
var hyphenateStyleName = __webpack_require__(23);
|
||||||
var camelizeStyleName = __webpack_require__(25);
|
var camelizeStyleName = __webpack_require__(25);
|
||||||
|
@ -18293,5 +18360,654 @@ function camelize(string) {
|
||||||
|
|
||||||
module.exports = camelize;
|
module.exports = camelize;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 27 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
var _react = __webpack_require__(1);
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
|
var Dropzone = function (_React$Component) {
|
||||||
|
_inherits(Dropzone, _React$Component);
|
||||||
|
|
||||||
|
function Dropzone(props) {
|
||||||
|
_classCallCheck(this, Dropzone);
|
||||||
|
|
||||||
|
var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this, props));
|
||||||
|
|
||||||
|
_this.state = {
|
||||||
|
fileError: null
|
||||||
|
};
|
||||||
|
_this.handleDrop = _this.handleDrop.bind(_this);
|
||||||
|
_this.handleDragOver = _this.handleDragOver.bind(_this);
|
||||||
|
_this.handleDragEnd = _this.handleDragEnd.bind(_this);
|
||||||
|
_this.handleDragEnter = _this.handleDragEnter.bind(_this);
|
||||||
|
_this.handleDragLeave = _this.handleDragLeave.bind(_this);
|
||||||
|
_this.handleClick = _this.handleClick.bind(_this);
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Dropzone, [{
|
||||||
|
key: 'validateFile',
|
||||||
|
value: function validateFile(file) {
|
||||||
|
if (!file) {
|
||||||
|
console.log('no file found');
|
||||||
|
throw new Error('no file provided');
|
||||||
|
}
|
||||||
|
if (/'/.test(file.name)) {
|
||||||
|
console.log('file name had apostrophe in it');
|
||||||
|
throw new Error('apostrophes are not allowed in the file name');
|
||||||
|
}
|
||||||
|
// validate size and type
|
||||||
|
switch (file.type) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/png':
|
||||||
|
if (file.size > 10000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, images are limited to 10 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'image/gif':
|
||||||
|
if (file.size > 50000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, .gifs are limited to 50 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'video/mp4':
|
||||||
|
if (file.size > 50000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, videos are limited to 50 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('file type is not supported');
|
||||||
|
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleDrop',
|
||||||
|
value: function handleDrop(event) {
|
||||||
|
console.log('handleDrop', event);
|
||||||
|
event.preventDefault();
|
||||||
|
// if dropped items aren't files, reject them
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
console.log('dt', dt);
|
||||||
|
if (dt.items) {
|
||||||
|
if (dt.items[0].kind == 'file') {
|
||||||
|
var droppedFile = dt.items[0].getAsFile();
|
||||||
|
console.log('droppedFile', droppedFile);
|
||||||
|
// When a file is selected for publish, validate that file and
|
||||||
|
try {
|
||||||
|
this.validateFile(droppedFile); // validate the file's name, type, and size
|
||||||
|
} catch (error) {
|
||||||
|
return this.setState('fileError', error.message);
|
||||||
|
}
|
||||||
|
// stage it so it will be ready when the publish button is clicked
|
||||||
|
this.props.stageFileAndShowDetails(droppedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleDragOver',
|
||||||
|
value: function handleDragOver(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleDragEnd',
|
||||||
|
value: function handleDragEnd(event) {
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.items) {
|
||||||
|
for (var i = 0; i < dt.items.length; i++) {
|
||||||
|
dt.items.remove(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.dataTransfer.clearData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleDragEnter',
|
||||||
|
value: function handleDragEnter() {
|
||||||
|
var thisDropzone = document.getElementById('primary-dropzone');
|
||||||
|
thisDropzone.setAttribute('class', 'dropzone dropzone--drag-over row row--margined row--padded row--tall flex-container--column flex-container--center-center');
|
||||||
|
thisDropzone.firstElementChild.setAttribute('class', 'hidden');
|
||||||
|
thisDropzone.lastElementChild.setAttribute('class', '');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleDragLeave',
|
||||||
|
value: function handleDragLeave() {
|
||||||
|
var thisDropzone = document.getElementById('primary-dropzone');
|
||||||
|
thisDropzone.setAttribute('class', 'dropzone row row--tall row--margined row--padded flex-container--column flex-container--center-center');
|
||||||
|
thisDropzone.firstElementChild.setAttribute('class', '');
|
||||||
|
thisDropzone.lastElementChild.setAttribute('class', 'hidden');
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'handleClick',
|
||||||
|
value: function handleClick(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// trigger file input
|
||||||
|
document.getElementById('file_input').click();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement(
|
||||||
|
'form',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement('input', { className: 'input-file', type: 'file', id: 'file_input', name: 'file_input', accept: 'video/*,image/*', onChange: this.handleDrop, encType: 'multipart/form-data' })
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'primary-dropzone', className: 'dropzone row row--margined row--padded row--tall flex-container--column flex-container--center-center', onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragEnd: this.handleDragEnd, onDragEnter: this.handleDragEnter, onDragLeave: this.handleDragLeave, onClick: this.handleClick },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'primary-dropzone-instructions' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'info-message-placeholder info-message--failure', id: 'input-error-file-selection', hidden: 'true' },
|
||||||
|
this.state.fileError
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
null,
|
||||||
|
'Drag & drop image or video here to publish'
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'fine-print' },
|
||||||
|
'OR'
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'blue--underlined' },
|
||||||
|
'CHOOSE FILE'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'dropbzone-dragover', className: 'hidden' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'blue' },
|
||||||
|
'Drop it.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Dropzone;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
module.exports = Dropzone;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 28 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
var _react = __webpack_require__(1);
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
var _preview = __webpack_require__(30);
|
||||||
|
|
||||||
|
var _preview2 = _interopRequireDefault(_preview);
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
|
var Title = function (_React$Component) {
|
||||||
|
_inherits(Title, _React$Component);
|
||||||
|
|
||||||
|
function Title(props) {
|
||||||
|
_classCallCheck(this, Title);
|
||||||
|
|
||||||
|
var _this = _possibleConstructorReturn(this, (Title.__proto__ || Object.getPrototypeOf(Title)).call(this, props));
|
||||||
|
|
||||||
|
_this.handleInput = _this.handleInput.bind(_this);
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Title, [{
|
||||||
|
key: 'handleInput',
|
||||||
|
value: function handleInput(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var name = e.target.name;
|
||||||
|
var value = e.target.value;
|
||||||
|
this.props.updateUploaderState(name, value);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement('input', { type: 'text', id: 'publish-title', className: 'input-text text--large input-text--full-width', placeholder: 'Give your post a title...', onChange: this.handleInput, value: this.props.title });
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Title;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
var Channel = function (_React$Component2) {
|
||||||
|
_inherits(Channel, _React$Component2);
|
||||||
|
|
||||||
|
function Channel() {
|
||||||
|
_classCallCheck(this, Channel);
|
||||||
|
|
||||||
|
return _possibleConstructorReturn(this, (Channel.__proto__ || Object.getPrototypeOf(Channel)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Channel, [{
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement(
|
||||||
|
'h3',
|
||||||
|
null,
|
||||||
|
'channel component'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Channel;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
var Url = function (_React$Component3) {
|
||||||
|
_inherits(Url, _React$Component3);
|
||||||
|
|
||||||
|
function Url() {
|
||||||
|
_classCallCheck(this, Url);
|
||||||
|
|
||||||
|
return _possibleConstructorReturn(this, (Url.__proto__ || Object.getPrototypeOf(Url)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Url, [{
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement(
|
||||||
|
'h3',
|
||||||
|
null,
|
||||||
|
'url component'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Url;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
var Thumbnail = function (_React$Component4) {
|
||||||
|
_inherits(Thumbnail, _React$Component4);
|
||||||
|
|
||||||
|
function Thumbnail() {
|
||||||
|
_classCallCheck(this, Thumbnail);
|
||||||
|
|
||||||
|
return _possibleConstructorReturn(this, (Thumbnail.__proto__ || Object.getPrototypeOf(Thumbnail)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Thumbnail, [{
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement(
|
||||||
|
'h3',
|
||||||
|
null,
|
||||||
|
'thumbnail component'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Thumbnail;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
var Details = function (_React$Component5) {
|
||||||
|
_inherits(Details, _React$Component5);
|
||||||
|
|
||||||
|
function Details() {
|
||||||
|
_classCallCheck(this, Details);
|
||||||
|
|
||||||
|
return _possibleConstructorReturn(this, (Details.__proto__ || Object.getPrototypeOf(Details)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Details, [{
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
null,
|
||||||
|
_react2.default.createElement(
|
||||||
|
'h3',
|
||||||
|
null,
|
||||||
|
'details component'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Details;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
var PublishDetails = function (_React$Component6) {
|
||||||
|
_inherits(PublishDetails, _React$Component6);
|
||||||
|
|
||||||
|
function PublishDetails(props) {
|
||||||
|
_classCallCheck(this, PublishDetails);
|
||||||
|
|
||||||
|
var _this6 = _possibleConstructorReturn(this, (PublishDetails.__proto__ || Object.getPrototypeOf(PublishDetails)).call(this, props));
|
||||||
|
|
||||||
|
_this6.state = {
|
||||||
|
showThumbnailSelector: false
|
||||||
|
// set defaults
|
||||||
|
};_this6.updateUploaderState = _this6.updateUploaderState.bind(_this6);
|
||||||
|
_this6.showThumbnailTool = _this6.showThumbnailTool.bind(_this6);
|
||||||
|
_this6.hideThumbnailTool = _this6.hideThumbnailTool.bind(_this6);
|
||||||
|
_this6.publish = _this6.publish.bind(_this6);
|
||||||
|
_this6.cancelPublish = _this6.cancelPublish.bind(_this6);
|
||||||
|
return _this6;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(PublishDetails, [{
|
||||||
|
key: 'updateUploaderState',
|
||||||
|
value: function updateUploaderState(name, value) {
|
||||||
|
this.props.updateUploaderState(name, value);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'showThumbnailTool',
|
||||||
|
value: function showThumbnailTool() {
|
||||||
|
this.setState({ showThumbnailSelector: true });
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'hideThumbnailTool',
|
||||||
|
value: function hideThumbnailTool() {
|
||||||
|
this.setState({ showThumbnailSelector: false });
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'publish',
|
||||||
|
value: function publish() {
|
||||||
|
// publish the asset
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'cancelPublish',
|
||||||
|
value: function cancelPublish() {
|
||||||
|
// cancel this publish
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'row row--padded row--no-bottom' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'column column--10' },
|
||||||
|
_react2.default.createElement(Title, { title: this.props.title, updateUploaderState: this.updateUploaderState })
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'column column--5 column--sml-10' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'row row--padded' },
|
||||||
|
_react2.default.createElement(_preview2.default, {
|
||||||
|
file: this.props.file,
|
||||||
|
hideThumbnailTool: this.hideThumbnailTool,
|
||||||
|
showThumbnailTool: this.showThumbnailTool
|
||||||
|
})
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'column column--5 column--sml-10 align-content-top' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'publish-active-area', className: 'row row--padded' },
|
||||||
|
_react2.default.createElement(Channel, null),
|
||||||
|
_react2.default.createElement(Url, { file: this.props.file }),
|
||||||
|
this.state.showThumbnailSelector && _react2.default.createElement(Thumbnail, { thumbnail: this.props.thumbnail }),
|
||||||
|
_react2.default.createElement(Details, null),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'row row--padded row--wide' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'input-error', id: 'input-error-publish-submit', hidden: 'true' },
|
||||||
|
this.props.inputError
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'button',
|
||||||
|
{ id: 'publish-submit', className: 'button--primary button--large', onClick: this.publish },
|
||||||
|
'Upload'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'row row--short align-content-center' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'button',
|
||||||
|
{ className: 'button--cancel', onClick: this.cancelPublish },
|
||||||
|
'Cancel'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ className: 'row row--short align-content-center' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'fine-print' },
|
||||||
|
'By clicking \'Upload\', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. ',
|
||||||
|
_react2.default.createElement(
|
||||||
|
'a',
|
||||||
|
{ className: 'link--primary', target: '_blank', href: 'https://lbry.io/learn' },
|
||||||
|
'Read more.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return PublishDetails;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
module.exports = PublishDetails;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 29 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
var _react = __webpack_require__(1);
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
|
var PublishStatus = function (_React$Component) {
|
||||||
|
_inherits(PublishStatus, _React$Component);
|
||||||
|
|
||||||
|
function PublishStatus() {
|
||||||
|
_classCallCheck(this, PublishStatus);
|
||||||
|
|
||||||
|
return _possibleConstructorReturn(this, (PublishStatus.__proto__ || Object.getPrototypeOf(PublishStatus)).apply(this, arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(PublishStatus, [{
|
||||||
|
key: "render",
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
"div",
|
||||||
|
{ id: "publish-status", "class": "hidden" },
|
||||||
|
_react2.default.createElement(
|
||||||
|
"div",
|
||||||
|
{ "class": "row row--margined" },
|
||||||
|
_react2.default.createElement("div", { id: "publish-update", "class": "row align-content-center" }),
|
||||||
|
_react2.default.createElement("div", { id: "publish-progress-bar", "class": "row align-content-center" }),
|
||||||
|
_react2.default.createElement("div", { id: "upload-percent", "class": "row align-content-center" }),
|
||||||
|
_react2.default.createElement(
|
||||||
|
"div",
|
||||||
|
null,
|
||||||
|
this.props.status
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return PublishStatus;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
module.exports = PublishStatus;
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
/* 30 */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||||
|
|
||||||
|
var _react = __webpack_require__(1);
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||||
|
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||||
|
|
||||||
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||||
|
|
||||||
|
var Preview = function (_React$Component) {
|
||||||
|
_inherits(Preview, _React$Component);
|
||||||
|
|
||||||
|
function Preview(props) {
|
||||||
|
_classCallCheck(this, Preview);
|
||||||
|
|
||||||
|
var _this = _possibleConstructorReturn(this, (Preview.__proto__ || Object.getPrototypeOf(Preview)).call(this, props));
|
||||||
|
|
||||||
|
_this.state = {
|
||||||
|
previewSource: ''
|
||||||
|
};
|
||||||
|
_this.previewFile = _this.previewFile.bind(_this);
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_createClass(Preview, [{
|
||||||
|
key: 'componentDidMount',
|
||||||
|
value: function componentDidMount() {
|
||||||
|
console.log('props after mount', this.props);
|
||||||
|
this.previewFile(this.props.file);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'previewFile',
|
||||||
|
value: function previewFile(file) {
|
||||||
|
console.log('previewFile', file);
|
||||||
|
var that = this;
|
||||||
|
if (file.type !== 'video/mp4') {
|
||||||
|
var previewReader = new FileReader();
|
||||||
|
previewReader.readAsDataURL(file);
|
||||||
|
previewReader.onloadend = function () {
|
||||||
|
that.setState({ previewSource: previewReader.result });
|
||||||
|
};
|
||||||
|
// clear & hide the thumbnail selection input
|
||||||
|
this.props.hideThumbnailTool();
|
||||||
|
} else {
|
||||||
|
that.setState({ previewSource: '/assets/img/video_thumb_default.png' });
|
||||||
|
// clear & show the thumbnail selection input
|
||||||
|
this.props.showThumbnailTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: 'render',
|
||||||
|
value: function render() {
|
||||||
|
return _react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'asset-preview-holder', className: 'dropzone' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'div',
|
||||||
|
{ id: 'asset-preview-dropzone-instructions', className: 'hidden' },
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
null,
|
||||||
|
'Drag & drop image or video here'
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'fine-print' },
|
||||||
|
'OR'
|
||||||
|
),
|
||||||
|
_react2.default.createElement(
|
||||||
|
'p',
|
||||||
|
{ className: 'blue--underlined' },
|
||||||
|
'CHOOSE FILE'
|
||||||
|
)
|
||||||
|
),
|
||||||
|
_react2.default.createElement('img', { id: 'asset-preview', src: this.state.previewSource, alt: 'publish preview' })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return Preview;
|
||||||
|
}(_react2.default.Component);
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
module.exports = Preview;
|
||||||
|
|
||||||
/***/ })
|
/***/ })
|
||||||
/******/ ]);
|
/******/ ]);
|
53
react/app.js
53
react/app.js
|
@ -1,53 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom';
|
|
||||||
import Dropzone from './components/dropzone.jsx';
|
|
||||||
import PublishDetails from './components/publishDetails.jsx';
|
|
||||||
import PublishStatus from './components/publishStatus.jsx';
|
|
||||||
|
|
||||||
const WAITING = 'WAITING';
|
|
||||||
const READY = 'READY';
|
|
||||||
const PUBLISHING = 'PUBLISHING';
|
|
||||||
|
|
||||||
class Uploader extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
componentStatus : WAITING, // WAITING, DETAILS, or PUBLISHING
|
|
||||||
publishingStatus: 'starting status',
|
|
||||||
files : [],
|
|
||||||
};
|
|
||||||
// bind class methods with `this`
|
|
||||||
this.handleClick = this.handleClick.bind(this);
|
|
||||||
this.updateComponentStatus = this.updateComponentStatus.bind(this);
|
|
||||||
}
|
|
||||||
handleClick (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
console.log('The link was clicked.');
|
|
||||||
}
|
|
||||||
updateComponentStatus (newStatus) {
|
|
||||||
this.setState({componentStatus: newStatus});
|
|
||||||
}
|
|
||||||
render () {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<form>
|
|
||||||
<input class="input-file" type="file" id="file_input" name="file_input" accept="video/*,image/*" onchange="publishFileFunctions.previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
|
|
||||||
</form>
|
|
||||||
{ this.state.componentStatus === WAITING &&
|
|
||||||
<Dropzone/>
|
|
||||||
}
|
|
||||||
{ this.state.componentStatus === READY &&
|
|
||||||
<PublishDetails />
|
|
||||||
}
|
|
||||||
{ this.state.componentStatus === PUBLISHING &&
|
|
||||||
<PublishStatus status={this.state.publishingStatus} />
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ReactDOM.render(
|
|
||||||
<Uploader />,
|
|
||||||
document.getElementById('react-uploader')
|
|
||||||
);
|
|
|
@ -1,17 +1,121 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
class Dropzone extends React.Component {
|
class Dropzone extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
fileError: null,
|
||||||
|
}
|
||||||
|
this.handleDrop = this.handleDrop.bind(this);
|
||||||
|
this.handleDragOver = this.handleDragOver.bind(this);
|
||||||
|
this.handleDragEnd = this.handleDragEnd.bind(this);
|
||||||
|
this.handleDragEnter = this.handleDragEnter.bind(this);
|
||||||
|
this.handleDragLeave = this.handleDragLeave.bind(this);
|
||||||
|
this.handleClick = this.handleClick.bind(this);
|
||||||
|
}
|
||||||
|
validateFile (file) {
|
||||||
|
if (!file) {
|
||||||
|
console.log('no file found');
|
||||||
|
throw new Error('no file provided');
|
||||||
|
}
|
||||||
|
if (/'/.test(file.name)) {
|
||||||
|
console.log('file name had apostrophe in it');
|
||||||
|
throw new Error('apostrophes are not allowed in the file name');
|
||||||
|
}
|
||||||
|
// validate size and type
|
||||||
|
switch (file.type) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/jpg':
|
||||||
|
case 'image/png':
|
||||||
|
if (file.size > 10000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, images are limited to 10 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'image/gif':
|
||||||
|
if (file.size > 50000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, .gifs are limited to 50 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'video/mp4':
|
||||||
|
if (file.size > 50000000) {
|
||||||
|
console.log('file was too big');
|
||||||
|
throw new Error('Sorry, videos are limited to 50 megabytes.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('file type is not supported');
|
||||||
|
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleDrop (event) {
|
||||||
|
console.log('handleDrop', event);
|
||||||
|
event.preventDefault();
|
||||||
|
// if dropped items aren't files, reject them
|
||||||
|
const dt = event.dataTransfer;
|
||||||
|
console.log('dt', dt);
|
||||||
|
if (dt.items) {
|
||||||
|
if (dt.items[0].kind == 'file') {
|
||||||
|
const droppedFile = dt.items[0].getAsFile();
|
||||||
|
console.log('droppedFile', droppedFile);
|
||||||
|
// When a file is selected for publish, validate that file and
|
||||||
|
try {
|
||||||
|
this.validateFile(droppedFile); // validate the file's name, type, and size
|
||||||
|
} catch (error) {
|
||||||
|
return this.setState('fileError', error.message);
|
||||||
|
}
|
||||||
|
// stage it so it will be ready when the publish button is clicked
|
||||||
|
this.props.stageFileAndShowDetails(droppedFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleDragOver (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
handleDragEnd (event) {
|
||||||
|
var dt = event.dataTransfer;
|
||||||
|
if (dt.items) {
|
||||||
|
for (var i = 0; i < dt.items.length; i++) {
|
||||||
|
dt.items.remove(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
event.dataTransfer.clearData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleDragEnter () {
|
||||||
|
const thisDropzone = document.getElementById('primary-dropzone');
|
||||||
|
thisDropzone.setAttribute('class', 'dropzone dropzone--drag-over row row--margined row--padded row--tall flex-container--column flex-container--center-center');
|
||||||
|
thisDropzone.firstElementChild.setAttribute('class', 'hidden');
|
||||||
|
thisDropzone.lastElementChild.setAttribute('class', '');
|
||||||
|
}
|
||||||
|
handleDragLeave () {
|
||||||
|
const thisDropzone = document.getElementById('primary-dropzone');
|
||||||
|
thisDropzone.setAttribute('class', 'dropzone row row--tall row--margined row--padded flex-container--column flex-container--center-center');
|
||||||
|
thisDropzone.firstElementChild.setAttribute('class', '');
|
||||||
|
thisDropzone.lastElementChild.setAttribute('class', 'hidden');
|
||||||
|
}
|
||||||
|
handleClick (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// trigger file input
|
||||||
|
document.getElementById('file_input').click();
|
||||||
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div id="primary-dropzone" class="dropzone row row--margined row--padded row--tall flex-container--column flex-container--center-center" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="dragenter_handler(event)" ondragleave="dragexit_handler(event)" onclick="publishFileFunctions.triggerFileChooser('file_input', event)">
|
<div>
|
||||||
<div id="primary-dropzone-instructions">
|
<form>
|
||||||
<p class="info-message-placeholder info-message--failure" id="input-error-file-selection" hidden="true"></p>
|
<input className="input-file" type="file" id="file_input" name="file_input" accept="video/*,image/*" onChange={this.handleDrop} encType="multipart/form-data"/>
|
||||||
<p>Drag & drop image or video here to publish</p>
|
</form>
|
||||||
<p class="fine-print">OR</p>
|
<div id="primary-dropzone" className="dropzone row row--margined row--padded row--tall flex-container--column flex-container--center-center" onDrop={this.handleDrop} onDragOver={this.handleDragOver} onDragEnd={this.handleDragEnd} onDragEnter={this.handleDragEnter} onDragLeave={this.handleDragLeave} onClick={this.handleClick}>
|
||||||
<p class="blue--underlined">CHOOSE FILE</p>
|
<div id="primary-dropzone-instructions">
|
||||||
</div>
|
<p className="info-message-placeholder info-message--failure" id="input-error-file-selection" hidden="true">{this.state.fileError}</p>
|
||||||
<div id="dropbzone-dragover" class="hidden">
|
<p>Drag & drop image or video here to publish</p>
|
||||||
<p class="blue">Drop it.</p>
|
<p className="fine-print">OR</p>
|
||||||
|
<p className="blue--underlined">CHOOSE FILE</p>
|
||||||
|
</div>
|
||||||
|
<div id="dropbzone-dragover" className="hidden">
|
||||||
|
<p className="blue">Drop it.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
46
react/components/preview.jsx
Normal file
46
react/components/preview.jsx
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
class Preview extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
previewSource: '',
|
||||||
|
}
|
||||||
|
this.previewFile = this.previewFile.bind(this);
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
console.log('props after mount', this.props);
|
||||||
|
this.previewFile(this.props.file);
|
||||||
|
}
|
||||||
|
previewFile (file) {
|
||||||
|
console.log('previewFile', file)
|
||||||
|
const that = this;
|
||||||
|
if (file.type !== 'video/mp4') {
|
||||||
|
const previewReader = new FileReader();
|
||||||
|
previewReader.readAsDataURL(file);
|
||||||
|
previewReader.onloadend = function () {
|
||||||
|
that.setState({previewSource: previewReader.result});
|
||||||
|
};
|
||||||
|
// clear & hide the thumbnail selection input
|
||||||
|
this.props.hideThumbnailTool();
|
||||||
|
} else {
|
||||||
|
that.setState({previewSource: '/assets/img/video_thumb_default.png'});
|
||||||
|
// clear & show the thumbnail selection input
|
||||||
|
this.props.showThumbnailTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div id="asset-preview-holder" className="dropzone">
|
||||||
|
<div id="asset-preview-dropzone-instructions" className="hidden">
|
||||||
|
<p>Drag & drop image or video here</p>
|
||||||
|
<p className="fine-print">OR</p>
|
||||||
|
<p className="blue--underlined">CHOOSE FILE</p>
|
||||||
|
</div>
|
||||||
|
<img id="asset-preview" src={this.state.previewSource} alt="publish preview"/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = Preview;
|
|
@ -1,56 +1,125 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Preview from './preview.jsx';
|
||||||
|
|
||||||
class Title extends React.Component {
|
class Title extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.handleInput = this.handleInput.bind(this);
|
||||||
|
}
|
||||||
|
handleInput (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const name = e.target.name;
|
||||||
|
const value = e.target.value;
|
||||||
|
this.props.updateUploaderState(name, value);
|
||||||
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<input type="text" id="publish-title" class="input-text text--large input-text--full-width" placeholder="Give your post a title..." />
|
<input type="text" id="publish-title" className="input-text text--large input-text--full-width" placeholder="Give your post a title..." onChange={this.handleInput} value={this.props.title}/>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Preview extends React.Component {
|
class Channel extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div id="asset-preview-holder" class="dropzone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)" ondragenter="preview_onmouseenter_handler()" ondragleave="preview_onmouseleave_handler()" onmouseenter="preview_onmouseenter_handler()" onmouseleave="preview_onmouseleave_handler()" onclick="publishFileFunctions.triggerFileChooser('file_input', event)">
|
<div>
|
||||||
<div id="asset-preview-dropzone-instructions" class="hidden">
|
<h3>channel component</h3>
|
||||||
<p>Drag & drop image or video here</p>
|
|
||||||
<p class="fine-print">OR</p>
|
|
||||||
<p class="blue--underlined">CHOOSE FILE</p>
|
|
||||||
</div>
|
|
||||||
<div id="asset-preview-target"></div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
class Url extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>url component</h3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Thumbnail extends React.Component {
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>thumbnail component</h3>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Details extends React.Component {
|
class Details extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
{{> publishForm-Channel}}
|
<div>
|
||||||
{{> publishForm-Url}}
|
<h3>details component</h3>
|
||||||
{{> publishForm-Thumbnail}}
|
</div>
|
||||||
{{> publishForm-Details}}
|
);
|
||||||
{{> publishForm-Submit}}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PublishDetails extends React.Component {
|
class PublishDetails extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
showThumbnailSelector: false,
|
||||||
|
}
|
||||||
|
// set defaults
|
||||||
|
this.updateUploaderState = this.updateUploaderState.bind(this);
|
||||||
|
this.showThumbnailTool = this.showThumbnailTool.bind(this);
|
||||||
|
this.hideThumbnailTool = this.hideThumbnailTool.bind(this);
|
||||||
|
this.publish = this.publish.bind(this);
|
||||||
|
this.cancelPublish = this.cancelPublish.bind(this);
|
||||||
|
}
|
||||||
|
updateUploaderState (name, value) {
|
||||||
|
this.props.updateUploaderState(name, value);
|
||||||
|
}
|
||||||
|
showThumbnailTool () {
|
||||||
|
this.setState({showThumbnailSelector: true});
|
||||||
|
}
|
||||||
|
hideThumbnailTool () {
|
||||||
|
this.setState({showThumbnailSelector: false});
|
||||||
|
}
|
||||||
|
publish () {
|
||||||
|
// publish the asset
|
||||||
|
}
|
||||||
|
cancelPublish () {
|
||||||
|
// cancel this publish
|
||||||
|
}
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div id="publish-form" class="hidden">
|
<div className="row row--padded row--no-bottom">
|
||||||
<div class="row row--padded row--no-bottom">
|
<div className="column column--10">
|
||||||
<div class="column column--10">
|
<Title title={this.props.title} updateUploaderState={this.updateUploaderState}/>
|
||||||
<Title />
|
</div>
|
||||||
|
<div className="column column--5 column--sml-10" >
|
||||||
|
<div className="row row--padded">
|
||||||
|
<Preview
|
||||||
|
file={this.props.file}
|
||||||
|
hideThumbnailTool={this.hideThumbnailTool}
|
||||||
|
showThumbnailTool={this.showThumbnailTool}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="column column--5 column--sml-10" >
|
</div>
|
||||||
<div class="row row--padded">
|
<div className="column column--5 column--sml-10 align-content-top">
|
||||||
<Preview />
|
<div id="publish-active-area" className="row row--padded">
|
||||||
|
<Channel />
|
||||||
|
<Url file={this.props.file}/>
|
||||||
|
{ this.state.showThumbnailSelector && <Thumbnail thumbnail={this.props.thumbnail}/> }
|
||||||
|
<Details />
|
||||||
|
|
||||||
|
<div className="row row--padded row--wide">
|
||||||
|
<div className="input-error" id="input-error-publish-submit" hidden="true">{this.props.inputError}</div>
|
||||||
|
<button id="publish-submit" className="button--primary button--large" onClick={this.publish}>Upload</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="column column--5 column--sml-10 align-content-top">
|
<div className="row row--short align-content-center">
|
||||||
<div id="publish-active-area" class="row row--padded">
|
<button className="button--cancel" onClick={this.cancelPublish}>Cancel</button>
|
||||||
<Details />
|
</div>
|
||||||
|
|
||||||
|
<div className="row row--short align-content-center">
|
||||||
|
<p className="fine-print">By clicking 'Upload', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. <a className="link--primary" target="_blank" href="https://lbry.io/learn">Read more.</a></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
74
react/uploader.js
Normal file
74
react/uploader.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import Dropzone from './components/dropzone.jsx';
|
||||||
|
import PublishDetails from './components/publishDetails.jsx';
|
||||||
|
import PublishStatus from './components/publishStatus.jsx';
|
||||||
|
|
||||||
|
const DROPZONE = 'DROPZONE';
|
||||||
|
const DETAILS = 'DETAILS';
|
||||||
|
const STATUS = 'STATUS';
|
||||||
|
|
||||||
|
class Uploader extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
showComponent: DROPZONE, // DROPZONE, DETAILS, or PUBLISHING
|
||||||
|
file : null,
|
||||||
|
title : '',
|
||||||
|
channel : '',
|
||||||
|
url : '',
|
||||||
|
thumbnail : '',
|
||||||
|
description : '',
|
||||||
|
license : '',
|
||||||
|
nsfw : '',
|
||||||
|
};
|
||||||
|
// bind class methods with `this`
|
||||||
|
this.updateUploaderState = this.updateUploaderState.bind(this);
|
||||||
|
this.showComponent = this.showComponent.bind(this);
|
||||||
|
this.stageFileAndShowDetails = this.stageFileAndShowDetails.bind(this);
|
||||||
|
}
|
||||||
|
updateUploaderState (name, value) {
|
||||||
|
console.log(`updateUploaderState ${name} ${value}`);
|
||||||
|
this.setState({[name]: value});
|
||||||
|
}
|
||||||
|
showComponent (component) {
|
||||||
|
this.setState({showComponent: component});
|
||||||
|
}
|
||||||
|
stageFileAndShowDetails (selectedFile) {
|
||||||
|
console.log('stageFileAndShowDetails', selectedFile);
|
||||||
|
// store the selected file for upload
|
||||||
|
this.setState({'file': selectedFile});
|
||||||
|
// hide the dropzone and show the details
|
||||||
|
this.showComponent(DETAILS);
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{ this.state.showComponent === DROPZONE &&
|
||||||
|
<Dropzone stageFileAndShowDetails={this.stageFileAndShowDetails}/>
|
||||||
|
}
|
||||||
|
{ this.state.showComponent === DETAILS &&
|
||||||
|
<PublishDetails
|
||||||
|
updateUploaderState={this.updateUploaderState}
|
||||||
|
file={this.state.file}
|
||||||
|
title={this.state.title}
|
||||||
|
channel={this.state.channel}
|
||||||
|
url={this.state.url}
|
||||||
|
thumbnail={this.state.thumbnail}
|
||||||
|
description={this.state.description}
|
||||||
|
license={this.state.license}
|
||||||
|
nsfw={this.state.nsfw}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{ this.state.showComponent === STATUS &&
|
||||||
|
<PublishStatus />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Uploader />,
|
||||||
|
document.getElementById('react-uploader')
|
||||||
|
);
|
|
@ -1,10 +1 @@
|
||||||
<div class="row row--padded row--wide">
|
|
||||||
<div class="input-error" id="input-error-publish-submit" hidden="true"></div>
|
|
||||||
<button id="publish-submit" class="button--primary button--large" onclick="publishFileFunctions.publishStagedFile(event)">Upload</button>
|
|
||||||
</div>
|
|
||||||
<div class="row row--short align-content-center">
|
|
||||||
<button class="button--cancel" onclick="publishFileFunctions.cancelPublish()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
<div class="row row--short align-content-center">
|
|
||||||
<p class="fine-print">By clicking 'Upload', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. <a class="link--primary" target="_blank" href="https://lbry.io/learn">Read more.</a></p>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry : './react/app.js',
|
entry : './react/uploader.js',
|
||||||
output: {
|
output: {
|
||||||
path : path.join(__dirname, '/public/bundle/'),
|
path : path.join(__dirname, '/public/bundle/'),
|
||||||
filename: 'bundle.js',
|
filename: 'bundle.js',
|
||||||
|
|
Loading…
Reference in a new issue