Fix shared album photo viewing

old-stable24
Varun Patil 2022-10-28 14:26:56 -07:00
parent 8e0c2bc61b
commit 06b5c2c29a
7 changed files with 83 additions and 18 deletions

View File

@ -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'];

View File

@ -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();

View File

@ -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
*/

View File

@ -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

View File

@ -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: () => {

View File

@ -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,
};
});
}

View File

@ -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;
};