From 9bbeef208fe9769618d2de3b69f0eb417eb007f8 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Thu, 6 Aug 2015 20:07:14 -0700 Subject: Added handlers for dragging and dropping files onto the center pane or RHS --- web/react/components/file_upload.jsx | 38 ++++++++++++++++++++++++++++++++++++ web/react/components/post_list.jsx | 6 ++++++ 2 files changed, 44 insertions(+) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index b90fa4fd3..aaf45c1ef 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -84,7 +84,45 @@ module.exports = React.createClass({ var inputDiv = this.refs.input.getDOMNode(); var self = this; +<<<<<<< HEAD document.addEventListener('paste', function(e) { +======= + $('body').on('dragover', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + //e.target.style + console.log("HERE!: drag center"); + }); + $('body').on('dragover', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + //e.target.style + console.log("HERE!: drag right"); + }); + $('body').on('dragenter', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + //e.target.style + console.log("HERE!: dragenter center"); + }); + $('body').on('dragenter', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + //e.target.style + console.log("HERE!: dragenter right"); + }); + $('body').on('drop', '.app__content', function(e) { + if (e.originalEvent.dataTransfer) + e.preventDefault(); + console.log("HERE!: drop center"); + }); + $('body').on('drop', '.sidebar--right', function(e) { + e.preventDefault(); + console.log("HERE!: drop right"); + }); + + document.addEventListener("paste", function(e) { +>>>>>>> Added handlers for dragging and dropping files onto the center pane or RHS var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0]; if (textarea !== e.target && !$.contains(textarea, e.target)) { diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 83f806b79..5724dbd62 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -125,6 +125,12 @@ module.exports = React.createClass({ } }); + //$('body').on('drop drag') + /*window.document.addEventListener("drop", function(e) { + e.preventDefault(); + var centerPostList = $(inputDiv.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode).find('.post-list')[0]; + console.log("HERE!: " + centerPostList); + });*/ }, componentDidUpdate: function() { this.resize(); -- cgit v1.2.3-1-g7c22 From 1fa436b4f99d482bc2adb926b93d0c0b832d9288 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Fri, 7 Aug 2015 14:24:09 -0700 Subject: Users can now drop files into the center pane or the rhs respectively to upload images and other files --- web/react/components/create_comment.jsx | 4 +- web/react/components/create_post.jsx | 4 +- web/react/components/file_upload.jsx | 104 ++++++++++++++++++++----------- web/react/components/post_list.jsx | 7 --- web/sass-files/sass/partials/_files.scss | 14 ++--- 5 files changed, 79 insertions(+), 54 deletions(-) diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 78e06c532..c954229ae 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -222,7 +222,9 @@ module.exports = React.createClass({ getFileCount={this.getFileCount} onUploadStart={this.handleUploadStart} onFileUpload={this.handleFileUploadComplete} - onUploadError={this.handleUploadError} /> + onUploadError={this.handleUploadError} + postType='comment' + channelId={this.props.channelId} />
diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 9ca1d5388..137420440 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -262,7 +262,9 @@ module.exports = React.createClass({ getFileCount={this.getFileCount} onUploadStart={this.handleUploadStart} onFileUpload={this.handleFileUploadComplete} - onUploadError={this.handleUploadError} /> + onUploadError={this.handleUploadError} + postType='post' + channelId='' />
{postError} diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index aaf45c1ef..eb461ae9c 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -80,49 +80,77 @@ module.exports = React.createClass({ } } catch(e) {} }, + handleDrop: function(e) { + this.props.onUploadError(null); + + var files = e.originalEvent.dataTransfer.files; + if (files.length) { + var numFiles = files.length; + var numToUpload = this.props.setUploads(numFiles); + + for (var i = 0; i < numFiles && i < numToUpload; i++) { + var file = files[i]; + var channelId = this.props.channelId || ChannelStore.getCurrentId(); + + var formData = new FormData(); + formData.append('channel_id', channelId); + formData.append('files', file, file.name); + + client.uploadFile(formData, + function(data) { + var parsedData = $.parseJSON(data); + this.props.onFileUpload(parsedData.filenames, channelId); + }.bind(this), + function(err) { + this.props.onUploadError(err); + }.bind(this) + ); + } + } + }, componentDidMount: function() { var inputDiv = this.refs.input.getDOMNode(); var self = this; -<<<<<<< HEAD - document.addEventListener('paste', function(e) { -======= - $('body').on('dragover', '.app__content', function(e) { - e.preventDefault(); - e.stopPropagation(); - //e.target.style - console.log("HERE!: drag center"); - }); - $('body').on('dragover', '.sidebar--right', function(e) { - e.preventDefault(); - e.stopPropagation(); - //e.target.style - console.log("HERE!: drag right"); - }); - $('body').on('dragenter', '.app__content', function(e) { - e.preventDefault(); - e.stopPropagation(); - //e.target.style - console.log("HERE!: dragenter center"); - }); - $('body').on('dragenter', '.sidebar--right', function(e) { - e.preventDefault(); - e.stopPropagation(); - //e.target.style - console.log("HERE!: dragenter right"); - }); - $('body').on('drop', '.app__content', function(e) { - if (e.originalEvent.dataTransfer) - e.preventDefault(); - console.log("HERE!: drop center"); - }); - $('body').on('drop', '.sidebar--right', function(e) { - e.preventDefault(); - console.log("HERE!: drop right"); - }); + if (this.props.postType === 'post') { + $('body').on('dragover', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('dragenter', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('dragend dragleave', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('drop', '.app__content', function(e) { + e.preventDefault(); + e.stopPropagation(); + self.handleDrop(e); + }); + } else if (this.props.postType === 'comment') { + $('body').on('dragover', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('dragenter', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('dragend dragleave', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + }); + $('body').on('drop', '.sidebar--right', function(e) { + e.preventDefault(); + e.stopPropagation(); + self.handleDrop(e); + }); + } - document.addEventListener("paste", function(e) { ->>>>>>> Added handlers for dragging and dropping files onto the center pane or RHS + document.addEventListener('paste', function(e) { var textarea = $(inputDiv.parentNode.parentNode).find('.custom-textarea')[0]; if (textarea !== e.target && !$.contains(textarea, e.target)) { diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 5724dbd62..4df78817a 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -124,13 +124,6 @@ module.exports = React.createClass({ $(this).parent('div').next('.date-separator, .new-separator').removeClass('hovered--comment'); } }); - - //$('body').on('drop drag') - /*window.document.addEventListener("drop", function(e) { - e.preventDefault(); - var centerPostList = $(inputDiv.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode).find('.post-list')[0]; - console.log("HERE!: " + centerPostList); - });*/ }, componentDidUpdate: function() { this.resize(); diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss index 65775f01e..34409d563 100644 --- a/web/sass-files/sass/partials/_files.scss +++ b/web/sass-files/sass/partials/_files.scss @@ -194,11 +194,11 @@ border-right: 1px solid #ddd; vertical-align: center; - // helper to center the image icon in the preview window - .file-details__preview-helper { - height: 100%; - display: inline-block; - vertical-align: middle; - } - } + // helper to center the image icon in the preview window + .file-details__preview-helper { + height: 100%; + display: inline-block; + vertical-align: middle; } + } +} -- cgit v1.2.3-1-g7c22 From 81d7599f75b11d619f8ee9440394de3f9f86f39f Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Sun, 9 Aug 2015 13:04:24 -0700 Subject: Working on adding overlays for file drag and drop --- web/react/components/file_upload.jsx | 18 +++++------------- web/react/components/post_list.jsx | 11 ++++++++++- web/react/components/post_right.jsx | 11 ++++++++++- web/sass-files/sass/partials/_post.scss | 5 +++++ web/sass-files/sass/partials/_post_right.scss | 6 ++++++ 5 files changed, 36 insertions(+), 15 deletions(-) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index eb461ae9c..a479883c9 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -113,39 +113,31 @@ module.exports = React.createClass({ var self = this; if (this.props.postType === 'post') { - $('body').on('dragover', '.app__content', function(e) { + $('body').on('dragover', '.post-list__table', function(e) { e.preventDefault(); - e.stopPropagation(); }); - $('body').on('dragenter', '.app__content', function(e) { + $('body').on('dragenter', '.post-list__table', function(e) { e.preventDefault(); - e.stopPropagation(); }); - $('body').on('dragend dragleave', '.app__content', function(e) { + $('body').on('dragleave', '.post-list__table', function(e) { e.preventDefault(); - e.stopPropagation(); }); - $('body').on('drop', '.app__content', function(e) { + $('body').on('drop', '.post-list__table', function(e) { e.preventDefault(); - e.stopPropagation(); self.handleDrop(e); }); } else if (this.props.postType === 'comment') { $('body').on('dragover', '.sidebar--right', function(e) { e.preventDefault(); - e.stopPropagation(); }); $('body').on('dragenter', '.sidebar--right', function(e) { e.preventDefault(); - e.stopPropagation(); }); - $('body').on('dragend dragleave', '.sidebar--right', function(e) { + $('body').on('dragleave', '.sidebar--right', function(e) { e.preventDefault(); - e.stopPropagation(); }); $('body').on('drop', '.sidebar--right', function(e) { e.preventDefault(); - e.stopPropagation(); self.handleDrop(e); }); } diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 4df78817a..cf0c4c663 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -280,6 +280,10 @@ module.exports = React.createClass({ } ); }, + handleDragEnter: function() { + console.log("HERE ENTER"); + this.setState({fileDrag: true}); + }, getInitialState: function() { return getStateFromStores(); }, @@ -461,9 +465,14 @@ module.exports = React.createClass({ postCtls.push(); } + var fileDragOverlay = ''; + if (this.state.fileDrag) { + fileDragOverlay = 'post-list-file-overlay'; + } + return (
-
+
{ more_messages } { postCtls } diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index ad8b54012..f7f5ed509 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -243,6 +243,10 @@ module.exports = React.createClass({ this.refs[id].forceUpdate(); } }, + handleDragEnter: function() { + console.log("HERE ENTER RIGHT"); + this.setState({fileDrag: true}); + }, getInitialState: function() { return getStateFromStores(); }, @@ -294,8 +298,13 @@ module.exports = React.createClass({ var currentId = UserStore.getCurrentId(); var searchForm = currentId == null ? null : ; + var fileDragOverlay = ''; + if (this.state.fileDrag) { + fileDragOverlay = 'post-right-file-overlay'; + } + return ( -
+
{searchForm}
diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index 98b17120d..093e10ee0 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -107,6 +107,11 @@ body.ios { } #post-list { + .post-list-file-overlay { + width: 100%; + height: 100%; + background:rgba(255,255,255,0.5); + } .post-list-holder-by-time { background: #fff; overflow-y: scroll; diff --git a/web/sass-files/sass/partials/_post_right.scss b/web/sass-files/sass/partials/_post_right.scss index 4cf3e32a1..1b98d62f9 100644 --- a/web/sass-files/sass/partials/_post_right.scss +++ b/web/sass-files/sass/partials/_post_right.scss @@ -1,5 +1,11 @@ .post-right__container { + .post-right-file-overlay { + width: 100%; + height: 100%; + background:rgba(255,255,255,0.5); + } + .post-right-root-message { padding: 1em 1em 0; } -- cgit v1.2.3-1-g7c22 From 9baafdb372d92c96a4063f11531f4fb5d9e7059e Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Tue, 11 Aug 2015 09:48:25 -0700 Subject: Changed structure to keep code contained to file_upload.jsx --- web/react/components/file_upload.jsx | 26 ++++++++++++++------------ web/react/components/post_list.jsx | 6 +----- web/react/components/post_right.jsx | 6 +----- web/sass-files/sass/partials/_files.scss | 12 ++++++++++++ web/sass-files/sass/partials/_post_right.scss | 6 ------ 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index a479883c9..e082abcd2 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -113,31 +113,33 @@ module.exports = React.createClass({ var self = this; if (this.props.postType === 'post') { - $('body').on('dragover', '.post-list__table', function(e) { + $('body').on('dragover dragleave', '.app__content', function(e) { e.preventDefault(); }); - $('body').on('dragenter', '.post-list__table', function(e) { + $('body').on('dragenter', '.app__content', function(e) { e.preventDefault(); + console.log('HERE'); + $('.app__content').addClass('center-file-overlay'); + $('.post-right__container').removeClass('right-file-overlay'); }); - $('body').on('dragleave', '.post-list__table', function(e) { - e.preventDefault(); - }); - $('body').on('drop', '.post-list__table', function(e) { + $('body').on('drop', '.app__content', function(e) { e.preventDefault(); + $('.app__content').removeClass('center-file-overlay'); self.handleDrop(e); }); } else if (this.props.postType === 'comment') { - $('body').on('dragover', '.sidebar--right', function(e) { - e.preventDefault(); - }); - $('body').on('dragenter', '.sidebar--right', function(e) { + $('body').on('dragover dragleave', '.post-right__container', function(e) { e.preventDefault(); }); - $('body').on('dragleave', '.sidebar--right', function(e) { + $('body').on('dragenter', '.post-right__container', function(e) { e.preventDefault(); + console.log('HERE RIGHT'); + $('.post-right__container').addClass('right-file-overlay'); + $('.app__content').removeClass('center-file-overlay'); }); - $('body').on('drop', '.sidebar--right', function(e) { + $('body').on('drop', '.post-right__container', function(e) { e.preventDefault(); + $('.post-right__container').removeClass('right-file-overlay'); self.handleDrop(e); }); } diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index cf0c4c663..826d34a7d 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -280,10 +280,6 @@ module.exports = React.createClass({ } ); }, - handleDragEnter: function() { - console.log("HERE ENTER"); - this.setState({fileDrag: true}); - }, getInitialState: function() { return getStateFromStores(); }, @@ -472,7 +468,7 @@ module.exports = React.createClass({ return (
-
+
{ more_messages } { postCtls } diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index f7f5ed509..ad993aee1 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -243,10 +243,6 @@ module.exports = React.createClass({ this.refs[id].forceUpdate(); } }, - handleDragEnter: function() { - console.log("HERE ENTER RIGHT"); - this.setState({fileDrag: true}); - }, getInitialState: function() { return getStateFromStores(); }, @@ -304,7 +300,7 @@ module.exports = React.createClass({ } return ( -
+
{searchForm}
diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss index 34409d563..83c87132b 100644 --- a/web/sass-files/sass/partials/_files.scss +++ b/web/sass-files/sass/partials/_files.scss @@ -202,3 +202,15 @@ } } } + +.center-file-overlay { + width: 100%; + height: 100%; + background:rgba(255,255,255,0.5); +} + +.right-file-overlay { + width: 100%; + height: 100%; + background:rgba(255,255,255,0.5); +} diff --git a/web/sass-files/sass/partials/_post_right.scss b/web/sass-files/sass/partials/_post_right.scss index 1b98d62f9..4cf3e32a1 100644 --- a/web/sass-files/sass/partials/_post_right.scss +++ b/web/sass-files/sass/partials/_post_right.scss @@ -1,11 +1,5 @@ .post-right__container { - .post-right-file-overlay { - width: 100%; - height: 100%; - background:rgba(255,255,255,0.5); - } - .post-right-root-message { padding: 1em 1em 0; } -- cgit v1.2.3-1-g7c22 From 9f9d93e6133ffd2523546e27e9099e2e6f436506 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Tue, 11 Aug 2015 11:42:31 -0700 Subject: Switched to using the jquery-dragster library to implement more consistent drag and drop support, rather than using the inconsistent html5 implementation --- web/react/components/file_upload.jsx | 48 ++++++------- web/static/js/jquery-dragster/LICENSE | 21 ++++++ web/static/js/jquery-dragster/README.md | 17 +++++ web/static/js/jquery-dragster/bower.json | 25 +++++++ web/static/js/jquery-dragster/jquery.dragster.js | 85 ++++++++++++++++++++++++ web/templates/head.html | 2 + 6 files changed, 172 insertions(+), 26 deletions(-) create mode 100644 web/static/js/jquery-dragster/LICENSE create mode 100644 web/static/js/jquery-dragster/README.md create mode 100644 web/static/js/jquery-dragster/bower.json create mode 100644 web/static/js/jquery-dragster/jquery.dragster.js diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index e082abcd2..f382b848a 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -113,34 +113,30 @@ module.exports = React.createClass({ var self = this; if (this.props.postType === 'post') { - $('body').on('dragover dragleave', '.app__content', function(e) { - e.preventDefault(); - }); - $('body').on('dragenter', '.app__content', function(e) { - e.preventDefault(); - console.log('HERE'); - $('.app__content').addClass('center-file-overlay'); - $('.post-right__container').removeClass('right-file-overlay'); - }); - $('body').on('drop', '.app__content', function(e) { - e.preventDefault(); - $('.app__content').removeClass('center-file-overlay'); - self.handleDrop(e); + $('.app__content').dragster({ + enter: function(dragsterEvent, e) { + $('.app__content').addClass('center-file-overlay'); + }, + leave: function(dragsterEvent, e) { + $('.app__content').removeClass('center-file-overlay'); + }, + drop: function(dragsterEvent, e) { + $('.app__content').removeClass('center-file-overlay'); + self.handleDrop(e); + } }); } else if (this.props.postType === 'comment') { - $('body').on('dragover dragleave', '.post-right__container', function(e) { - e.preventDefault(); - }); - $('body').on('dragenter', '.post-right__container', function(e) { - e.preventDefault(); - console.log('HERE RIGHT'); - $('.post-right__container').addClass('right-file-overlay'); - $('.app__content').removeClass('center-file-overlay'); - }); - $('body').on('drop', '.post-right__container', function(e) { - e.preventDefault(); - $('.post-right__container').removeClass('right-file-overlay'); - self.handleDrop(e); + $('.post-right__container').dragster({ + enter: function(dragsterEvent, e) { + $('.post-right__container').addClass('right-file-overlay'); + }, + leave: function(dragsterEvent, e) { + $('.post-right__container').removeClass('right-file-overlay'); + }, + drop: function(dragsterEvent, e) { + $('.post-right__container').removeClass('right-file-overlay'); + self.handleDrop(e); + } }); } diff --git a/web/static/js/jquery-dragster/LICENSE b/web/static/js/jquery-dragster/LICENSE new file mode 100644 index 000000000..b8b51dc0b --- /dev/null +++ b/web/static/js/jquery-dragster/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Jan Martin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/web/static/js/jquery-dragster/README.md b/web/static/js/jquery-dragster/README.md new file mode 100644 index 000000000..1c28adaf0 --- /dev/null +++ b/web/static/js/jquery-dragster/README.md @@ -0,0 +1,17 @@ +Include [jquery.dragster.js](https://rawgithub.com/catmanjan/jquery-dragster/master/jquery.dragster.js) in page. + +Works in IE. + +```javascript +$('.element').dragster({ + enter: function (dragsterEvent, event) { + $(this).addClass('hover'); + }, + leave: function (dragsterEvent, event) { + $(this).removeClass('hover'); + }, + drop: function (dragsterEvent, event) { + $(this).removeClass('hover'); + } +}); +``` \ No newline at end of file diff --git a/web/static/js/jquery-dragster/bower.json b/web/static/js/jquery-dragster/bower.json new file mode 100644 index 000000000..a3cf7ed16 --- /dev/null +++ b/web/static/js/jquery-dragster/bower.json @@ -0,0 +1,25 @@ +{ + "name": "jquery-dragster", + "version": "1.0.3", + "homepage": "https://github.com/catmanjan/jquery-dragster", + "authors": [ + "catmanjan" + ], + "description": "Unified drag and drop listener", + "main": "jquery.dragster.js", + "keywords": [ + "jquery", + "dragster", + "dragenter", + "dragleave", + "drop" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/web/static/js/jquery-dragster/jquery.dragster.js b/web/static/js/jquery-dragster/jquery.dragster.js new file mode 100644 index 000000000..db73fe3f0 --- /dev/null +++ b/web/static/js/jquery-dragster/jquery.dragster.js @@ -0,0 +1,85 @@ +// 1.0.3 +/* +The MIT License (MIT) + +Copyright (c) 2015 Jan Martin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +(function ($) { + + $.fn.dragster = function (options) { + var settings = $.extend({ + enter: $.noop, + leave: $.noop, + over: $.noop, + drop: $.noop + }, options); + + return this.each(function () { + var first = false, + second = false, + $this = $(this); + + $this.on({ + dragenter: function (event) { + if (first) { + second = true; + return; + } else { + first = true; + $this.trigger('dragster:enter', event); + } + event.preventDefault(); + }, + dragleave: function (event) { + if (second) { + second = false; + } else if (first) { + first = false; + } + if (!first && !second) { + $this.trigger('dragster:leave', event); + } + event.preventDefault(); + }, + dragover: function (event) { + $this.trigger('dragster:over', event); + event.preventDefault(); + }, + drop: function (event) { + if (second) { + second = false; + } else if (first) { + first = false; + } + if (!first && !second) { + $this.trigger('dragster:drop', event); + } + event.preventDefault(); + }, + 'dragster:enter': settings.enter, + 'dragster:leave': settings.leave, + 'dragster:over': settings.over, + 'dragster:drop': settings.drop + }); + }); + }; + +}(jQuery)); diff --git a/web/templates/head.html b/web/templates/head.html index 7a7d4fe8e..dd5e9f46e 100644 --- a/web/templates/head.html +++ b/web/templates/head.html @@ -32,6 +32,8 @@ + + -- cgit v1.2.3-1-g7c22 From 6f091f0f6d17b74a5d87517ef35f89cd46e1bcb4 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Tue, 11 Aug 2015 15:31:07 -0700 Subject: Added check to make sure files are not strings --- web/react/components/file_upload.jsx | 8 ++++++-- web/react/components/post_list.jsx | 6 +----- web/react/components/post_right.jsx | 7 +------ web/sass-files/sass/partials/_files.scss | 4 ---- web/sass-files/sass/partials/_post.scss | 5 ----- 5 files changed, 8 insertions(+), 22 deletions(-) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index f382b848a..05c883ffc 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -84,13 +84,17 @@ module.exports = React.createClass({ this.props.onUploadError(null); var files = e.originalEvent.dataTransfer.files; - if (files.length) { + if (!files.length) { + files = e.originalEvent.dataTransfer.getData('URL'); + } + var channelId = this.props.channelId || ChannelStore.getCurrentId(); + + if (typeof files !== 'string' && files.length) { var numFiles = files.length; var numToUpload = this.props.setUploads(numFiles); for (var i = 0; i < numFiles && i < numToUpload; i++) { var file = files[i]; - var channelId = this.props.channelId || ChannelStore.getCurrentId(); var formData = new FormData(); formData.append('channel_id', channelId); diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 826d34a7d..83f806b79 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -124,6 +124,7 @@ module.exports = React.createClass({ $(this).parent('div').next('.date-separator, .new-separator').removeClass('hovered--comment'); } }); + }, componentDidUpdate: function() { this.resize(); @@ -461,11 +462,6 @@ module.exports = React.createClass({ postCtls.push(); } - var fileDragOverlay = ''; - if (this.state.fileDrag) { - fileDragOverlay = 'post-list-file-overlay'; - } - return (
diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index ad993aee1..ad8b54012 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -294,13 +294,8 @@ module.exports = React.createClass({ var currentId = UserStore.getCurrentId(); var searchForm = currentId == null ? null : ; - var fileDragOverlay = ''; - if (this.state.fileDrag) { - fileDragOverlay = 'post-right-file-overlay'; - } - return ( -
+
{searchForm}
diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss index 83c87132b..3736f9303 100644 --- a/web/sass-files/sass/partials/_files.scss +++ b/web/sass-files/sass/partials/_files.scss @@ -204,13 +204,9 @@ } .center-file-overlay { - width: 100%; - height: 100%; background:rgba(255,255,255,0.5); } .right-file-overlay { - width: 100%; - height: 100%; background:rgba(255,255,255,0.5); } diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index 093e10ee0..98b17120d 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -107,11 +107,6 @@ body.ios { } #post-list { - .post-list-file-overlay { - width: 100%; - height: 100%; - background:rgba(255,255,255,0.5); - } .post-list-holder-by-time { background: #fff; overflow-y: scroll; -- cgit v1.2.3-1-g7c22 From 596e76d40418465c80fadb640450ee4d37bc4e1e Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 12 Aug 2015 08:30:03 -0700 Subject: Fixed issue with uploading files from RHS when trying to upload after opening the RHS and then switching channels --- web/react/components/file_upload.jsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index 05c883ffc..7918b42ec 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -14,7 +14,7 @@ module.exports = React.createClass({ var element = $(this.refs.fileInput.getDOMNode()); var files = element.prop('files'); - var channelId = ChannelStore.getCurrentId(); + var channelId = this.props.channelId || ChannelStore.getCurrentId(); this.props.onUploadError(null); @@ -192,14 +192,13 @@ module.exports = React.createClass({ continue; } - var channelId = ChannelStore.getCurrentId(); + var channelId = this.props.channelId || ChannelStore.getCurrentId(); // generate a unique id that can be used by other components to refer back to this file upload var clientId = utils.generateId(); var formData = new FormData(); formData.append('channel_id', channelId); - var d = new Date(); var hour; if (d.getHours() < 10) { -- cgit v1.2.3-1-g7c22 From 0f1c9917271d8e28c55b8d930ac9057ef19e5862 Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 12 Aug 2015 12:47:29 -0700 Subject: Updated feature to work with new upload cancel logic --- web/react/components/file_upload.jsx | 39 +++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index 7918b42ec..641a888c7 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -91,24 +91,49 @@ module.exports = React.createClass({ if (typeof files !== 'string' && files.length) { var numFiles = files.length; - var numToUpload = this.props.setUploads(numFiles); - for (var i = 0; i < numFiles && i < numToUpload; i++) { - var file = files[i]; + var numToUpload = Math.min(Constants.MAX_UPLOAD_FILES - this.props.getFileCount(channelId), numFiles); + if (numFiles > numToUpload) { + this.props.onUploadError('Uploads limited to ' + Constants.MAX_UPLOAD_FILES + ' files maximum. Please use additional posts for more files.'); + } + + for (var i = 0; i < files.length && i < numToUpload; i++) { + if (files[i].size > Constants.MAX_FILE_SIZE) { + this.props.onUploadError('Files must be no more than ' + Constants.MAX_FILE_SIZE / 1000000 + ' MB'); + continue; + } + + // generate a unique id that can be used by other components to refer back to this file upload + var clientId = utils.generateId(); + + // Prepare data to be uploaded. var formData = new FormData(); formData.append('channel_id', channelId); - formData.append('files', file, file.name); + formData.append('files', files[i], files[i].name); + formData.append('client_ids', clientId); - client.uploadFile(formData, + var request = client.uploadFile(formData, function(data) { var parsedData = $.parseJSON(data); - this.props.onFileUpload(parsedData.filenames, channelId); + this.props.onFileUpload(parsedData['filenames'], parsedData['client_ids'], channelId); + + var requests = this.state.requests; + for (var i = 0; i < parsedData['client_ids'].length; i++) { + delete requests[parsedData['client_ids'][i]]; + } + this.setState({requests: requests}); }.bind(this), function(err) { - this.props.onUploadError(err); + this.props.onUploadError(err, clientId); }.bind(this) ); + + var requests = this.state.requests; + requests[clientId] = request; + this.setState({requests: requests}); + + this.props.onUploadStart([clientId], channelId); } } }, -- cgit v1.2.3-1-g7c22 From 14c121dc0cccdd36f97b0b13cde6dd3a5802bb9e Mon Sep 17 00:00:00 2001 From: Reed Garmsen Date: Wed, 12 Aug 2015 14:12:17 -0700 Subject: Implements better markup for css changes to be made, including an overlay of the dropzones and help pic/text --- web/react/components/file_upload.jsx | 18 ++++++++++++------ web/react/components/post_list.jsx | 16 +++++++++++----- web/react/components/post_right.jsx | 4 ++++ web/sass-files/sass/partials/_files.scss | 7 ------- web/sass-files/sass/partials/_post.scss | 23 +++++++++++++++++++++++ web/sass-files/sass/partials/_post_right.scss | 23 +++++++++++++++++++++++ web/static/js/jquery-dragster/bower.json | 25 ------------------------- 7 files changed, 73 insertions(+), 43 deletions(-) delete mode 100644 web/static/js/jquery-dragster/bower.json diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index 641a888c7..adf0a9fa8 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -144,26 +144,32 @@ module.exports = React.createClass({ if (this.props.postType === 'post') { $('.app__content').dragster({ enter: function(dragsterEvent, e) { - $('.app__content').addClass('center-file-overlay'); + $('.center-file-overlay').removeClass('invisible'); + $('.center-file-overlay').addClass('visible'); }, leave: function(dragsterEvent, e) { - $('.app__content').removeClass('center-file-overlay'); + $('.center-file-overlay').removeClass('visible'); + $('.center-file-overlay').addClass('invisible'); }, drop: function(dragsterEvent, e) { - $('.app__content').removeClass('center-file-overlay'); + $('.center-file-overlay').removeClass('visible'); + $('.center-file-overlay').addClass('invisible'); self.handleDrop(e); } }); } else if (this.props.postType === 'comment') { $('.post-right__container').dragster({ enter: function(dragsterEvent, e) { - $('.post-right__container').addClass('right-file-overlay'); + $('.right-file-overlay').removeClass('invisible'); + $('.right-file-overlay').addClass('visible'); }, leave: function(dragsterEvent, e) { - $('.post-right__container').removeClass('right-file-overlay'); + $('.right-file-overlay').removeClass('visible'); + $('.right-file-overlay').addClass('invisible'); }, drop: function(dragsterEvent, e) { - $('.post-right__container').removeClass('right-file-overlay'); + $('.right-file-overlay').removeClass('visible'); + $('.right-file-overlay').addClass('invisible'); self.handleDrop(e); } }); diff --git a/web/react/components/post_list.jsx b/web/react/components/post_list.jsx index 83f806b79..756ed521d 100644 --- a/web/react/components/post_list.jsx +++ b/web/react/components/post_list.jsx @@ -463,11 +463,17 @@ module.exports = React.createClass({ } return ( -
-
-
- { more_messages } - { postCtls } +
+
+ Drop a file to upload it. + +
+
+
+
+ { more_messages } + { postCtls } +
diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index ad8b54012..49c12ad9c 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -296,6 +296,10 @@ module.exports = React.createClass({ return (
+
+ Drop a file to upload it. + +
{searchForm}
diff --git a/web/sass-files/sass/partials/_files.scss b/web/sass-files/sass/partials/_files.scss index 3736f9303..9bf6fd83a 100644 --- a/web/sass-files/sass/partials/_files.scss +++ b/web/sass-files/sass/partials/_files.scss @@ -203,10 +203,3 @@ } } -.center-file-overlay { - background:rgba(255,255,255,0.5); -} - -.right-file-overlay { - background:rgba(255,255,255,0.5); -} diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index 98b17120d..0af5c01e2 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -107,6 +107,29 @@ body.ios { } #post-list { + .center-file-overlay { + top: 0px; + height: 100%; + width: 59.7%; + position: fixed; + z-index: 2147483646; + -moz-box-shadow: 0px 0px 3px #8a8a8a; + -webkit-box-shadow: 0px 0px 3px #8a8a8a; + box-shadow: 0px 0px 3px #8a8a8a; + + .invisible { + visibility: hidden; + } + .visible { + visibility: visible; + } + .center-file-help-text { + + } + .center-file-help-picture { + + } + } .post-list-holder-by-time { background: #fff; overflow-y: scroll; diff --git a/web/sass-files/sass/partials/_post_right.scss b/web/sass-files/sass/partials/_post_right.scss index 4cf3e32a1..41b7aaada 100644 --- a/web/sass-files/sass/partials/_post_right.scss +++ b/web/sass-files/sass/partials/_post_right.scss @@ -1,5 +1,28 @@ .post-right__container { + .right-file-overlay { + height: 100%; + width: 100%; + position: fixed; + z-index: 2147483646; + -moz-box-shadow: 0px 0px 3px #8a8a8a; + -webkit-box-shadow: 0px 0px 3px #8a8a8a; + box-shadow: 0px 0px 3px #8a8a8a; + + .invisible { + visibility: hidden; + } + .visible { + visibility: visible; + } + .right-file-help-text { + + } + .right-file-help-picture { + + } + } + .post-right-root-message { padding: 1em 1em 0; } diff --git a/web/static/js/jquery-dragster/bower.json b/web/static/js/jquery-dragster/bower.json deleted file mode 100644 index a3cf7ed16..000000000 --- a/web/static/js/jquery-dragster/bower.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "jquery-dragster", - "version": "1.0.3", - "homepage": "https://github.com/catmanjan/jquery-dragster", - "authors": [ - "catmanjan" - ], - "description": "Unified drag and drop listener", - "main": "jquery.dragster.js", - "keywords": [ - "jquery", - "dragster", - "dragenter", - "dragleave", - "drop" - ], - "license": "MIT", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests" - ] -} -- cgit v1.2.3-1-g7c22