Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d3808a097
|
||
|
|
6aa13d7243
|
||
|
|
6804e80528
|
@@ -52,7 +52,7 @@ const GalleryContent = <template>
|
||||
<button
|
||||
class="dropdown-item text-danger"
|
||||
type="button"
|
||||
{{on "click" (fn @deletePhotoTask.perform closeMenu)}}
|
||||
{{on "click" (fn @deletePhoto closeMenu)}}
|
||||
>Delete Photo</button>
|
||||
{{/if}}
|
||||
</DropdownMenu>
|
||||
@@ -259,21 +259,27 @@ export default class PhotoGallery extends Component {
|
||||
this.zapModalOpen = false;
|
||||
}
|
||||
|
||||
deletePhotoTask = task(async (closeMenu) => {
|
||||
@action
|
||||
deletePhoto(closeMenu, e) {
|
||||
e?.stopPropagation();
|
||||
if (closeMenu) closeMenu();
|
||||
if (
|
||||
!confirm(
|
||||
'Are you sure you want to delete this photo? This cannot be undone.'
|
||||
)
|
||||
) {
|
||||
if (closeMenu) closeMenu();
|
||||
return;
|
||||
}
|
||||
this.deletePhotoTask.perform();
|
||||
}
|
||||
|
||||
deletePhotoTask = task(async () => {
|
||||
const deletedEventId = this.currentPhoto.eventId;
|
||||
const deletedIndex = this.args.photos?.indexOf(this.currentPhoto) ?? -1;
|
||||
|
||||
try {
|
||||
const eventId = this.currentPhoto.eventId;
|
||||
|
||||
// Publish Nostr kind: 5 deletion event first so we don't end up with dead blossom links on a failure
|
||||
const tags = [['e', eventId]];
|
||||
const tags = [['e', deletedEventId]];
|
||||
|
||||
if (this.currentPhoto.placeIdentifier) {
|
||||
tags.push(['i', this.currentPhoto.placeIdentifier]);
|
||||
@@ -316,12 +322,20 @@ export default class PhotoGallery extends Component {
|
||||
|
||||
this.toast.show('Photo deleted successfully');
|
||||
|
||||
if (closeMenu) closeMenu();
|
||||
this.handleClose();
|
||||
// Navigate to the next remaining photo, or close the gallery if none left.
|
||||
// this.args.photos may be stale until Glimmer re-renders, so filter locally.
|
||||
const remaining = (this.args.photos || []).filter(
|
||||
(p) => p.eventId !== deletedEventId
|
||||
);
|
||||
if (remaining.length === 0) {
|
||||
this.handleClose();
|
||||
} else {
|
||||
this.currentPhoto =
|
||||
remaining[Math.min(deletedIndex, remaining.length - 1)];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to delete photo:', e);
|
||||
this.toast.show('Failed to delete photo: ' + e.message);
|
||||
if (closeMenu) closeMenu();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -333,7 +347,7 @@ export default class PhotoGallery extends Component {
|
||||
@handleKeydown={{this.handleKeydown}}
|
||||
@copyEventId={{this.copyEventId}}
|
||||
@canDeletePhoto={{this.canDeletePhoto}}
|
||||
@deletePhotoTask={{this.deletePhotoTask}}
|
||||
@deletePhoto={{this.deletePhoto}}
|
||||
@handleClose={{this.handleClose}}
|
||||
@photos={{@photos}}
|
||||
@currentPhoto={{this.currentPhoto}}
|
||||
@@ -356,7 +370,7 @@ export default class PhotoGallery extends Component {
|
||||
@handleKeydown={{this.handleKeydown}}
|
||||
@copyEventId={{this.copyEventId}}
|
||||
@canDeletePhoto={{this.canDeletePhoto}}
|
||||
@deletePhotoTask={{this.deletePhotoTask}}
|
||||
@deletePhoto={{this.deletePhoto}}
|
||||
@handleClose={{this.handleClose}}
|
||||
@photos={{@photos}}
|
||||
@currentPhoto={{this.currentPhoto}}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "marco",
|
||||
"version": "1.32.0",
|
||||
"version": "1.32.1",
|
||||
"private": true,
|
||||
"description": "Unhosted maps app",
|
||||
"repository": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -42,7 +42,7 @@
|
||||
<meta name="msapplication-TileColor" content="#F6E9A6">
|
||||
<meta name="msapplication-TileImage" content="/icons/icon-144.png">
|
||||
|
||||
<script type="module" crossorigin src="/assets/main-Znuwpp9Y.js"></script>
|
||||
<script type="module" crossorigin src="/assets/main-qw72UzgO.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/main-CEhcTO-R.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -133,6 +133,9 @@ module('Integration | Component | photo-gallery', function (hooks) {
|
||||
|
||||
assert.ok(confirmStub.calledOnce, 'confirmation dialog was shown');
|
||||
assert.ok(blossomSpy.notCalled, 'blossom.delete was NOT called');
|
||||
assert
|
||||
.dom('.dropdown-popover')
|
||||
.doesNotExist('dropdown menu was closed on cancel');
|
||||
});
|
||||
|
||||
test('it performs full deletion flow when confirmed', async function (assert) {
|
||||
@@ -226,7 +229,58 @@ module('Integration | Component | photo-gallery', function (hooks) {
|
||||
toastSpy.calledWith('Photo deleted successfully'),
|
||||
'success toast was shown'
|
||||
);
|
||||
assert.ok(closed, 'gallery was closed after deletion');
|
||||
assert
|
||||
.dom('.dropdown-popover')
|
||||
.doesNotExist('dropdown menu was closed after deletion');
|
||||
assert.notOk(closed, 'gallery was kept open after deletion');
|
||||
});
|
||||
|
||||
test('it closes the gallery when deleting the last remaining photo', async function (assert) {
|
||||
this.nostrAuth.pubkey = USER_A;
|
||||
this.settings.update('experimentalEnablePhotoDeletion', true);
|
||||
Object.defineProperty(this.nostrAuth, 'signer', {
|
||||
configurable: true,
|
||||
get: () => ({
|
||||
signEvent: async (e) => ({
|
||||
...e,
|
||||
id: 'a3b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1',
|
||||
sig: 'b3b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1',
|
||||
pubkey: USER_A,
|
||||
}),
|
||||
getPublicKey: async () => USER_A,
|
||||
}),
|
||||
});
|
||||
|
||||
this.set('photos', [this.photos[0]]);
|
||||
this.selectedPhoto = this.photos[0];
|
||||
|
||||
let closed = false;
|
||||
this.handleClose = () => {
|
||||
closed = true;
|
||||
};
|
||||
|
||||
sinon.stub(window, 'confirm').returns(true);
|
||||
sinon.stub(this.blossom, 'delete').resolves();
|
||||
sinon.stub(this.nostrRelay, 'publish').resolves();
|
||||
sinon.stub(this.nostrData.store, 'add');
|
||||
|
||||
await render(
|
||||
<template>
|
||||
<div id="test-container">
|
||||
<div id="modal-portal"></div>
|
||||
<PhotoGallery
|
||||
@photos={{this.photos}}
|
||||
@selectedPhoto={{this.selectedPhoto}}
|
||||
@onClose={{this.handleClose}}
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
);
|
||||
|
||||
await click('.dropdown-trigger-btn');
|
||||
await click('.dropdown-item.text-danger');
|
||||
|
||||
assert.ok(closed, 'gallery was closed when last photo was deleted');
|
||||
});
|
||||
|
||||
test('it copies event id to clipboard', async function (assert) {
|
||||
|
||||
Reference in New Issue
Block a user