diff --git a/blocks/browse/da-actionbar/da-actionbar.js b/blocks/browse/da-actionbar/da-actionbar.js
index 63d45039..01c8923f 100644
--- a/blocks/browse/da-actionbar/da-actionbar.js
+++ b/blocks/browse/da-actionbar/da-actionbar.js
@@ -8,7 +8,8 @@ const STYLE = await getStyle(import.meta.url);
export default class DaActionBar extends LitElement {
static properties = {
items: { attribute: false },
- _canPaste: { state: true },
+ permissions: { attribute: false },
+ _isCopying: { state: true },
_isDeleting: { state: true },
_isMoving: { state: true },
currentPath: { type: String },
@@ -29,7 +30,7 @@ export default class DaActionBar extends LitElement {
if (props.has('items')) {
// Reset state when items go empty
if (this.items.length === 0) {
- this._canPaste = false;
+ this._isCopying = false;
this._isMoving = false;
this._isDeleting = false;
}
@@ -39,7 +40,7 @@ export default class DaActionBar extends LitElement {
}
handleClear() {
- this._canPaste = false;
+ this._isCopying = false;
this._isMoving = false;
this._isDeleting = false;
const opts = { detail: true, bubbles: true, composed: true };
@@ -54,12 +55,12 @@ export default class DaActionBar extends LitElement {
}
handleCopy() {
- this._canPaste = true;
+ this._isCopying = true;
}
handleMove() {
+ this._isCopying = true;
this._isMoving = true;
- this._canPaste = true;
}
handlePaste() {
@@ -106,13 +107,19 @@ export default class DaActionBar extends LitElement {
return itemDir !== this.currentPath;
}
+ get _canWrite() {
+ if (!this.permissions) return false;
+ return this.permissions.some((permission) => permission === 'write');
+ }
+
get _canShare() {
- return this.items.some((item) => item.ext && item.ext !== 'link');
+ const isFile = this.items.some((item) => item.ext && item.ext !== 'link');
+ return isFile && !this._isCopying;
}
get currentAction() {
const itemStr = this.items.length > 1 ? 'items' : 'item';
- if (this._canPaste) {
+ if (this._isCopying && this._canWrite) {
const folderName = this.currentPath.split('/').pop();
return `Paste ${this.items.length} ${itemStr} into ${folderName}`;
}
@@ -135,37 +142,37 @@ export default class DaActionBar extends LitElement {
+ @click=${this.handleMove}
+ class="copy-button ${this._canWrite ? '' : 'hide'} ${this._isCopying ? 'hide' : ''}">
+
+
Cut
+
diff --git a/blocks/browse/da-browse/da-browse.js b/blocks/browse/da-browse/da-browse.js
index dca0f052..74504f51 100644
--- a/blocks/browse/da-browse/da-browse.js
+++ b/blocks/browse/da-browse/da-browse.js
@@ -39,6 +39,10 @@ export default class DaBrowse extends LitElement {
this.shadowRoot.adoptedStyleSheets = [STYLE];
}
+ handlePermissions(e) {
+ if (this.newCmp) this.newCmp.permissions = e.detail;
+ }
+
handleTabClick(idx) {
this._tabItems = this._tabItems.map((tab, tidx) => ({ ...tab, selected: idx === tidx }));
}
@@ -55,6 +59,10 @@ export default class DaBrowse extends LitElement {
return this._tabItems.find((tab) => tab.selected).id;
}
+ get newCmp() {
+ return this.shadowRoot.querySelector('da-new');
+ }
+
renderNew() {
return html`
`;
}
@@ -68,6 +76,7 @@ export default class DaBrowse extends LitElement {
`;
diff --git a/blocks/browse/da-list/da-list.js b/blocks/browse/da-list/da-list.js
index 2074090f..4a1f1dc6 100644
--- a/blocks/browse/da-list/da-list.js
+++ b/blocks/browse/da-list/da-list.js
@@ -25,6 +25,7 @@ export default class DaList extends LitElement {
drag: { type: Boolean },
listItems: { attribute: false },
newItem: { attribute: false },
+ _permissions: { state: true },
_listItems: { state: true },
_selectedItems: { state: true },
_dropFiles: { state: true },
@@ -51,6 +52,7 @@ export default class DaList extends LitElement {
}
if (props.has('fullpath') && this.fullpath) {
+ this.handlePermissions(null);
this._listItems = await this.getList();
}
@@ -69,9 +71,19 @@ export default class DaList extends LitElement {
this._status = { type, text, description };
}
+ handlePermissions(permissions) {
+ this._permissions = permissions;
+
+ // Notify parent
+ const opts = { detail: permissions, bubbles: true, composed: true };
+ const event = new CustomEvent('onpermissions', opts);
+ this.dispatchEvent(event);
+ }
+
async getList() {
const resp = await daFetch(`${DA_ORIGIN}/list${this.fullpath}`);
- if (!resp.ok) return null;
+ if (!resp.ok) return [];
+ if (resp.permissions) this.handlePermissions(resp.permissions);
return resp.json();
}
@@ -127,6 +139,12 @@ export default class DaList extends LitElement {
this.requestUpdate();
}
+ wait(milliseconds) {
+ return new Promise((r) => {
+ setTimeout(r, milliseconds);
+ });
+ }
+
async handlePasteItem(item) {
let continuation = true;
let continuationToken;
@@ -140,6 +158,13 @@ export default class DaList extends LitElement {
if (resp.status === 204) {
continuation = false;
break;
+ } else if (resp.status >= 400) {
+ this.setStatus('Copying', 'There was an issue copying.');
+
+ // TODO maybe there is a better way to keep the status dialog visible for a bit?
+ await this.wait(2000);
+
+ return;
}
const json = await resp.json();
({ continuationToken } = json);
@@ -418,6 +443,7 @@ export default class DaList extends LitElement {
${this.drag ? this.renderDropArea() : nothing}
permission === 'write');
+ }
+
render() {
return html`
-
+