diff options
Diffstat (limited to 'client/components/cards')
-rw-r--r-- | client/components/cards/attachments.jade | 12 | ||||
-rw-r--r-- | client/components/cards/attachments.js | 85 | ||||
-rw-r--r-- | client/components/cards/attachments.styl | 11 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 54 | ||||
-rw-r--r-- | client/components/cards/labels.jade | 2 | ||||
-rw-r--r-- | client/components/cards/labels.js | 55 | ||||
-rw-r--r-- | client/components/cards/minicard.jade | 2 |
7 files changed, 135 insertions, 86 deletions
diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 59eaf077..2cb3bb85 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -3,6 +3,16 @@ template(name="cardAttachmentsPopup") li input.js-attach-file.hide(type="file" name="file" multiple) a.js-computer-upload {{_ 'computer'}} + li + a.js-upload-clipboard-image {{_ 'clipboard'}} + +template(name="previewClipboardImagePopup") + p <kbd>Ctrl</kbd>+<kbd>V</kbd> {{_ "paste-or-dragdrop"}} + img.preview-clipboard-image() + button.primary.js-upload-pasted-image {{_ 'upload'}} + +template(name="previewAttachedImagePopup") + img.preview-large-image.js-large-image-clicked(src="{{pathFor url}}") template(name="attachmentDeletePopup") p {{_ "attachment-delete-pop"}} @@ -15,7 +25,7 @@ template(name="attachmentsGalery") .attachment-thumbnail if isUploaded if isImage - img.attachment-thumbnail-img(src=url) + img.attachment-thumbnail-img.js-preview-image(src="{{pathFor url}}") else span.attachment-thumbnail-ext= extension else diff --git a/client/components/cards/attachments.js b/client/components/cards/attachments.js index ba56aa1a..1e5aa03b 100644 --- a/client/components/cards/attachments.js +++ b/client/components/cards/attachments.js @@ -1,7 +1,7 @@ Template.attachmentsGalery.events({ 'click .js-add-attachment': Popup.open('cardAttachments'), 'click .js-confirm-delete': Popup.afterConfirm('attachmentDelete', - () => { + function() { Attachments.remove(this._id); Popup.close(); } @@ -15,10 +15,43 @@ Template.attachmentsGalery.events({ // XXX Not implemented! }, 'click .js-add-cover'() { - Cards.update(this.cardId, { $set: { coverId: this._id } }); + Cards.findOne(this.cardId).setCover(this._id); }, 'click .js-remove-cover'() { - Cards.update(this.cardId, { $unset: { coverId: '' } }); + Cards.findOne(this.cardId).unsetCover(); + }, + 'click .js-preview-image'(evt) { + Popup.open('previewAttachedImage').call(this, evt); + // when multiple thumbnails, if click one then another very fast, + // we might get a wrong width from previous img. + // when popup reused, onRendered() won't be called, so we cannot get there. + // here make sure to get correct size when this img fully loaded. + const img = $('img.preview-large-image')[0]; + if (!img) return; + const rePosPopup = () => { + const w = img.width; + const h = img.height; + // if the image is too large, we resize & center the popup. + if (w > 300) { + $('div.pop-over').css({ + width: (w + 20), + position: 'absolute', + left: (window.innerWidth - w)/2, + top: (window.innerHeight - h)/2, + }); + } + }; + const url = $(evt.currentTarget).attr('src'); + if (img.src === url && img.complete) + rePosPopup(); + else + img.onload = rePosPopup; + }, +}); + +Template.previewAttachedImagePopup.events({ + 'click .js-large-image-clicked'(){ + Popup.close(); }, }); @@ -28,7 +61,7 @@ Template.cardAttachmentsPopup.events({ FS.Utility.eachFile(evt, (f) => { const file = new FS.File(f); file.boardId = card.boardId; - file.cardId = card._id; + file.cardId = card._id; Attachments.insert(file); Popup.close(); @@ -38,4 +71,48 @@ Template.cardAttachmentsPopup.events({ tpl.find('.js-attach-file').click(); evt.preventDefault(); }, + 'click .js-upload-clipboard-image': Popup.open('previewClipboardImage'), +}); + +let pastedResults = null; + +Template.previewClipboardImagePopup.onRendered(() => { + // we can paste image from clipboard + $(document.body).pasteImageReader((results) => { + if (results.dataURL.startsWith('data:image/')) { + $('img.preview-clipboard-image').attr('src', results.dataURL); + pastedResults = results; + } + }); + + // we can also drag & drop image file to it + $(document.body).dropImageReader((results) => { + if (results.dataURL.startsWith('data:image/')) { + $('img.preview-clipboard-image').attr('src', results.dataURL); + pastedResults = results; + } + }); +}); + +Template.previewClipboardImagePopup.events({ + 'click .js-upload-pasted-image'() { + const results = pastedResults; + if (results && results.file) { + const card = this; + const file = new FS.File(results.file); + if (!results.name) { + // if no filename, it's from clipboard. then we give it a name, with ext name from MIME type + if (typeof results.file.type === 'string') { + file.name(results.file.type.replace('image/', 'clipboard.')); + } + } + file.updatedAt(new Date()); + file.boardId = card.boardId; + file.cardId = card._id; + Attachments.insert(file); + pastedResults = null; + $(document.body).pasteImageReader(() => {}); + Popup.close(); + } + }, }); diff --git a/client/components/cards/attachments.styl b/client/components/cards/attachments.styl index 5cdf7386..a582f3af 100644 --- a/client/components/cards/attachments.styl +++ b/client/components/cards/attachments.styl @@ -45,3 +45,14 @@ display: block box-shadow: 0 1px 2px rgba(0,0,0,.2) +.preview-large-image + max-width: 1000px + display: block + box-shadow: 0 1px 2px rgba(0,0,0,.2) + +.preview-clipboard-image + width: 280px + height: 200px + display: block + border: 1px solid black + box-shadow: 0 1px 2px rgba(0,0,0,.2) diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 09c99f4e..b4fdca52 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -13,19 +13,19 @@ BlazeComponent.extendComponent({ }, reachNextPeak() { - const activitiesComponent = this.componentChildren('activities')[0]; + const activitiesComponent = this.childComponents('activities')[0]; activitiesComponent.loadNextPage(); }, onCreated() { this.isLoaded = new ReactiveVar(false); - this.componentParent().showOverlay.set(true); - this.componentParent().mouseHasEnterCardDetails = false; + this.parentComponent().showOverlay.set(true); + this.parentComponent().mouseHasEnterCardDetails = false; }, scrollParentContainer() { const cardPanelWidth = 510; - const bodyBoardComponent = this.componentParent(); + const bodyBoardComponent = this.parentComponent(); const $cardContainer = bodyBoardComponent.$('.js-lists'); const $cardView = this.$(this.firstNode()); @@ -52,13 +52,7 @@ BlazeComponent.extendComponent({ }, onDestroyed() { - this.componentParent().showOverlay.set(false); - }, - - updateCard(modifier) { - Cards.update(this.data()._id, { - $set: modifier, - }); + this.parentComponent().showOverlay.set(false); }, events() { @@ -68,7 +62,8 @@ BlazeComponent.extendComponent({ }, }; - return [_.extend(events, { + return [{ + ...events, 'click .js-close-card-details'() { Utils.goBoardId(this.data().boardId); }, @@ -76,23 +71,23 @@ BlazeComponent.extendComponent({ 'submit .js-card-description'(evt) { evt.preventDefault(); const description = this.currentComponent().getValue(); - this.updateCard({ description }); + this.data().setDescription(description); }, 'submit .js-card-details-title'(evt) { evt.preventDefault(); - const title = this.currentComponent().getValue(); - if ($.trim(title)) { - this.updateCard({ title }); + const title = this.currentComponent().getValue().trim(); + if (title) { + this.data().setTitle(title); } }, 'click .js-member': Popup.open('cardMember'), 'click .js-add-members': Popup.open('cardMembers'), 'click .js-add-labels': Popup.open('cardLabels'), 'mouseenter .js-card-details'() { - this.componentParent().showOverlay.set(true); - this.componentParent().mouseHasEnterCardDetails = true; + this.parentComponent().showOverlay.set(true); + this.parentComponent().mouseHasEnterCardDetails = true; }, - })]; + }]; }, }).register('cardDetails'); @@ -111,7 +106,7 @@ BlazeComponent.extendComponent({ close(isReset = false) { if (this.isOpen.get() && !isReset) { - const draft = $.trim(this.getValue()); + const draft = this.getValue().trim(); if (draft !== Cards.findOne(Session.get('currentCard')).description) { UnsavedEdits.set(this._getUnsavedEditKey(), this.getValue()); } @@ -138,14 +133,9 @@ Template.cardDetailsActionsPopup.events({ 'click .js-labels': Popup.open('cardLabels'), 'click .js-attachments': Popup.open('cardAttachments'), 'click .js-move-card': Popup.open('moveCard'), - // 'click .js-copy': Popup.open(), 'click .js-archive'(evt) { evt.preventDefault(); - Cards.update(this._id, { - $set: { - archived: true, - }, - }); + this.archive(); Popup.close(); }, 'click .js-more': Popup.open('cardMore'), @@ -155,22 +145,18 @@ Template.moveCardPopup.events({ 'click .js-select-list'() { // XXX We should *not* get the currentCard from the global state, but // instead from a “component” state. - const cardId = Session.get('currentCard'); + const card = Cards.findOne(Session.get('currentCard')); const newListId = this._id; - Cards.update(cardId, { - $set: { - listId: newListId, - }, - }); + card.move(newListId); Popup.close(); }, }); Template.cardMorePopup.events({ - 'click .js-delete': Popup.afterConfirm('cardDelete', () => { + 'click .js-delete': Popup.afterConfirm('cardDelete', function() { Popup.close(); Cards.remove(this._id); - Utils.goBoardId(this.board()._id); + Utils.goBoardId(this.boardId); }), }); diff --git a/client/components/cards/labels.jade b/client/components/cards/labels.jade index a868627c..31bd4d06 100644 --- a/client/components/cards/labels.jade +++ b/client/components/cards/labels.jade @@ -18,7 +18,7 @@ template(name="editLabelPopup") form.edit-label +formLabel button.primary.wide.left(type="submit") {{_ 'save'}} - span.right + button.js-delete-label.negate.wide.right {{_ 'delete'}} template(name="deleteLabelPopup") p {{_ "label-delete-pop"}} diff --git a/client/components/cards/labels.js b/client/components/cards/labels.js index 2da3b80b..4e61a0c6 100644 --- a/client/components/cards/labels.js +++ b/client/components/cards/labels.js @@ -13,7 +13,7 @@ BlazeComponent.extendComponent({ }, labels() { - return _.map(labelColors, (color) => { + return labelColors.map((color) => { return { color, name: '' }; }); }, @@ -45,19 +45,9 @@ Template.createLabelPopup.helpers({ Template.cardLabelsPopup.events({ 'click .js-select-label'(evt) { - const cardId = Template.parentData(2).data._id; + const card = Cards.findOne(Session.get('currentCard')); const labelId = this._id; - let operation; - if (Cards.find({ _id: cardId, labelIds: labelId}).count() === 0) - operation = '$addToSet'; - else - operation = '$pull'; - - Cards.update(cardId, { - [operation]: { - labelIds: labelId, - }, - }); + card.toggleLabel(labelId); evt.preventDefault(); }, 'click .js-edit-label': Popup.open('editLabel'), @@ -79,52 +69,27 @@ Template.formLabel.events({ Template.createLabelPopup.events({ // Create the new label 'submit .create-label'(evt, tpl) { + evt.preventDefault(); + const board = Boards.findOne(Session.get('currentBoard')); const name = tpl.$('#labelName').val().trim(); - const boardId = Session.get('currentBoard'); const color = Blaze.getData(tpl.find('.fa-check')).color; - - Boards.update(boardId, { - $push: { - labels: { - name, - color, - _id: Random.id(6), - }, - }, - }); - + board.addLabel(name, color); Popup.back(); - evt.preventDefault(); }, }); Template.editLabelPopup.events({ 'click .js-delete-label': Popup.afterConfirm('deleteLabel', function() { - const boardId = Session.get('currentBoard'); - Boards.update(boardId, { - $pull: { - labels: { - _id: this._id, - }, - }, - }); - + const board = Boards.findOne(Session.get('currentBoard')); + board.removeLabel(this._id); Popup.back(2); }), 'submit .edit-label'(evt, tpl) { evt.preventDefault(); + const board = Boards.findOne(Session.get('currentBoard')); const name = tpl.$('#labelName').val().trim(); - const boardId = Session.get('currentBoard'); - const getLabel = Utils.getLabelIndex(boardId, this._id); const color = Blaze.getData(tpl.find('.fa-check')).color; - - Boards.update(boardId, { - $set: { - [getLabel.key('name')]: name, - [getLabel.key('color')]: color, - }, - }); - + board.editLabel(this._id, name, color); Popup.back(); }, }); diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index 660b0fa5..573b3da1 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -2,7 +2,7 @@ template(name="minicard") .minicard if cover .minicard-cover - img(src=cover.url) + img(src="{{pathFor cover.url}}") if labels .minicard-labels each labels |