Skip to content
This repository has been archived by the owner on Nov 8, 2018. It is now read-only.

Show attachments as blocks instead of list to allow enhanced actions #1448

Merged
merged 6 commits into from
May 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions css/mail.css
Original file line number Diff line number Diff line change
Expand Up @@ -614,20 +614,49 @@ input.submit-message,
.mail-message-attachments {
margin-bottom: 20px;
}
.mail-message-attachment {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.mail-message-attachments .attachments > div {
position: relative;
display: inline-block;
border: 1px solid #f5f5f5;
margin: 5px;
padding: 6px;
}
.mail-message-attachment-image {
margin-bottom: 32px;
.mail-message-attachments .attachments > div:hover,
.mail-message-attachments .attachments > div span:hover {
background-color: #f8f8f8;
cursor: pointer;
}
@media only screen and (max-width: 768px) {
.mail-message-attachments .attachments > div {
width: calc(100% - 5px);
}
}
@media only screen and (min-width: 769px) and (max-width: 1400px) {
.mail-message-attachments .attachments > div {
width: calc(50% - 10px);
}
}
@media only screen and (min-width: 1401px) {
.mail-message-attachments .attachments > div {
width: calc(33% - 12px);
}
}
.mail-message-attachments .mail-attached-image {
max-width: 100%;
max-height: 120px;
}
.attachment-save-to-cloud,
.attachment-download {
position: absolute;
height: 32px;
min-width: 32px;
float: left;
display: inline-block;
width: 32px;
bottom: 3px;
}
.attachment-save-to-cloud {
right: 3px;
}
.attachment-download {
right: 41px;
}
/* show icon + text for Download all button
as well as when there is only one attachment */
Expand All @@ -638,6 +667,14 @@ input.submit-message,
background-position: 9px center;
padding-left: 32px;
}
.attachment-name {
display: inline-block;
width: calc(100% - 110px);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
}
/* show attachment size less prominent */
.attachment-size {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
Expand Down
1 change: 1 addition & 0 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ define(function(require) {
require('controller/foldercontroller');
require('controller/messagecontroller');
require('service/accountservice');
require('service/attachmentservice');
require('service/folderservice');
require('service/messageservice');
require('notification');
Expand Down
96 changes: 42 additions & 54 deletions js/controller/messagecontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,66 +126,54 @@ define(function(require) {
}

/**
* @param {Account} account
* @param {Folder} folder
* @param {number} messageId
* @param {number} attachmentId
* @returns {undefined}
* @returns {Promise}
*/
function saveAttachment(messageId, attachmentId) {
function saveAttachmentToFiles(account, folder, messageId, attachmentId) {
var defer = $.Deferred();
var saveAll = _.isUndefined(attachmentId);

OC.dialogs.filepicker(
t('mail', 'Choose a folder to store the attachment in'),
function(path) {
// Loading feedback
var saveToFilesBtnSelector = '.attachment-save-to-cloud';
if (typeof attachmentId !== 'undefined') {
saveToFilesBtnSelector = 'li[data-attachment-id="' +
attachmentId + '"] ' + saveToFilesBtnSelector;
}
$(saveToFilesBtnSelector)
.removeClass('icon-folder')
.addClass('icon-loading-small')
.prop('disabled', true);

$.ajax(
OC.generateUrl(
'apps/mail/accounts/{accountId}/' +
'folders/{folderId}/messages/{messageId}/' +
'attachment/{attachmentId}',
{
accountId: require('state').currentAccount.get('accountId'),
folderId: require('state').currentFolder.get('id'),
messageId: messageId,
attachmentId: attachmentId
}), {
data: {
targetPath: path
},
type: 'POST',
success: function() {
if (typeof attachmentId === 'undefined') {
Radio.ui.trigger('error:show', t('mail', 'Attachments saved to Files.'));
} else {
Radio.ui.trigger('error:show', t('mail', 'Attachment saved to Files.'));
}
},
error: function() {
if (typeof attachmentId === 'undefined') {
Radio.ui.trigger('error:show', t('mail', 'Error while saving attachments to Files.'));
} else {
Radio.ui.trigger('error:show', t('mail', 'Error while saving attachment to Files.'));
}
},
complete: function() {
// Remove loading feedback again
$('.attachment-save-to-cloud')
.removeClass('icon-loading-small')
.addClass('icon-folder')
.prop('disabled', false);
var savingToFiles = Radio.message.request('save:cloud', account,
folder, messageId, attachmentId, path);
$.when(savingToFiles).done(function() {
if (saveAll) {
Radio.ui.trigger('error:show', t('mail', 'Attachments saved to Files.'));
} else {
Radio.ui.trigger('error:show', t('mail', 'Attachment saved to Files.'));
}
defer.resolve();
});
},
false,
'httpd/unix-directory',
true
);
$.when(savingToFiles).fail(function() {
if (saveAll) {
Radio.ui.trigger('error:show', t('mail', 'Error while saving attachments to Files.'));
} else {
Radio.ui.trigger('error:show', t('mail', 'Error while saving attachment to Files.'));
}
defer.reject();
});
}, false, 'httpd/unix-directory', true);

return defer.promise();
}
});

/**
* @param {Account} account
* @param {Folder} folder
* @param {number} messageId
* @returns {Promise}
*/
function saveAttachmentsToFiles(account, folder, messageId) {
return saveAttachmentToFiles(account, folder, messageId);
}

return {
saveAttachmentToFiles: saveAttachmentToFiles,
saveAttachmentsToFiles: saveAttachmentsToFiles
};
});
7 changes: 5 additions & 2 deletions js/models/attachment.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,23 @@
* later. See the COPYING file.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @copyright Christoph Wurst 2015
* @copyright Christoph Wurst 2015, 2016
*/

define(function(require) {
'use strict';

var Backbone = require('backbone');
var _ = require('underscore');

/**
* @class Attachment
*/
var Attachment = Backbone.Model.extend({
initialize: function() {
this.set('id', _.uniqueId());
if (_.isUndefined(this.get('id'))) {
this.set('id', _.uniqueId());
}

var s = this.get('fileName');
if (s.charAt(0) === '/') {
Expand Down
66 changes: 66 additions & 0 deletions js/service/attachmentservice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
*
* ownCloud - Mail
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/

define(function(require) {
'use strict';

var $ = require('jquery');
var OC = require('OC');
var Radio = require('radio');

Radio.message.reply('save:cloud', saveToFiles);

/**
* @param {Account} account
* @param {Folder} folder
* @param {number} messageId
* @param {number} attachmentId
* @param {string} path
* @returns {Promise}
*/
function saveToFiles(account, folder, messageId, attachmentId, path) {
var defer = $.Deferred();
var url = OC.generateUrl(
'apps/mail/accounts/{accountId}/' +
'folders/{folderId}/messages/{messageId}/' +
'attachment/{attachmentId}', {
accountId: account.get('accountId'),
folderId: folder.get('id'),
messageId: messageId,
attachmentId: attachmentId
});

var options = {
data: {
targetPath: path
},
type: 'POST',
success: function() {
defer.resolve();
},
error: function() {
defer.reject();
}
};

$.ajax(url, options);
return defer.promise();
}

});
8 changes: 8 additions & 0 deletions js/templates/message-attachment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{{#if isImage}}
<img class="mail-attached-image" src="{{downloadUrl}}">
<br>
{{/if}}
<img class="attachment-icon" src="{{mimeUrl}}" />
<span class="attachment-name" title="{{fileName}} ({{humanFileSize size}})">{{fileName}} <span class="attachment-size">({{humanFileSize size}})</span></span>
<button class="button icon-download attachment-download" title="{{ t 'Download attachment' }}"></button>
<button class="icon-folder attachment-save-to-cloud" title="{{ t 'Save to Files' }}"></button>
8 changes: 8 additions & 0 deletions js/templates/message-attachments.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="attachments">

</div>
{{#if moreThanOne}}
<p>
<button class="icon-folder attachments-save-to-cloud">{{ t 'Save all to Files' }}</button>
</p>
{{/if}}
36 changes: 1 addition & 35 deletions js/templates/message.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,41 +33,7 @@ <h2 title="{{subject}}">{{subject}}</h2>
</div>
{{/if}}

<div class="mail-message-attachments">
{{#if attachment}}
<ul>
<li class="mail-message-attachment mail-message-attachment-single" data-message-id="{{attachment.messageId}}" data-attachment-id="{{attachment.id}}" data-attachment-mime="{{attachment.mime}}">
{{#if attachment.isImage}}
<img class="mail-attached-image" src="{{attachment.downloadUrl}}">
<br>
{{/if}}
<img class="attachment-icon" src="{{attachment.mimeUrl}}" />
{{attachment.fileName}} <span class="attachment-size">({{humanFileSize attachment.size}})</span><br/>
<a class="button icon-download attachment-download" href="{{attachment.downloadUrl}}">{{ t 'Download attachment' }}</a>
<button class="icon-folder attachment-save-to-cloud">{{ t 'Save to Files' }}</button>
</li>
</ul>
{{/if}}
{{#if attachments}}
<ul>
{{#each attachments}}
<li class="mail-message-attachment {{#if isImage}}mail-message-attachment-image{{/if}}" data-message-id="{{messageId}}" data-attachment-id="{{id}}" data-attachment-mime="{{mime}}">
{{#if isImage}}
<img class="mail-attached-image" src="{{downloadUrl}}">
<br>
{{/if}}
<a class="button icon-download attachment-download" href="{{downloadUrl}}" title="{{ t 'Download attachment' }}"></a>
<button class="icon-folder attachment-save-to-cloud" title="{{ t 'Save to Files' }}"></button>
<img class="attachment-icon" src="{{mimeUrl}}" />
{{fileName}} <span class="attachment-size">({{humanFileSize size}})</span>
</li>
{{/each}}
</ul>
<p>
<button data-message-id="{{id}}" class="icon-folder attachments-save-to-cloud">{{ t 'Save all to Files' }}</button>
</p>
{{/if}}
</div>
<div class="mail-message-attachments"></div>
<div id="reply-composer"></div>
<input type="button" id="forward-button" value="{{ t 'Forward' }}">
</div>
20 changes: 0 additions & 20 deletions js/views/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,6 @@ define(function(require) {
Radio.message.trigger('forward');
});

// TODO: create marionette view and encapsulate events
$(document).on('click', '#mail-message .attachment-save-to-cloud', function(event) {
event.stopPropagation();
var messageId = $(this).parent().data('messageId');
var attachmentId = $(this).parent().data('attachmentId');
Radio.message.trigger('attachment:save', messageId, attachmentId);
});

// TODO: create marionette view and encapsulate events
$(document).on('click', '#mail-message .attachments-save-to-cloud', function(event) {
event.stopPropagation();
var messageId = $(this).data('messageId');
Radio.message.trigger('attachment:save', messageId);
});

$(document).on('click', '.link-mailto', function(event) {
Radio.ui.trigger('composer:show', event);
});
Expand Down Expand Up @@ -149,11 +134,6 @@ define(function(require) {
// Resize iframe
var iframe = $('#mail-content iframe');
iframe.height(iframe.contents().find('html').height() + 20);

// resize width of attached images
$('.mail-message-attachments .mail-attached-image').each(function() {
$(this).css('max-width', $('.mail-message-body').width());
});
},
render: function() {
// This view doesn't need rendering
Expand Down
Loading