Skip to content

Commit 8765cf4

Browse files
committed
Viewer: Add a three-dot menu to perform additional actions photoprism#4811
Signed-off-by: Michael Mayer <michael@photoprism.app>
1 parent c78b023 commit 8765cf4

File tree

2 files changed

+106
-17
lines changed

2 files changed

+106
-17
lines changed

frontend/src/component/lightbox.vue

+103-15
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,35 @@
9090
></v-icon>
9191
</div>
9292
</div>
93+
<v-menu
94+
v-if="menuElement"
95+
transition="slide-y-transition"
96+
:activator="menuElement"
97+
open-on-click
98+
open-on-hover
99+
class="p-action-menu action-menu"
100+
@update:model-value="onShowMenu"
101+
>
102+
<v-list slim nav density="compact" :bg-color="menuBgColor" class="action-menu__list">
103+
<v-list-item
104+
v-for="action in menuActions()"
105+
:key="action.name"
106+
:value="action.name"
107+
:prepend-icon="action.icon"
108+
:title="action.text"
109+
:class="action.class ? action.class : 'action-' + action.name"
110+
:to="action.to ? action.to : undefined"
111+
:href="action.href ? action.href : undefined"
112+
:link="true"
113+
:target="action.target ? '_blank' : '_self'"
114+
:disabled="action.disabled"
115+
:nav="true"
116+
class="action-menu__item"
117+
@click="action.click"
118+
>
119+
</v-list-item>
120+
</v-list>
121+
</v-menu>
93122
</v-dialog>
94123
</template>
95124

@@ -114,6 +143,9 @@ export default {
114143
visible: false,
115144
busy: false,
116145
sidebarVisible: false,
146+
menuElement: null,
147+
menuBgColor: "#252525",
148+
menuVisible: false,
117149
lightbox: null, // Current PhotoSwipe lightbox instance.
118150
captionPlugin: null, // Current PhotoSwipe caption plugin instance.
119151
muted: window.sessionStorage.getItem("lightbox.muted") === "true",
@@ -1165,24 +1197,76 @@ export default {
11651197
11661198
// Add download button control if user has permission to use it.
11671199
if (this.canDownload) {
1168-
lightbox.pswp.ui.registerElement({
1169-
name: "download-button",
1170-
className: "pswp__button--download-button pswp__button--mdi", // Sets the icon style/size in lightbox.css.
1171-
title: this.$gettext("Download"),
1172-
ariaLabel: this.$gettext("Download"),
1173-
order: 10,
1174-
isButton: true,
1175-
html: {
1176-
isCustomSVG: true,
1177-
inner: `<path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" id="pswp__icn-download" />`,
1178-
outlineID: "pswp__icn-download", // Add this to the <path> in the inner property.
1179-
size: 24, // Depends on the original SVG viewBox, e.g. use 24 for viewBox="0 0 24 24".
1180-
},
1181-
onClick: (ev) => this.onControlClick(ev, this.onDownload),
1182-
});
1200+
// When experimental features are enabled, displays an action menu with additional options.
1201+
if (this.featExperimental) {
1202+
lightbox.pswp.ui.registerElement({
1203+
name: "menu-button",
1204+
className: "pswp__button--menu-button pswp__button--mdi", // Sets the icon style/size in lightbox.css.
1205+
ariaLabel: this.$gettext("More options"),
1206+
order: 10,
1207+
isButton: true,
1208+
html: {
1209+
isCustomSVG: true,
1210+
inner: `<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>`,
1211+
outlineID: "pswp__icn-menu-button", // Add this to the <path> in the inner property.
1212+
size: 16, // Depends on the original SVG viewBox, e.g. use 24 for viewBox="0 0 24 24".
1213+
},
1214+
onInit: (el) => {
1215+
this.menuElement = el;
1216+
},
1217+
});
1218+
} else {
1219+
lightbox.pswp.ui.registerElement({
1220+
name: "download-button",
1221+
className: "pswp__button--download-button pswp__button--mdi", // Sets the icon style/size in lightbox.css.
1222+
title: this.$gettext("Download"),
1223+
ariaLabel: this.$gettext("Download"),
1224+
order: 10,
1225+
isButton: true,
1226+
html: {
1227+
isCustomSVG: true,
1228+
inner: `<path d="M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z" id="pswp__icn-download" />`,
1229+
outlineID: "pswp__icn-download", // Add this to the <path> in the inner property.
1230+
size: 24, // Depends on the original SVG viewBox, e.g. use 24 for viewBox="0 0 24 24".
1231+
},
1232+
onClick: (ev) => this.onControlClick(ev, this.onDownload),
1233+
});
1234+
}
11831235
}
11841236
});
11851237
},
1238+
// Returns the available menu actions.
1239+
menuActions() {
1240+
return [
1241+
/* {
1242+
name: "edit",
1243+
icon: "mdi-pencil",
1244+
text: this.$gettext("Edit"),
1245+
visible: this.canEdit,
1246+
click: () => {
1247+
this.onEdit();
1248+
},
1249+
}, */
1250+
{
1251+
name: "download",
1252+
icon: "mdi-download",
1253+
text: this.$gettext("Download"),
1254+
visible: this.canDownload,
1255+
click: () => {
1256+
this.onDownload();
1257+
},
1258+
},
1259+
];
1260+
},
1261+
// Opens the action menu.
1262+
onShowMenu(visible) {
1263+
if (visible) {
1264+
this.pauseSlideshow();
1265+
this.menuVisible = true;
1266+
} else {
1267+
this.menuVisible = false;
1268+
}
1269+
},
11861270
closeLightbox() {
11871271
if (this.isBusy("close lightbox")) {
11881272
return Promise.reject();
@@ -1854,6 +1938,10 @@ export default {
18541938
this.hideLightboxControls();
18551939
},
18561940
hideLightboxControls() {
1941+
if (this.menuVisible) {
1942+
return;
1943+
}
1944+
18571945
this.controlsShown = 0;
18581946
this.hidePswpControls();
18591947
},

frontend/src/css/controls.css

+3-2
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,13 @@ table td > .action-buttons {
218218
/* Action Menu */
219219

220220
.p-action-menu .v-overlay__content {
221-
border-radius: 8px;
221+
border-radius: 6px;
222222
}
223223

224224
.p-action-menu .action-menu__list {
225-
min-width: 108px;
225+
min-width: 122px;
226226
opacity: 0.97;
227+
padding: 3px;
227228
}
228229

229230
/* Table Actions */

0 commit comments

Comments
 (0)