preview: use unified preview API

cap
Varun Patil 2022-12-02 21:04:31 -08:00
parent df0272e95d
commit db125b5298
9 changed files with 66 additions and 41 deletions

View File

@ -52,6 +52,7 @@ return [
['name' => 'Faces#faces', 'url' => '/api/faces', 'verb' => 'GET'], ['name' => 'Faces#faces', 'url' => '/api/faces', 'verb' => 'GET'],
['name' => 'Faces#preview', 'url' => '/api/faces/preview/{id}', 'verb' => 'GET'], ['name' => 'Faces#preview', 'url' => '/api/faces/preview/{id}', 'verb' => 'GET'],
['name' => 'Image#preview', 'url' => '/api/image/preview/{id}', 'verb' => 'GET'],
['name' => 'Image#info', 'url' => '/api/image/info/{id}', 'verb' => 'GET'], ['name' => 'Image#info', 'url' => '/api/image/info/{id}', 'verb' => 'GET'],
['name' => 'Image#setExif', 'url' => '/api/image/set-exif/{id}', 'verb' => 'PATCH'], ['name' => 'Image#setExif', 'url' => '/api/image/set-exif/{id}', 'verb' => 'PATCH'],
['name' => 'Image#jpeg', 'url' => '/api/image/jpeg/{id}', 'verb' => 'GET'], ['name' => 'Image#jpeg', 'url' => '/api/image/jpeg/{id}', 'verb' => 'GET'],

View File

@ -12,6 +12,6 @@ test.describe("Open", () => {
test("Open folder", async ({ page }) => { test("Open folder", async ({ page }) => {
await page.locator("text=Local").click(); await page.locator("text=Local").click();
await page.waitForSelector('img[src*="core/preview"]'); await page.waitForSelector('img[src*="api/image/preview"]');
}); });
}); });

View File

@ -13,6 +13,6 @@ export function login(route: string) {
await expect(page).toHaveURL( await expect(page).toHaveURL(
"http://localhost:8080/index.php/apps/memories" + route "http://localhost:8080/index.php/apps/memories" + route
); );
await page.waitForSelector('img[src*="core/preview"]'); await page.waitForSelector('img[src*="api/image/preview"]');
}; };
} }

View File

@ -6,7 +6,7 @@ test.beforeEach(login("/"));
test.describe("Open", () => { test.describe("Open", () => {
test("Look for Images", async ({ page }) => { test("Look for Images", async ({ page }) => {
expect( expect(
await page.locator('img[src*="core/preview"]').count(), await page.locator('img[src*="api/image/preview"]').count(),
"Number of previews" "Number of previews"
).toBeGreaterThan(4); ).toBeGreaterThan(4);
await page.waitForTimeout(1000); await page.waitForTimeout(1000);
@ -50,7 +50,7 @@ test.describe("Open", () => {
// refresh page // refresh page
await page.reload(); await page.reload();
await page.waitForTimeout(4000); // cache await page.waitForTimeout(4000); // cache
await page.waitForSelector('img[src*="core/preview"]'); await page.waitForSelector('img[src*="api/image/preview"]');
expect(await page.locator(`img[src="${src1}"]`).count()).toBe(0); expect(await page.locator(`img[src="${src1}"]`).count()).toBe(0);
expect(await page.locator(`img[src="${src2}"]`).count()).toBe(0); expect(await page.locator(`img[src="${src2}"]`).count()).toBe(0);
}); });

View File

@ -26,10 +26,55 @@ namespace OCA\Memories\Controller;
use OCA\Memories\AppInfo\Application; use OCA\Memories\AppInfo\Application;
use OCA\Memories\Exif; use OCA\Memories\Exif;
use OCP\AppFramework\Http; use OCP\AppFramework\Http;
use OCP\AppFramework\Http\FileDisplayResponse;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
class ImageController extends ApiBase class ImageController extends ApiBase
{ {
/**
* @NoAdminRequired
*
* @NoCSRFRequired
*
* @PublicPage
*
* Get preview of image
*/
public function preview(
int $id,
int $x = 32,
int $y = 32,
bool $a = false,
string $mode = 'fill'
) {
if (-1 === $id || 0 === $x || 0 === $y) {
return new JSONResponse([
'message' => 'Invalid parameters',
], Http::STATUS_BAD_REQUEST);
}
$file = $this->getUserFile($id);
if (!$file) {
return new JSONResponse([
'message' => 'File not found',
], Http::STATUS_NOT_FOUND);
}
try {
$f = $this->previewManager->getPreview($file, $x, $y, !$a, $mode);
$response = new FileDisplayResponse($f, Http::STATUS_OK, [
'Content-Type' => $f->getMimeType(),
]);
$response->cacheFor(3600 * 24, false, true);
return $response;
} catch (\OCP\Files\NotFoundException $e) {
return new JSONResponse([], Http::STATUS_NOT_FOUND);
} catch (\InvalidArgumentException $e) {
return new JSONResponse([], Http::STATUS_BAD_REQUEST);
}
}
/** /**
* @NoAdminRequired * @NoAdminRequired
* *

View File

@ -38,7 +38,7 @@
import { Component, Prop, Watch, Mixins, Emit } from "vue-property-decorator"; import { Component, Prop, Watch, Mixins, Emit } from "vue-property-decorator";
import { IAlbum, IPhoto, ITag } from "../../types"; import { IAlbum, IPhoto, ITag } from "../../types";
import { generateUrl } from "@nextcloud/router"; import { generateUrl } from "@nextcloud/router";
import { getPhotosPreviewUrl, getPreviewUrl } from "../../services/FileUtils"; import { getPreviewUrl } from "../../services/FileUtils";
import { getCurrentUser } from "@nextcloud/auth"; import { getCurrentUser } from "@nextcloud/auth";
import NcCounterBubble from "@nextcloud/vue/dist/Components/NcCounterBubble"; import NcCounterBubble from "@nextcloud/vue/dist/Components/NcCounterBubble";
@ -89,10 +89,6 @@ export default class Tag extends Mixins(GlobalMixin) {
); );
} }
if (this.isAlbum) {
return getPhotosPreviewUrl(photo, true, 256);
}
return getPreviewUrl(photo, true, 256); return getPreviewUrl(photo, true, 256);
} }

View File

@ -70,7 +70,7 @@ import NcLoadingIcon from "@nextcloud/vue/dist/Components/NcLoadingIcon";
const NcListItem = () => import("@nextcloud/vue/dist/Components/NcListItem"); const NcListItem = () => import("@nextcloud/vue/dist/Components/NcListItem");
import { generateUrl } from "@nextcloud/router"; import { generateUrl } from "@nextcloud/router";
import { getPhotosPreviewUrl } from "../../services/FileUtils"; import { getPreviewUrl } from "../../services/FileUtils";
import { IAlbum, IPhoto } from "../../types"; import { IAlbum, IPhoto } from "../../types";
import axios from "@nextcloud/axios"; import axios from "@nextcloud/axios";
@ -85,7 +85,7 @@ import axios from "@nextcloud/axios";
}, },
filters: { filters: {
toCoverUrl(fileId: string) { toCoverUrl(fileId: string) {
return getPhotosPreviewUrl( return getPreviewUrl(
{ {
fileid: Number(fileId), fileid: Number(fileId),
} as IPhoto, } as IPhoto,

View File

@ -143,35 +143,23 @@ const getPreviewUrl = function (
const [x, y] = typeof size === "number" ? [size, size] : size; const [x, y] = typeof size === "number" ? [size, size] : size;
const a = square ? "0" : "1"; const a = square ? "0" : "1";
// Public preview // Get base URL
if (vuerouter.currentRoute.name === "folder-share") { let url = generateUrl(
const token = vuerouter.currentRoute.params.token; `/apps/memories/api/image/preview/${photo.fileid}?c=${photo.etag}&x=${x}&y=${y}&a=${a}`
return generateUrl(
`/apps/files_sharing/publicpreview/${token}?file=${photo.filename}&fileId=${photo.fileid}&x=${x}&y=${y}&a=${a}`
); );
}
// Albums from Photos // Albums from Photos
if (vuerouter.currentRoute.name === "albums") { if (vuerouter.currentRoute.name === "albums") {
return getPhotosPreviewUrl(photo, square, size); url += `&album=1`;
} }
return generateUrl( // Public preview
`/core/preview?fileId=${photo.fileid}&c=${photo.etag}&x=${x}&y=${y}&forceIcon=0&a=${a}` if (vuerouter.currentRoute.name === "folder-share") {
); const token = vuerouter.currentRoute.params.token;
}; url += `&folder_share=${token}`;
}
/** Get the preview URL from the photos app */ return url;
const getPhotosPreviewUrl = function (
photo: IPhoto | IFileInfo,
square: boolean,
size: number | [number, number]
): string {
const [x, y] = typeof size === "number" ? [size, size] : size;
const a = square ? "0" : "1";
return generateUrl(
`/apps/photos/api/v1/preview/${photo.fileid}?c=${photo.etag}&x=${x}&y=${y}&forceIcon=0&a=${a}`
);
}; };
export { export {
@ -180,5 +168,4 @@ export {
sortCompare, sortCompare,
genFileInfo, genFileInfo,
getPreviewUrl, getPreviewUrl,
getPhotosPreviewUrl,
}; };

View File

@ -64,12 +64,8 @@ if (!isDev) {
urlPattern: /^.*\/apps\/files\/ajax\/download.php?.*/, urlPattern: /^.*\/apps\/files\/ajax\/download.php?.*/,
handler: 'NetworkOnly', handler: 'NetworkOnly',
}, { }, {
// Preview file request from core // Preview file request
urlPattern: /^.*\/core\/preview\?fileId=.*/, urlPattern: /^.*\/apps\/memories\/api\/image\/preview\/.*/,
...imageCacheOpts(7),
}, {
// Albums from Photos
urlPattern: /^.*\/apps\/photos\/api\/v1\/preview\/.*/,
...imageCacheOpts(7), ...imageCacheOpts(7),
}, { }, {
// Live photo videos // Live photo videos