mirror of https://github.com/immich-app/immich.git
feat (web/server) 360 degrees Web panoramas [attempt 2] (#3412)
* commit 1 (isPanorama: boolean)
* working solution for projectiontypeenum
* fix
* format fix
* fix
* fix
* fix
* fix
* enum projectiontype
* working solution with exif
* fix
* reverted >
* fix format
* reverted auto-magic api.ts prettification
* fix
* reverted api.ts autogenerated
* api ts regenerated
* Update web/src/lib/components/assets/thumbnail/thumbnail.svelte
Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com>
* Update web/src/lib/components/asset-viewer/asset-viewer.svelte
Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com>
* exifProjectionType
* Update server/src/microservices/processors/metadata-extraction.processor.ts
Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com>
* projectionType?: string = ProjectionType.NONE;
* not null
* projectionType!: ProjectionType;
* opeapi generator fix
* fixes
* fix
* fix
* generate api
* asset.exifInifo?.projectionType
* Update server/src/domain/asset/response-dto/exif-response.dto.ts
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
* Update server/src/microservices/processors/metadata-extraction.processor.ts
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
* enum -> varchar;projectiontypeenum->projectiontype
* asset-viewer fixed prettiffier
* @Column({}) single line
* enum | string
* make api
* enum | string
* enum | str fix
* fix
* chore: use string instead of enum
* chore: open api
* fix: checks
---------
Co-authored-by: Sergey Kondrikov <sergey.kondrikov@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
pull/3452/head
parent
13b2b2fc4e
commit
e071b82e8a
@ -0,0 +1,13 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class Panoramas1690217088596 implements MigrationInterface {
|
||||||
|
name = 'Panoramas1690217088596';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "exif" ADD "projectionType" character varying`);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE "exif" DROP COLUMN "projectionType"`);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
.view360-container {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
touch-action: pan-y;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view360-canvas {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
}
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { fade } from 'svelte/transition';
|
||||||
|
import LoadingSpinner from '../shared-components/loading-spinner.svelte';
|
||||||
|
import { api, AssetResponseDto } from '@api';
|
||||||
|
import View360, { EquirectProjection } from '@egjs/svelte-view360';
|
||||||
|
import './panorama-viewer.css';
|
||||||
|
export let asset: AssetResponseDto;
|
||||||
|
export let publicSharedKey = '';
|
||||||
|
let dataUrl = '';
|
||||||
|
let errorMessage = '';
|
||||||
|
const loadAssetData = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await api.assetApi.serveFile(
|
||||||
|
{ id: asset.id, isThumb: false, isWeb: false, key: publicSharedKey },
|
||||||
|
{ responseType: 'blob' },
|
||||||
|
);
|
||||||
|
if (data instanceof Blob) {
|
||||||
|
dataUrl = URL.createObjectURL(data);
|
||||||
|
return dataUrl;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid data format');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
errorMessage = 'Failed to load asset';
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div transition:fade={{ duration: 150 }} class="flex h-full select-none place-content-center place-items-center">
|
||||||
|
{#await loadAssetData()}
|
||||||
|
<LoadingSpinner />
|
||||||
|
{:then assetData}
|
||||||
|
{#if assetData}
|
||||||
|
<View360 autoResize={true} initialZoom={0.5} projection={new EquirectProjection({ src: assetData })} />
|
||||||
|
{:else}
|
||||||
|
<p>{errorMessage}</p>
|
||||||
|
{/if}
|
||||||
|
{/await}
|
||||||
|
</div>
|
||||||
Loading…
Reference in New Issue