Merge pull request #407 from padloc/feature/drag-and-drop-attachments

Allow drag & drop for attachments
This commit is contained in:
Martin Kleinschrodt 2022-02-26 16:39:18 +01:00 committed by GitHub
commit 97f016d7d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 9 deletions

View File

@ -33,6 +33,7 @@
"pwa:start": "lerna run start --scope @padloc/pwa",
"server:start": "lerna run start --scope @padloc/server --stream",
"server:start-dry": "lerna run start-dry --stream --scope @padloc/server",
"electron:start": "lerna run start --scope @padloc/electron",
"electron:build": "lerna run build --scope @padloc/electron",
"web-extension:build": "lerna run build --scope @padloc/extension",
"cordova:start:android": "lerna run start:android",
@ -47,11 +48,11 @@
"dev": "lerna run --parallel --scope '@padloc/{server,pwa}' --parallel dev",
"tauri:dev": "lerna run --parallel --scope '@padloc/{server,tauri}' --parallel dev",
"tauri:update": "lerna run update",
"tauri:build": "lerna run build --scope @padloc/tauri",
"tauri:build:debug": "lerna run build:debug --scope @padloc/tauri",
"tauri:build": "lerna run build:production",
"tauri:build:debug": "lerna run build --scope @padloc/tauri",
"repl": "cd packages/server && npm run repl && cd ../..",
"test": "lerna run test",
"test:e2e": "concurrently --prefix=name --prefix-length=30 --kill-others --success=first -n app,v3-app,cypress \"PL_DATA_BACKEND=memory PL_DISABLE_SW=true PL_EMAIL_BACKEND=smtp PL_EMAIL_SMTP_HOST=localhost PL_EMAIL_SMTP_PORT=1025 PL_EMAIL_SMTP_IGNORE_TLS=true npm start\" \"npm run start:v3\" \"npx maildev\" \"./node_modules/.bin/wait-on tcp:localhost:8080 && CYPRESS_CRASH_REPORTS=0 cypress run\"",
"test:e2e": "concurrently --prefix=name --prefix-length=30 --kill-others --success=first -n app,v3-app,maildev,cypress \"PL_DATA_BACKEND=memory PL_DISABLE_SW=true PL_EMAIL_BACKEND=smtp PL_EMAIL_SMTP_HOST=localhost PL_EMAIL_SMTP_PORT=1025 PL_EMAIL_SMTP_IGNORE_TLS=true npm start\" \"npm run start:v3\" \"npx maildev\" \"./node_modules/.bin/wait-on tcp:localhost:8080 && CYPRESS_CRASH_REPORTS=0 cypress run\"",
"test:e2e:dev": "concurrently --prefix=name --prefix-length=30 --kill-others --success=first -n app,v3-app,cypress \"PL_DATA_BACKEND=memory PL_DISABLE_SW=true PL_EMAIL_BACKEND=smtp PL_EMAIL_SMTP_HOST=localhost PL_EMAIL_SMTP_PORT=1025 PL_EMAIL_SMTP_IGNORE_TLS=true npm run dev\" \"npm run start:v3\" \"npx maildev\" \"./node_modules/.bin/wait-on tcp:localhost:8080 && CYPRESS_CRASH_REPORTS=0 cypress open\"",
"locale:extract": "lerna run extract --scope '@padloc/locale'",
"add": "lerna add $1 --scope=@padloc/$scope",

View File

@ -65,6 +65,9 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
@state()
private _fields: Field[] = [];
@state()
private _isDraggingFileToAttach: boolean = false;
@query("#nameInput")
private _nameInput: Input;
@ -256,7 +259,12 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
const isFavorite = app.account!.favorites.has(this.itemId);
return html`
<div class="fullbleed vertical layout">
<div
class="fullbleed vertical layout"
@drop=${this._handleDrop}
@dragover=${this._handleDragOver}
@dragleave=${this._handleDragLeave}
>
<header class="animated padded center-aligning horizontal layout">
<pl-button
class="transparent slim back-button"
@ -393,7 +401,7 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
</pl-list>
</div>
<div class="attachments" ?hidden=${!attachments.length}>
<div class="attachments">
<h2
class="horizontally-double-margined bottom-margined animated section-header"
style="margin-left: 2.2em;"
@ -401,7 +409,7 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
${$l("Attachments")}
</h2>
<pl-list class="border-top border-bottom block">
<pl-list class="border-top block" ?hidden=${!attachments.length}>
${attachments.map(
(a) => html`
<pl-attachment
@ -415,6 +423,17 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
`
)}
</pl-list>
<div
class="double-padded text-centering border-top border-bottom hover click"
@click=${() => this.addAttachment()}
>
<span class="small ${this._isDraggingFileToAttach ? "highlighted bold" : "subtle"}">
<pl-icon class="inline" icon="attachment"></pl-icon> ${$l(
"Click or drag files here to add an attachment!"
)}
</span>
</div>
</div>
<div class="stretch"></div>
@ -556,9 +575,7 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
}
}
private async _attachFile() {
const file = this._fileInput.files![0];
this._fileInput.value = "";
private async _addFileAttachment(file: File) {
if (!file) {
return;
}
@ -577,6 +594,12 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
}
}
private async _attachFile() {
const file = this._fileInput.files![0];
this._fileInput.value = "";
this._addFileAttachment(file);
}
private async _openAttachment(info: AttachmentInfo) {
if (this._editing) {
return;
@ -619,6 +642,40 @@ export class ItemView extends Routing(StateMixin(LitElement)) {
}
}
private async _handleDrop(event: DragEvent) {
event.preventDefault();
this._isDraggingFileToAttach = true;
if (event.dataTransfer?.items) {
for (const transferItem of event.dataTransfer.items) {
// Only handle files
if (transferItem.kind === "file") {
const transferFile = transferItem.getAsFile();
if (transferFile) {
await this._addFileAttachment(transferFile);
}
}
}
} else if (event.dataTransfer?.files) {
for (const transferFile of event.dataTransfer.files) {
await this._addFileAttachment(transferFile);
}
}
this._isDraggingFileToAttach = false;
}
private async _handleDragOver(event: DragEvent) {
event.preventDefault();
this._isDraggingFileToAttach = true;
}
private async _handleDragLeave(event: DragEvent) {
event.preventDefault();
this._isDraggingFileToAttach = false;
}
private _drop(e: DragEvent) {
// console.log("drop", e, this._draggingIndex, this._dragOverIndex);
e.preventDefault();