Fix shared album photo viewing
parent
a463e82f83
commit
f2d61c3e07
|
@ -691,6 +691,12 @@ class ApiController extends Controller
|
|||
{
|
||||
$transforms = [];
|
||||
|
||||
// Add extra information, basename and mimetype
|
||||
if (!$aggregateOnly && ($fields = $this->request->getParam('fields'))) {
|
||||
$fields = explode(',', $fields);
|
||||
$transforms[] = [$this->timelineQuery, 'transformExtraFields', $fields];
|
||||
}
|
||||
|
||||
// Filter only favorites
|
||||
if ($this->request->getParam('fav')) {
|
||||
$transforms[] = [$this->timelineQuery, 'transformFavoriteFilter'];
|
||||
|
|
|
@ -43,6 +43,18 @@ class TimelineQuery
|
|||
return $sql;
|
||||
}
|
||||
|
||||
public function transformExtraFields(IQueryBuilder &$query, string $uid, array &$fields)
|
||||
{
|
||||
if (\in_array('basename', $fields, true)) {
|
||||
$query->addSelect('f.name AS basename');
|
||||
}
|
||||
|
||||
if (\in_array('mimetype', $fields, true)) {
|
||||
$query->join('f', 'mimetypes', 'mimetypes', $query->expr()->eq('f.mimetype', 'mimetypes.id'));
|
||||
$query->addSelect('mimetypes.mimetype');
|
||||
}
|
||||
}
|
||||
|
||||
public function getInfoById(int $id): array
|
||||
{
|
||||
$qb = $this->connection->getQueryBuilder();
|
||||
|
|
|
@ -108,17 +108,17 @@ export default class SelectionHandler extends Mixins(GlobalMixin, UserConfig) {
|
|||
|
||||
// Make default actions
|
||||
this.defaultActions = [
|
||||
{
|
||||
// This is at the top because otherwise it is confusing
|
||||
name: t("memories", "Remove from album"),
|
||||
icon: AlbumRemoveIcon,
|
||||
callback: this.removeFromAlbum.bind(this),
|
||||
if: () => this.$route.name === "albums",
|
||||
},
|
||||
{
|
||||
name: t("memories", "Delete"),
|
||||
icon: DeleteIcon,
|
||||
callback: this.deleteSelection.bind(this),
|
||||
if: () => !this.routeIsAlbum(),
|
||||
},
|
||||
{
|
||||
name: t("memories", "Remove from album"),
|
||||
icon: AlbumRemoveIcon,
|
||||
callback: this.removeFromAlbum.bind(this),
|
||||
if: () => this.routeIsAlbum(),
|
||||
},
|
||||
{
|
||||
name: t("memories", "Download"),
|
||||
|
@ -134,7 +134,8 @@ export default class SelectionHandler extends Mixins(GlobalMixin, UserConfig) {
|
|||
name: t("memories", "Archive"),
|
||||
icon: ArchiveIcon,
|
||||
callback: this.archiveSelection.bind(this),
|
||||
if: () => this.allowArchive() && !this.routeIsArchive(),
|
||||
if: () =>
|
||||
this.allowArchive() && !this.routeIsArchive() && !this.routeIsAlbum(),
|
||||
},
|
||||
{
|
||||
name: t("memories", "Unarchive"),
|
||||
|
@ -151,13 +152,14 @@ export default class SelectionHandler extends Mixins(GlobalMixin, UserConfig) {
|
|||
name: t("memories", "View in folder"),
|
||||
icon: OpenInNewIcon,
|
||||
callback: this.viewInFolder.bind(this),
|
||||
if: () => this.selection.size === 1,
|
||||
if: () => this.selection.size === 1 && !this.routeIsAlbum(),
|
||||
},
|
||||
{
|
||||
name: t("memories", "Add to album"),
|
||||
icon: AlbumsIcon,
|
||||
callback: this.addToAlbum.bind(this),
|
||||
if: (self: any) => self.config_albumsEnabled,
|
||||
if: (self: typeof this) =>
|
||||
self.config_albumsEnabled && !self.routeIsAlbum(),
|
||||
},
|
||||
{
|
||||
name: t("memories", "Move to another person"),
|
||||
|
@ -402,6 +404,11 @@ export default class SelectionHandler extends Mixins(GlobalMixin, UserConfig) {
|
|||
return this.$route.name === "archive";
|
||||
}
|
||||
|
||||
/** Is album route */
|
||||
private routeIsAlbum() {
|
||||
return this.config_albumsEnabled && this.$route.name === "albums";
|
||||
}
|
||||
|
||||
/**
|
||||
* Move selected photos to album
|
||||
*/
|
||||
|
|
|
@ -219,7 +219,8 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
/** Nextcloud viewer proxy */
|
||||
private viewerManager = new ViewerManager(
|
||||
this.deleteFromViewWithAnimation.bind(this),
|
||||
this.updateLoading.bind(this)
|
||||
this.updateLoading.bind(this),
|
||||
this.$route
|
||||
);
|
||||
|
||||
mounted() {
|
||||
|
@ -530,6 +531,7 @@ export default class Timeline extends Mixins(GlobalMixin, UserConfig) {
|
|||
"album",
|
||||
`${this.$route.params.user}/${this.$route.params.name}`
|
||||
);
|
||||
query.set("fields", "basename,mimetype");
|
||||
}
|
||||
|
||||
// Create query string and append to URL
|
||||
|
|
|
@ -2,6 +2,7 @@ import { IFileInfo, IPhoto } from "../types";
|
|||
import { showError } from "@nextcloud/dialogs";
|
||||
import { subscribe } from "@nextcloud/event-bus";
|
||||
import { translate as t, translatePlural as n } from "@nextcloud/l10n";
|
||||
import { Route } from "vue-router";
|
||||
import * as dav from "./DavRequests";
|
||||
|
||||
// Key to store sidebar state
|
||||
|
@ -13,7 +14,8 @@ export class ViewerManager {
|
|||
|
||||
constructor(
|
||||
ondelete: (photos: IPhoto[]) => void,
|
||||
private updateLoading: (delta: number) => void
|
||||
private updateLoading: (delta: number) => void,
|
||||
private $route: Route
|
||||
) {
|
||||
subscribe("files:file:deleted", ({ fileid }: { fileid: number }) => {
|
||||
const photo = this.photoMap.get(fileid);
|
||||
|
@ -23,7 +25,7 @@ export class ViewerManager {
|
|||
|
||||
public async open(photo: IPhoto, list?: IPhoto[]) {
|
||||
list = list || photo.d?.detail;
|
||||
if (!list) return;
|
||||
if (!list?.length) return;
|
||||
|
||||
// Repopulate map
|
||||
this.photoMap.clear();
|
||||
|
@ -36,7 +38,14 @@ export class ViewerManager {
|
|||
const ids = list.map((p) => p.fileid);
|
||||
try {
|
||||
this.updateLoading(1);
|
||||
fileInfos = await dav.getFiles(ids);
|
||||
|
||||
if (this.$route.name === "albums") {
|
||||
const user = this.$route.params.user;
|
||||
const name = this.$route.params.name;
|
||||
fileInfos = dav.getAlbumFileInfos(list, user, name);
|
||||
} else {
|
||||
fileInfos = await dav.getFiles(ids);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to load fileInfos", e);
|
||||
showError("Failed to load fileInfos");
|
||||
|
@ -66,7 +75,7 @@ export class ViewerManager {
|
|||
|
||||
// Open Nextcloud viewer
|
||||
globalThis.OCA.Viewer.open({
|
||||
path: fInfo.filename, // path
|
||||
fileInfo: fInfo,
|
||||
list: fileInfos, // file list
|
||||
canLoop: false, // don't loop
|
||||
onClose: () => {
|
||||
|
|
|
@ -3,7 +3,7 @@ import { getCurrentUser } from "@nextcloud/auth";
|
|||
import { generateUrl } from "@nextcloud/router";
|
||||
import { showError } from "@nextcloud/dialogs";
|
||||
import { translate as t, translatePlural as n } from "@nextcloud/l10n";
|
||||
import { IAlbum, IDay, ITag } from "../../types";
|
||||
import { IAlbum, IDay, IFileInfo, IPhoto, ITag } from "../../types";
|
||||
import { constants } from "../Utils";
|
||||
import axios from "@nextcloud/axios";
|
||||
import client from "../DavClient";
|
||||
|
@ -256,3 +256,32 @@ export async function renameAlbum(
|
|||
return album;
|
||||
}
|
||||
}
|
||||
|
||||
/** Get fileinfo objects from album photos */
|
||||
export function getAlbumFileInfos(
|
||||
photos: IPhoto[],
|
||||
albumUser: string,
|
||||
albumName: string
|
||||
): IFileInfo[] {
|
||||
const uid = getCurrentUser()?.uid;
|
||||
const collection =
|
||||
albumUser === uid
|
||||
? `/photos/${uid}/albums/${albumName}`
|
||||
: `/photos/${uid}/sharedalbums/${albumName} (${albumUser})`;
|
||||
|
||||
return photos.map((photo) => {
|
||||
const basename =
|
||||
albumUser === uid
|
||||
? `${photo.fileid}-${(<any>photo).basename}`
|
||||
: `${photo.fileid}-${albumName} (${albumUser})`;
|
||||
|
||||
return {
|
||||
fileid: photo.fileid,
|
||||
filename: `${collection}/${basename}`,
|
||||
basename: basename,
|
||||
mime: (<any>photo).mimetype,
|
||||
hasPreview: true,
|
||||
etag: photo.etag,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ export type IFileInfo = {
|
|||
/** Full file name, e.g. /pi/test/Qx0dq7dvEXA.jpg */
|
||||
filename: string;
|
||||
/** Original file name, e.g. /files/admin/pi/test/Qx0dq7dvEXA.jpg */
|
||||
originalFilename: string;
|
||||
originalFilename?: string;
|
||||
/** Base name of file e.g. Qx0dq7dvEXA.jpg */
|
||||
basename: string;
|
||||
/** Etag identifier */
|
||||
|
@ -14,7 +14,7 @@ export type IFileInfo = {
|
|||
/** File has preview available */
|
||||
hasPreview: boolean;
|
||||
/** File is marked favorite */
|
||||
favorite: boolean;
|
||||
favorite?: boolean;
|
||||
/** Vue flags */
|
||||
flag?: number;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue