Skip to content
Open
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
4 changes: 4 additions & 0 deletions src/app/compose/compose.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

<mat-card [ngClass]="{'draftPreview': !editing}" class="draft-card" [formGroup]="formGroup">
<mat-card-actions class="draft-actions">
<div class="draft-title">
Expand Down Expand Up @@ -51,6 +52,7 @@
[initialfocus]="model.to.length === 0"
placeholder="To"
[recipients]="model.to"
recipientField="to"
(updateRecipient)="onUpdateRecipient('to', $event)"
(drop)="recipientDropped($event, 'to')"
id="fieldTo"
Expand Down Expand Up @@ -87,6 +89,7 @@
<mailrecipient-input *ngIf="editing" style="width: auto; flex-grow: 1"
placeholder="CC"
[recipients]="model.cc"
recipientField="cc"
(updateRecipient)="onUpdateRecipient('cc', $event)"
></mailrecipient-input>
<button mat-icon-button (click)="formGroup.controls.cc.setValue(null)"><mat-icon svgIcon="close"></mat-icon></button>
Expand All @@ -95,6 +98,7 @@
<mailrecipient-input *ngIf="editing" style="width: auto; flex-grow: 1"
placeholder="BCC"
[recipients]="model.bcc"
recipientField="bcc"
(updateRecipient)="onUpdateRecipient('bcc', $event)"
></mailrecipient-input>
<button mat-icon-button (click)="formGroup.controls.bcc.setValue(null)"><mat-icon svgIcon="close"></mat-icon></button>
Expand Down
20 changes: 17 additions & 3 deletions src/app/compose/compose.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2022 Runbox Solutions AS (runbox.com).
//
Expand Down Expand Up @@ -899,11 +900,24 @@ export class ComposeComponent implements AfterViewInit, OnDestroy, OnInit {

recipientDropped(ev: DragEvent, target: string) {
const addressLine = ev.dataTransfer.getData('recipient');

const source = ev.dataTransfer.getData('recipientSource');
const newMAI = MailAddressInfo.parse(addressLine);
const newRecipients = this.model[target].concat(newMAI);

this.onUpdateRecipient(target, newRecipients);
if (source === target) {
return;
}

if (source) {
const sourceRecipients = this.model[source].filter(
recipient => recipient.address !== newMAI[0].address
);
this.onUpdateRecipient(source, sourceRecipients);
}

const targetRecipients = this.model[target].filter(
recipient => recipient.address !== newMAI[0].address
);
this.onUpdateRecipient(target, targetRecipients.concat(newMAI));
}

/// updates the displayed `suggestedRecipients`
Expand Down
78 changes: 78 additions & 0 deletions src/app/compose/compose.recipient-drag.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2018 Runbox Solutions AS (runbox.com).
//
// This file is part of Runbox 7.
//
// Runbox 7 is free software: You can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// Runbox 7 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
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Runbox 7. If not, see <https://www.gnu.org/licenses/>.
// ---------- END RUNBOX LICENSE ----------

import { ComposeComponent } from './compose.component';
import { MailAddressInfo } from '../common/mailaddressinfo';

class TestDataTransfer {
private values: { [key: string]: string } = {};

setData(type: string, value: string) {
this.values[type] = value;
}

getData(type: string): string {
return this.values[type] || '';
}
}

describe('Compose recipient drag and drop', () => {
const alice = MailAddressInfo.parse('Alice <alice@example.com>')[0];

function fakeCompose() {
const component = {
model: { to: [alice], cc: [], bcc: [] },
onUpdateRecipient(field: string, recipients: MailAddressInfo[]) {
this.model[field] = recipients;
}
};
return component;
}

it('moves an existing recipient from To to CC', () => {
const component = fakeCompose();
const dataTransfer = new TestDataTransfer();
dataTransfer.setData('recipient', alice.nameAndAddress);
dataTransfer.setData('recipientSource', 'to');

ComposeComponent.prototype.recipientDropped.call(
component,
{ dataTransfer } as unknown as DragEvent,
'cc'
);

expect(component.model.to).toEqual([]);
expect(component.model.cc).toEqual([alice]);
});

it('does not duplicate a recipient dropped back onto the same field', () => {
const component = fakeCompose();
const dataTransfer = new TestDataTransfer();
dataTransfer.setData('recipient', alice.nameAndAddress);
dataTransfer.setData('recipientSource', 'to');

ComposeComponent.prototype.recipientDropped.call(
component,
{ dataTransfer } as unknown as DragEvent,
'to'
);

expect(component.model.to).toEqual([alice]);
});
});
4 changes: 3 additions & 1 deletion src/app/compose/mailrecipientinput.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<mat-chip-list #chipList>
<mat-chip *ngFor="let recipient of recipientsList; let ndx=index" [selectable]="selectable"
style="background-color: #e3f2fd;"
[removable]="true"
[removable]="true"
draggable="true"
(dragstart)="dragRecipient($event, recipient)"
(removed)="removeRecipient(ndx)">
{{recipient.nameAndAddress}}
<mat-icon matChipRemove svgIcon="close"></mat-icon>
Expand Down
7 changes: 7 additions & 0 deletions src/app/compose/mailrecipientinput.component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

// --------- BEGIN RUNBOX LICENSE ---------
// Copyright (C) 2016-2018 Runbox Solutions AS (runbox.com).
//
Expand Down Expand Up @@ -51,6 +52,7 @@ export class MailRecipientInputComponent implements OnChanges, AfterViewInit {
@Input() recipients: MailAddressInfo[];
@Input() placeholder: string;
@Input() initialfocus = false;
@Input() recipientField: string;

@Output() updateRecipient: EventEmitter<MailAddressInfo[]> = new EventEmitter();

Expand Down Expand Up @@ -97,6 +99,11 @@ export class MailRecipientInputComponent implements OnChanges, AfterViewInit {
this.updateRecipient.emit(this.recipientsList);
}

dragRecipient(ev: DragEvent, recipient: MailAddressInfo) {
ev.dataTransfer.setData('recipient', recipient.nameAndAddress);
ev.dataTransfer.setData('recipientSource', this.recipientField);
}

removeRecipient(ndx: number) {
this.recipientsList.splice(ndx, 1);
this.notifyChangeListener();
Expand Down