mirror of
https://github.com/immich-app/immich.git
synced 2026-05-20 14:52:34 -04:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 65b865ad08 | |||
| 21ea5d8d85 | |||
| 17b6e0250a | |||
| a033d751b3 | |||
| ea293dfe06 | |||
| aea7651c75 | |||
| 74ff8f1e56 | |||
| c544526400 | |||
| 2f8cb30c34 | |||
| 4140a66cab | |||
| bf20c363fd | |||
| e270ae0017 | |||
| e2a25742f4 | |||
| 61e32f4bf7 | |||
| 02075bc52e | |||
| 230c7dae0f | |||
| 0e672a5b24 | |||
| c1452a359c | |||
| 758b5cd6c2 | |||
| 28413fedcc |
@@ -285,7 +285,7 @@ jobs:
|
||||
- name: Run API generation
|
||||
run: make open-api
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@v18
|
||||
uses: tj-actions/verify-changed-files@v13.1
|
||||
id: verify-changed-files
|
||||
with:
|
||||
files: |
|
||||
@@ -340,7 +340,7 @@ jobs:
|
||||
run: npm run typeorm:migrations:generate ./src/infra/migrations/TestMigration
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@v18
|
||||
uses: tj-actions/verify-changed-files@v13.1
|
||||
id: verify-changed-files
|
||||
with:
|
||||
files: |
|
||||
@@ -358,7 +358,7 @@ jobs:
|
||||
DB_URL: postgres://postgres:postgres@localhost:5432/immich
|
||||
|
||||
- name: Find file changes
|
||||
uses: tj-actions/verify-changed-files@v18
|
||||
uses: tj-actions/verify-changed-files@v13.1
|
||||
id: verify-changed-sql-files
|
||||
with:
|
||||
files: |
|
||||
|
||||
+1
-3
@@ -2,7 +2,5 @@
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 120,
|
||||
"semi": true,
|
||||
"plugins": ["prettier-plugin-organize-imports"],
|
||||
"organizeImportsSkipDestructiveCodeActions": true
|
||||
"semi": true
|
||||
}
|
||||
|
||||
Generated
+15
-42
@@ -31,8 +31,6 @@
|
||||
"glob": "^10.3.1",
|
||||
"immich": "file:../server",
|
||||
"mock-fs": "^5.2.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.12",
|
||||
"vitest": "^1.2.2",
|
||||
@@ -1307,9 +1305,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.11.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz",
|
||||
"integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==",
|
||||
"version": "20.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
|
||||
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
@@ -4070,10 +4068,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
@@ -4096,26 +4095,6 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-organize-imports": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz",
|
||||
"integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@volar/vue-language-plugin-pug": "^1.0.4",
|
||||
"@volar/vue-typescript": "^1.0.4",
|
||||
"prettier": ">=2.0",
|
||||
"typescript": ">=2.9"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@volar/vue-language-plugin-pug": {
|
||||
"optional": true
|
||||
},
|
||||
"@volar/vue-typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
@@ -6447,9 +6426,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.11.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz",
|
||||
"integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==",
|
||||
"version": "20.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
|
||||
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
@@ -8564,10 +8543,11 @@
|
||||
"dev": true
|
||||
},
|
||||
"prettier": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz",
|
||||
"integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==",
|
||||
"dev": true
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
|
||||
"integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"prettier-linter-helpers": {
|
||||
"version": "1.0.0",
|
||||
@@ -8578,13 +8558,6 @@
|
||||
"fast-diff": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"prettier-plugin-organize-imports": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz",
|
||||
"integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"pretty-format": {
|
||||
"version": "29.7.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
|
||||
|
||||
@@ -32,8 +32,6 @@
|
||||
"glob": "^10.3.1",
|
||||
"immich": "file:../server",
|
||||
"mock-fs": "^5.2.0",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"typescript": "^5.3.3",
|
||||
"vite": "^5.0.12",
|
||||
"vitest": "^1.2.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ServerVersionResponseDto, UserResponseDto } from '@immich/sdk';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
import { SessionService } from '../services/session.service';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
|
||||
export abstract class BaseCommand {
|
||||
protected sessionService!: SessionService;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import byteSize from 'byte-size';
|
||||
import cliProgress from 'cli-progress';
|
||||
import { createHash } from 'node:crypto';
|
||||
import fs, { createReadStream } from 'node:fs';
|
||||
import { access, constants, stat, unlink } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import { basename } from 'node:path';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
import { CrawlService } from '../services/crawl.service';
|
||||
import { BaseCommand } from './base-command';
|
||||
import { basename } from 'node:path';
|
||||
import { access, constants, stat, unlink } from 'node:fs/promises';
|
||||
import { createHash } from 'node:crypto';
|
||||
import os from 'node:os';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
|
||||
class Asset {
|
||||
readonly path: string;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#! /usr/bin/env node
|
||||
import { Command, Option } from 'commander';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import { version } from '../package.json';
|
||||
import { LoginCommand } from './commands/login.command';
|
||||
import { LogoutCommand } from './commands/logout.command';
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
ApiKeyCreateDto,
|
||||
AssetBulkUploadCheckDto,
|
||||
BulkIdsDto,
|
||||
CreateAlbumDto,
|
||||
CreateAssetDto,
|
||||
LoginCredentialDto,
|
||||
SignUpDto,
|
||||
addAssetsToAlbum,
|
||||
checkBulkUpload,
|
||||
createAlbum,
|
||||
@@ -20,6 +13,13 @@ import {
|
||||
pingServer,
|
||||
signUpAdmin,
|
||||
uploadFile,
|
||||
ApiKeyCreateDto,
|
||||
AssetBulkUploadCheckDto,
|
||||
BulkIdsDto,
|
||||
CreateAlbumDto,
|
||||
CreateAssetDto,
|
||||
LoginCredentialDto,
|
||||
SignUpDto,
|
||||
} from '@immich/sdk';
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import mockfs from 'mock-fs';
|
||||
import { CrawlOptions, CrawlService } from './crawl.service';
|
||||
import { CrawlService, CrawlOptions } from './crawl.service';
|
||||
|
||||
interface Test {
|
||||
test: string;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SessionService } from './session.service';
|
||||
import fs from 'node:fs';
|
||||
import yaml from 'yaml';
|
||||
import {
|
||||
@@ -10,7 +11,6 @@ import {
|
||||
readTestAuthFile,
|
||||
spyOnConsole,
|
||||
} from '../../test/cli-test-utils';
|
||||
import { SessionService } from './session.service';
|
||||
|
||||
const mocks = vi.hoisted(() => {
|
||||
return {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { restoreTempFolder, testApp } from '@test-utils';
|
||||
import { readFile, stat } from 'node:fs/promises';
|
||||
import { CLI_BASE_OPTIONS, TEST_AUTH_FILE, deleteAuthFile, setup, spyOnConsole } from 'test/cli-test-utils';
|
||||
import yaml from 'yaml';
|
||||
import { readFile, stat } from 'node:fs/promises';
|
||||
import { LoginCommand } from '../../src/commands/login.command';
|
||||
import yaml from 'yaml';
|
||||
|
||||
describe(`login-key (e2e)`, () => {
|
||||
let apiKey: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'node:path';
|
||||
import { PostgreSqlContainer } from '@testcontainers/postgresql';
|
||||
import { access } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
|
||||
export const directoryExists = (directory: string) =>
|
||||
access(directory)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IMMICH_TEST_ASSET_PATH, restoreTempFolder, testApp } from '@test-utils';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
import { CLI_BASE_OPTIONS, setup, spyOnConsole } from 'test/cli-test-utils';
|
||||
import { UploadCommand } from '../../src/commands/upload.command';
|
||||
import { ImmichApi } from 'src/services/api.service';
|
||||
|
||||
describe(`upload (e2e)`, () => {
|
||||
let api: ImmichApi;
|
||||
|
||||
@@ -57,7 +57,7 @@ services:
|
||||
image: immich-web-dev:latest
|
||||
build:
|
||||
context: ../web
|
||||
command: [ "/usr/src/app/bin/immich-web" ]
|
||||
command: "/usr/src/app/bin/immich-web"
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from '@playwright/test';
|
||||
import { app } from '../test-utils';
|
||||
|
||||
test.describe('Registration', () => {
|
||||
test.beforeEach(async () => {
|
||||
test.beforeAll(async () => {
|
||||
await app.reset();
|
||||
});
|
||||
|
||||
|
||||
+7
-16
@@ -63,26 +63,17 @@ export const app = {
|
||||
return response;
|
||||
},
|
||||
reset: async () => {
|
||||
try {
|
||||
if (!connected) {
|
||||
await client.connect();
|
||||
connected = true;
|
||||
}
|
||||
if (!connected) {
|
||||
await client.connect();
|
||||
}
|
||||
|
||||
for (const table of ['user_token', 'users', 'system_metadata']) {
|
||||
await client.query(`DELETE FROM ${table} CASCADE;`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to reset database', error);
|
||||
for (const table of ['users', 'system_metadata']) {
|
||||
await client.query(`DELETE FROM ${table} CASCADE;`);
|
||||
}
|
||||
},
|
||||
teardown: async () => {
|
||||
try {
|
||||
if (connected) {
|
||||
await client.end();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to teardown database', error);
|
||||
if (connected) {
|
||||
await client.end();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ start_docker_compose() {
|
||||
}
|
||||
|
||||
show_friendly_message() {
|
||||
echo "Successfully deployed Immich!"
|
||||
echo "Succesfully deployed Immich!"
|
||||
echo "You can access the website at http://$ip_address:2283 and the server URL for the mobile app is http://$ip_address:2283/api"
|
||||
echo "The library location is $upload_location"
|
||||
echo "---------------------------------------------------"
|
||||
|
||||
@@ -33,10 +33,10 @@ linter:
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
analyzer:
|
||||
exclude:
|
||||
- openapi/**
|
||||
- openapi/test/**
|
||||
- openapi/
|
||||
- openapi/test/
|
||||
- lib/generated_plugin_registrant.dart
|
||||
|
||||
|
||||
plugins:
|
||||
- custom_lint
|
||||
|
||||
|
||||
@@ -12,85 +12,92 @@ class AdvancedBottomSheet extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// One column
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const Align(
|
||||
child: Text(
|
||||
"ADVANCED INFO",
|
||||
style: TextStyle(fontSize: 12.0),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32.0),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.isDarkTheme
|
||||
? Colors.grey[900]
|
||||
: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 16.0,
|
||||
left: 16,
|
||||
top: 8,
|
||||
bottom: 16,
|
||||
child: Card(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
topRight: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
margin: const EdgeInsets.all(0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// One column
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const SizedBox(height: 32.0),
|
||||
const Align(
|
||||
child: Text(
|
||||
"ADVANCED INFO",
|
||||
style: TextStyle(fontSize: 12.0),
|
||||
),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(
|
||||
text: assetDetail.toString(),
|
||||
),
|
||||
).then((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"Copied to clipboard",
|
||||
style:
|
||||
context.textTheme.bodyLarge?.copyWith(
|
||||
color: context.primaryColor,
|
||||
),
|
||||
const SizedBox(height: 32.0),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: context.isDarkTheme
|
||||
? Colors.grey[900]
|
||||
: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 16.0,
|
||||
left: 16,
|
||||
top: 8,
|
||||
bottom: 16,
|
||||
),
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: assetDetail.toString()),
|
||||
).then((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"Copied to clipboard",
|
||||
style: context.textTheme.bodyLarge
|
||||
?.copyWith(
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.copy,
|
||||
size: 16.0,
|
||||
color: context.primaryColor,
|
||||
);
|
||||
});
|
||||
},
|
||||
icon: Icon(
|
||||
Icons.copy,
|
||||
size: 16.0,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SelectableText(
|
||||
assetDetail.toString(),
|
||||
style: const TextStyle(
|
||||
fontSize: 12.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: "Inconsolata",
|
||||
SelectableText(
|
||||
assetDetail.toString(),
|
||||
style: const TextStyle(
|
||||
fontSize: 12.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: "Inconsolata",
|
||||
),
|
||||
showCursor: true,
|
||||
),
|
||||
showCursor: true,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32.0),
|
||||
],
|
||||
);
|
||||
},
|
||||
const SizedBox(height: 32.0),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:immich_mobile/modules/asset_viewer/ui/description_input.dart';
|
||||
import 'package:immich_mobile/modules/map/widgets/map_thumbnail.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/providers/asset.provider.dart';
|
||||
import 'package:immich_mobile/shared/ui/drag_sheet.dart';
|
||||
import 'package:immich_mobile/utils/selection_handlers.dart';
|
||||
import 'package:immich_mobile/utils/bytes_units.dart';
|
||||
import 'package:maplibre_gl/maplibre_gl.dart';
|
||||
@@ -125,6 +126,20 @@ class ExifBottomSheet extends HookConsumerWidget {
|
||||
return text.isNotEmpty ? text : null;
|
||||
}
|
||||
|
||||
buildDragHeader() {
|
||||
return const Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: CustomDraggingHandle(),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
buildLocation() {
|
||||
// Guard no lat/lng
|
||||
if (!hasCoordinates()) {
|
||||
@@ -326,69 +341,86 @@ class ExifBottomSheet extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
if (constraints.maxWidth > 600) {
|
||||
// Two column
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
buildDate(),
|
||||
if (asset.isRemote) DescriptionInput(asset: asset),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: buildLocation(),
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
// FocusScope.of(context).unfocus();
|
||||
},
|
||||
child: SingleChildScrollView(
|
||||
child: Card(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(15),
|
||||
topRight: Radius.circular(15),
|
||||
),
|
||||
),
|
||||
margin: const EdgeInsets.all(0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
if (constraints.maxWidth > 600) {
|
||||
// Two column
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
buildDragHeader(),
|
||||
buildDate(),
|
||||
if (asset.isRemote) DescriptionInput(asset: asset),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Flexible(
|
||||
flex: hasCoordinates() ? 5 : 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: buildLocation(),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 5,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: buildDetail(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 300),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0),
|
||||
child: buildDetail(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 50),
|
||||
],
|
||||
);
|
||||
}
|
||||
const SizedBox(height: 50),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// One column
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
buildDate(),
|
||||
assetWithExif.when(
|
||||
data: (data) => DescriptionInput(asset: data),
|
||||
error: (error, stackTrace) => Icon(
|
||||
Icons.image_not_supported_outlined,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
loading: () => const SizedBox(
|
||||
width: 75,
|
||||
height: 75,
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
),
|
||||
),
|
||||
buildLocation(),
|
||||
SizedBox(height: hasCoordinates() ? 16.0 : 6.0),
|
||||
buildDetail(),
|
||||
const SizedBox(height: 50),
|
||||
],
|
||||
);
|
||||
},
|
||||
// One column
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
buildDragHeader(),
|
||||
buildDate(),
|
||||
assetWithExif.when(
|
||||
data: (data) => DescriptionInput(asset: data),
|
||||
error: (error, stackTrace) => Icon(
|
||||
Icons.image_not_supported_outlined,
|
||||
color: context.primaryColor,
|
||||
),
|
||||
loading: () => const SizedBox(
|
||||
width: 75,
|
||||
height: 75,
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
),
|
||||
),
|
||||
buildLocation(),
|
||||
SizedBox(height: hasCoordinates() ? 16.0 : 6.0),
|
||||
buildDetail(),
|
||||
const SizedBox(height: 50),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -136,7 +136,6 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
// swallow error silently
|
||||
debugPrint('Error precaching next image: $exception, $stackTrace');
|
||||
}
|
||||
|
||||
if (index < totalAssets && index >= 0) {
|
||||
final asset = loadAsset(index);
|
||||
precacheImage(
|
||||
@@ -153,11 +152,10 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
),
|
||||
barrierColor: Colors.transparent,
|
||||
backgroundColor: Colors.transparent,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
enableDrag: true,
|
||||
context: context,
|
||||
useSafeArea: true,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
|
||||
@@ -88,7 +88,7 @@ class UploadProfileImageNotifier
|
||||
var res = await _userSErvice.uploadProfileImage(file);
|
||||
|
||||
if (res != null) {
|
||||
debugPrint("Successfully upload profile image");
|
||||
debugPrint("Succesfully upload profile image");
|
||||
state = state.copyWith(
|
||||
status: UploadProfileStatus.success,
|
||||
profileImagePath: res.profileImagePath,
|
||||
|
||||
@@ -10,7 +10,6 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/extensions/collection_extensions.dart';
|
||||
import 'package:immich_mobile/modules/asset_viewer/providers/scroll_notifier.provider.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_image.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
|
||||
@@ -128,6 +127,184 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
|
||||
assets.firstWhereOrNull((e) => !_selectedAssets.contains(e)) == null;
|
||||
}
|
||||
|
||||
Widget _buildThumbnailOrPlaceholder(Asset asset, int index) {
|
||||
return ThumbnailImage(
|
||||
asset: asset,
|
||||
index: index,
|
||||
loadAsset: widget.renderList.loadAsset,
|
||||
totalAssets: widget.renderList.totalAssets,
|
||||
multiselectEnabled: widget.selectionActive,
|
||||
isSelected: widget.selectionActive && _selectedAssets.contains(asset),
|
||||
onSelect: () => _selectAssets([asset]),
|
||||
onDeselect: widget.canDeselect ||
|
||||
widget.preselectedAssets == null ||
|
||||
!widget.preselectedAssets!.contains(asset)
|
||||
? () => _deselectAssets([asset])
|
||||
: null,
|
||||
useGrayBoxPlaceholder: true,
|
||||
showStorageIndicator: widget.showStorageIndicator,
|
||||
heroOffset: widget.heroOffset,
|
||||
showStack: widget.showStack,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAssetRow(
|
||||
Key key,
|
||||
BuildContext context,
|
||||
List<Asset> assets,
|
||||
int absoluteOffset,
|
||||
double width,
|
||||
) {
|
||||
// Default: All assets have the same width
|
||||
final widthDistribution = List.filled(assets.length, 1.0);
|
||||
|
||||
if (widget.dynamicLayout) {
|
||||
final aspectRatios =
|
||||
assets.map((e) => (e.width ?? 1) / (e.height ?? 1)).toList();
|
||||
final meanAspectRatio = aspectRatios.sum / assets.length;
|
||||
|
||||
// 1: mean width
|
||||
// 0.5: width < mean - threshold
|
||||
// 1.5: width > mean + threshold
|
||||
final arConfiguration = aspectRatios.map((e) {
|
||||
if (e - meanAspectRatio > 0.3) return 1.5;
|
||||
if (e - meanAspectRatio < -0.3) return 0.5;
|
||||
return 1.0;
|
||||
});
|
||||
|
||||
// Normalize:
|
||||
final sum = arConfiguration.sum;
|
||||
widthDistribution.setRange(
|
||||
0,
|
||||
widthDistribution.length,
|
||||
arConfiguration.map((e) => (e * assets.length) / sum),
|
||||
);
|
||||
}
|
||||
return Row(
|
||||
key: key,
|
||||
children: assets.mapIndexed((int index, Asset asset) {
|
||||
final bool last = index + 1 == widget.assetsPerRow;
|
||||
return Container(
|
||||
key: ValueKey(index),
|
||||
width: width * widthDistribution[index],
|
||||
height: width,
|
||||
margin: EdgeInsets.only(
|
||||
bottom: widget.margin,
|
||||
right: last ? 0.0 : widget.margin,
|
||||
),
|
||||
child: _buildThumbnailOrPlaceholder(asset, absoluteOffset + index),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildTitle(
|
||||
BuildContext context,
|
||||
String title,
|
||||
List<Asset> assets,
|
||||
) {
|
||||
return GroupDividerTitle(
|
||||
text: title,
|
||||
multiselectEnabled: widget.selectionActive,
|
||||
onSelect: () => _selectAssets(assets),
|
||||
onDeselect: () => _deselectAssets(assets),
|
||||
selected: _allAssetsSelected(assets),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMonthTitle(BuildContext context, DateTime date) {
|
||||
final monthFormat = DateTime.now().year == date.year
|
||||
? DateFormat.MMMM()
|
||||
: DateFormat.yMMMM();
|
||||
final String title = monthFormat.format(date);
|
||||
return Padding(
|
||||
key: Key("month-$title"),
|
||||
padding: const EdgeInsets.only(left: 12.0, top: 24.0),
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPlaceHolderRow(Key key, int num, double width, double height) {
|
||||
return Row(
|
||||
key: key,
|
||||
children: [
|
||||
for (int i = 0; i < num; i++)
|
||||
Container(
|
||||
key: ValueKey(i),
|
||||
width: width,
|
||||
height: height,
|
||||
margin: EdgeInsets.only(
|
||||
bottom: widget.margin,
|
||||
right: i + 1 == num ? 0.0 : widget.margin,
|
||||
),
|
||||
color: Colors.grey,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSection(
|
||||
BuildContext context,
|
||||
RenderAssetGridElement section,
|
||||
bool scrolling,
|
||||
) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final width = constraints.maxWidth / widget.assetsPerRow -
|
||||
widget.margin * (widget.assetsPerRow - 1) / widget.assetsPerRow;
|
||||
final rows =
|
||||
(section.count + widget.assetsPerRow - 1) ~/ widget.assetsPerRow;
|
||||
final List<Asset> assetsToRender = scrolling
|
||||
? []
|
||||
: widget.renderList.loadAssets(section.offset, section.count);
|
||||
return Column(
|
||||
key: ValueKey(section.offset),
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (section.type == RenderAssetGridElementType.monthTitle)
|
||||
_buildMonthTitle(context, section.date),
|
||||
if (section.type == RenderAssetGridElementType.groupDividerTitle ||
|
||||
section.type == RenderAssetGridElementType.monthTitle)
|
||||
_buildTitle(
|
||||
context,
|
||||
section.title!,
|
||||
scrolling
|
||||
? []
|
||||
: widget.renderList
|
||||
.loadAssets(section.offset, section.totalCount),
|
||||
),
|
||||
for (int i = 0; i < rows; i++)
|
||||
scrolling
|
||||
? _buildPlaceHolderRow(
|
||||
ValueKey(i),
|
||||
i + 1 == rows
|
||||
? section.count - i * widget.assetsPerRow
|
||||
: widget.assetsPerRow,
|
||||
width,
|
||||
width,
|
||||
)
|
||||
: _buildAssetRow(
|
||||
ValueKey(i),
|
||||
context,
|
||||
assetsToRender.nestedSlice(
|
||||
i * widget.assetsPerRow,
|
||||
min((i + 1) * widget.assetsPerRow, section.count),
|
||||
),
|
||||
section.offset + i * widget.assetsPerRow,
|
||||
width,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _itemBuilder(BuildContext c, int position) {
|
||||
int index = position;
|
||||
if (widget.topWidget != null) {
|
||||
@@ -137,23 +314,8 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
|
||||
index--;
|
||||
}
|
||||
|
||||
final section = widget.renderList.elements[index];
|
||||
return _Section(
|
||||
showStorageIndicator: widget.showStorageIndicator,
|
||||
selectedAssets: _selectedAssets,
|
||||
selectionActive: widget.selectionActive,
|
||||
section: section,
|
||||
margin: widget.margin,
|
||||
renderList: widget.renderList,
|
||||
assetsPerRow: widget.assetsPerRow,
|
||||
scrolling: _scrolling,
|
||||
dynamicLayout: widget.dynamicLayout,
|
||||
selectAssets: _selectAssets,
|
||||
deselectAssets: _deselectAssets,
|
||||
allAssetsSelected: _allAssetsSelected,
|
||||
showStack: widget.showStack,
|
||||
heroOffset: widget.heroOffset,
|
||||
);
|
||||
final item = widget.renderList.elements[index];
|
||||
return _buildSection(c, item, _scrolling);
|
||||
}
|
||||
|
||||
Text _labelBuilder(int pos) {
|
||||
@@ -323,292 +485,3 @@ class ImmichAssetGridViewState extends State<ImmichAssetGridView> {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A single row of all placeholder widgets
|
||||
class _PlaceholderRow extends StatelessWidget {
|
||||
final int number;
|
||||
final double width;
|
||||
final double height;
|
||||
final double margin;
|
||||
|
||||
const _PlaceholderRow({
|
||||
super.key,
|
||||
required this.number,
|
||||
required this.width,
|
||||
required this.height,
|
||||
required this.margin,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
for (int i = 0; i < number; i++)
|
||||
ThumbnailPlaceholder(
|
||||
key: ValueKey(i),
|
||||
width: width,
|
||||
height: height,
|
||||
margin: EdgeInsets.only(
|
||||
bottom: margin,
|
||||
right: i + 1 == number ? 0.0 : margin,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A section for the render grid
|
||||
class _Section extends StatelessWidget {
|
||||
final RenderAssetGridElement section;
|
||||
final Set<Asset> selectedAssets;
|
||||
final bool scrolling;
|
||||
final double margin;
|
||||
final int assetsPerRow;
|
||||
final RenderList renderList;
|
||||
final bool selectionActive;
|
||||
final bool dynamicLayout;
|
||||
final Function(List<Asset>) selectAssets;
|
||||
final Function(List<Asset>) deselectAssets;
|
||||
final bool Function(List<Asset>) allAssetsSelected;
|
||||
final bool showStack;
|
||||
final int heroOffset;
|
||||
final bool showStorageIndicator;
|
||||
|
||||
const _Section({
|
||||
required this.section,
|
||||
required this.scrolling,
|
||||
required this.margin,
|
||||
required this.assetsPerRow,
|
||||
required this.renderList,
|
||||
required this.selectionActive,
|
||||
required this.dynamicLayout,
|
||||
required this.selectAssets,
|
||||
required this.deselectAssets,
|
||||
required this.allAssetsSelected,
|
||||
required this.selectedAssets,
|
||||
required this.showStack,
|
||||
required this.heroOffset,
|
||||
required this.showStorageIndicator,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(
|
||||
BuildContext context,
|
||||
) {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final width = constraints.maxWidth / assetsPerRow -
|
||||
margin * (assetsPerRow - 1) / assetsPerRow;
|
||||
final rows = (section.count + assetsPerRow - 1) ~/ assetsPerRow;
|
||||
final List<Asset> assetsToRender = scrolling
|
||||
? []
|
||||
: renderList.loadAssets(section.offset, section.count);
|
||||
return Column(
|
||||
key: ValueKey(section.offset),
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (section.type == RenderAssetGridElementType.monthTitle)
|
||||
_MonthTitle(date: section.date),
|
||||
if (section.type == RenderAssetGridElementType.groupDividerTitle ||
|
||||
section.type == RenderAssetGridElementType.monthTitle)
|
||||
_Title(
|
||||
selectionActive: selectionActive,
|
||||
title: section.title!,
|
||||
assets: scrolling
|
||||
? []
|
||||
: renderList.loadAssets(section.offset, section.totalCount),
|
||||
allAssetsSelected: allAssetsSelected,
|
||||
selectAssets: selectAssets,
|
||||
deselectAssets: deselectAssets,
|
||||
),
|
||||
for (int i = 0; i < rows; i++)
|
||||
scrolling
|
||||
? _PlaceholderRow(
|
||||
key: ValueKey(i),
|
||||
number: i + 1 == rows
|
||||
? section.count - i * assetsPerRow
|
||||
: assetsPerRow,
|
||||
width: width,
|
||||
height: width,
|
||||
margin: margin,
|
||||
)
|
||||
: _AssetRow(
|
||||
key: ValueKey(i),
|
||||
assets: assetsToRender.nestedSlice(
|
||||
i * assetsPerRow,
|
||||
min((i + 1) * assetsPerRow, section.count),
|
||||
),
|
||||
absoluteOffset: section.offset + i * assetsPerRow,
|
||||
width: width,
|
||||
assetsPerRow: assetsPerRow,
|
||||
margin: margin,
|
||||
dynamicLayout: dynamicLayout,
|
||||
renderList: renderList,
|
||||
selectedAssets: selectedAssets,
|
||||
isSelectionActive: selectionActive,
|
||||
showStack: showStack,
|
||||
heroOffset: heroOffset,
|
||||
showStorageIndicator: showStorageIndicator,
|
||||
selectionActive: selectionActive,
|
||||
onSelect: (asset) => selectAssets([asset]),
|
||||
onDeselect: (asset) => deselectAssets([asset]),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The month title row for a section
|
||||
class _MonthTitle extends StatelessWidget {
|
||||
final DateTime date;
|
||||
|
||||
const _MonthTitle({
|
||||
required this.date,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final monthFormat = DateTime.now().year == date.year
|
||||
? DateFormat.MMMM()
|
||||
: DateFormat.yMMMM();
|
||||
final String title = monthFormat.format(date);
|
||||
return Padding(
|
||||
key: Key("month-$title"),
|
||||
padding: const EdgeInsets.only(left: 12.0, top: 24.0),
|
||||
child: Text(
|
||||
title,
|
||||
style: const TextStyle(
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A title row
|
||||
class _Title extends StatelessWidget {
|
||||
final String title;
|
||||
final List<Asset> assets;
|
||||
final bool selectionActive;
|
||||
final Function(List<Asset>) selectAssets;
|
||||
final Function(List<Asset>) deselectAssets;
|
||||
final Function(List<Asset>) allAssetsSelected;
|
||||
|
||||
const _Title({
|
||||
required this.title,
|
||||
required this.assets,
|
||||
required this.selectionActive,
|
||||
required this.selectAssets,
|
||||
required this.deselectAssets,
|
||||
required this.allAssetsSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GroupDividerTitle(
|
||||
text: title,
|
||||
multiselectEnabled: selectionActive,
|
||||
onSelect: () => selectAssets(assets),
|
||||
onDeselect: () => deselectAssets(assets),
|
||||
selected: allAssetsSelected(assets),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The row of assets
|
||||
class _AssetRow extends StatelessWidget {
|
||||
final List<Asset> assets;
|
||||
final Set<Asset> selectedAssets;
|
||||
final int absoluteOffset;
|
||||
final double width;
|
||||
final bool dynamicLayout;
|
||||
final double margin;
|
||||
final int assetsPerRow;
|
||||
final RenderList renderList;
|
||||
final bool selectionActive;
|
||||
final bool showStorageIndicator;
|
||||
final int heroOffset;
|
||||
final bool showStack;
|
||||
final Function(Asset)? onSelect;
|
||||
final Function(Asset)? onDeselect;
|
||||
final bool isSelectionActive;
|
||||
|
||||
const _AssetRow({
|
||||
super.key,
|
||||
required this.assets,
|
||||
required this.absoluteOffset,
|
||||
required this.width,
|
||||
required this.dynamicLayout,
|
||||
required this.margin,
|
||||
required this.assetsPerRow,
|
||||
required this.renderList,
|
||||
required this.selectionActive,
|
||||
required this.showStorageIndicator,
|
||||
required this.heroOffset,
|
||||
required this.showStack,
|
||||
required this.isSelectionActive,
|
||||
required this.selectedAssets,
|
||||
this.onSelect,
|
||||
this.onDeselect,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Default: All assets have the same width
|
||||
final widthDistribution = List.filled(assets.length, 1.0);
|
||||
|
||||
if (dynamicLayout) {
|
||||
final aspectRatios =
|
||||
assets.map((e) => (e.width ?? 1) / (e.height ?? 1)).toList();
|
||||
final meanAspectRatio = aspectRatios.sum / assets.length;
|
||||
|
||||
// 1: mean width
|
||||
// 0.5: width < mean - threshold
|
||||
// 1.5: width > mean + threshold
|
||||
final arConfiguration = aspectRatios.map((e) {
|
||||
if (e - meanAspectRatio > 0.3) return 1.5;
|
||||
if (e - meanAspectRatio < -0.3) return 0.5;
|
||||
return 1.0;
|
||||
});
|
||||
|
||||
// Normalize:
|
||||
final sum = arConfiguration.sum;
|
||||
widthDistribution.setRange(
|
||||
0,
|
||||
widthDistribution.length,
|
||||
arConfiguration.map((e) => (e * assets.length) / sum),
|
||||
);
|
||||
}
|
||||
return Row(
|
||||
key: key,
|
||||
children: assets.mapIndexed((int index, Asset asset) {
|
||||
final bool last = index + 1 == assetsPerRow;
|
||||
return Container(
|
||||
width: width * widthDistribution[index],
|
||||
height: width,
|
||||
margin: EdgeInsets.only(
|
||||
bottom: margin,
|
||||
right: last ? 0.0 : margin,
|
||||
),
|
||||
child: ThumbnailImage(
|
||||
asset: asset,
|
||||
index: absoluteOffset + index,
|
||||
loadAsset: renderList.loadAsset,
|
||||
totalAssets: renderList.totalAssets,
|
||||
multiselectEnabled: selectionActive,
|
||||
isSelected: isSelectionActive && selectedAssets.contains(asset),
|
||||
onSelect: () => onSelect?.call(asset),
|
||||
onDeselect: () => onDeselect?.call(asset),
|
||||
showStorageIndicator: showStorageIndicator,
|
||||
heroOffset: heroOffset,
|
||||
showStack: showStack,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class ThumbnailImage extends StatelessWidget {
|
||||
final int totalAssets;
|
||||
final bool showStorageIndicator;
|
||||
final bool showStack;
|
||||
final bool useGrayBoxPlaceholder;
|
||||
final bool isSelected;
|
||||
final bool multiselectEnabled;
|
||||
final Function? onSelect;
|
||||
@@ -29,6 +30,7 @@ class ThumbnailImage extends StatelessWidget {
|
||||
required this.totalAssets,
|
||||
this.showStorageIndicator = true,
|
||||
this.showStack = false,
|
||||
this.useGrayBoxPlaceholder = false,
|
||||
this.isSelected = false,
|
||||
this.multiselectEnabled = false,
|
||||
this.onDeselect,
|
||||
@@ -136,8 +138,6 @@ class ThumbnailImage extends StatelessWidget {
|
||||
: asset.id + heroOffset,
|
||||
child: ImmichImage.thumbnail(
|
||||
asset,
|
||||
height: 300,
|
||||
width: 300,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
|
||||
class ThumbnailPlaceholder extends StatelessWidget {
|
||||
final EdgeInsets margin;
|
||||
final double width;
|
||||
final double height;
|
||||
|
||||
const ThumbnailPlaceholder({
|
||||
super.key,
|
||||
this.margin = EdgeInsets.zero,
|
||||
this.width = 250,
|
||||
this.height = 250,
|
||||
});
|
||||
|
||||
static const _brightColors = [
|
||||
Color(0xFFF1F3F4),
|
||||
Color(0xFFB4B6B8),
|
||||
];
|
||||
|
||||
static const _darkColors = [
|
||||
Color(0xFF3B3F42),
|
||||
Color(0xFF2B2F32),
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: height,
|
||||
margin: margin,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: context.isDarkTheme ? _darkColors : _brightColors,
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -125,19 +125,6 @@ class ControlBottomAppBar extends ConsumerWidget {
|
||||
.tr(),
|
||||
onPressed: enabled ? onFavorite : null,
|
||||
),
|
||||
if (hasLocal && hasRemote && onDelete != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 90),
|
||||
child: ControlBoxButton(
|
||||
iconData: Icons.delete_sweep_outlined,
|
||||
label: "control_bottom_app_bar_delete".tr(),
|
||||
onPressed: enabled
|
||||
? () => handleRemoteDelete(!trashEnabled, onDelete!)
|
||||
: null,
|
||||
onLongPressed:
|
||||
enabled ? () => showForceDeleteDialog(onDelete!) : null,
|
||||
),
|
||||
),
|
||||
if (hasRemote && onDeleteServer != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 85),
|
||||
@@ -185,43 +172,44 @@ class ControlBottomAppBar extends ConsumerWidget {
|
||||
: null,
|
||||
),
|
||||
),
|
||||
if (hasRemote && onEditTime != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 95),
|
||||
child: ControlBoxButton(
|
||||
iconData: Icons.edit_calendar_outlined,
|
||||
label: "control_bottom_app_bar_edit_time".tr(),
|
||||
onPressed: enabled ? onEditTime : null,
|
||||
),
|
||||
),
|
||||
if (hasRemote && onEditLocation != null)
|
||||
if (hasLocal && hasRemote && onDelete != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 90),
|
||||
child: ControlBoxButton(
|
||||
iconData: Icons.edit_location_alt_outlined,
|
||||
label: "control_bottom_app_bar_edit_location".tr(),
|
||||
onPressed: enabled ? onEditLocation : null,
|
||||
iconData: Icons.delete_sweep_outlined,
|
||||
label: "control_bottom_app_bar_delete".tr(),
|
||||
onPressed: enabled
|
||||
? () => handleRemoteDelete(!trashEnabled, onDelete!)
|
||||
: null,
|
||||
onLongPressed:
|
||||
enabled ? () => showForceDeleteDialog(onDelete!) : null,
|
||||
),
|
||||
),
|
||||
if (hasRemote && onEditTime != null)
|
||||
ControlBoxButton(
|
||||
iconData: Icons.edit_calendar_outlined,
|
||||
label: "control_bottom_app_bar_edit_time".tr(),
|
||||
onPressed: enabled ? onEditTime : null,
|
||||
),
|
||||
if (hasRemote && onEditLocation != null)
|
||||
ControlBoxButton(
|
||||
iconData: Icons.edit_location_alt_outlined,
|
||||
label: "control_bottom_app_bar_edit_location".tr(),
|
||||
onPressed: enabled ? onEditLocation : null,
|
||||
),
|
||||
if (!selectionAssetState.hasLocal &&
|
||||
selectionAssetState.selectedCount > 1 &&
|
||||
onStack != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 90),
|
||||
child: ControlBoxButton(
|
||||
iconData: Icons.filter_none_rounded,
|
||||
label: "control_bottom_app_bar_stack".tr(),
|
||||
onPressed: enabled ? onStack : null,
|
||||
),
|
||||
ControlBoxButton(
|
||||
iconData: Icons.filter_none_rounded,
|
||||
label: "control_bottom_app_bar_stack".tr(),
|
||||
onPressed: enabled ? onStack : null,
|
||||
),
|
||||
if (onRemoveFromAlbum != null)
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 90),
|
||||
child: ControlBoxButton(
|
||||
iconData: Icons.delete_sweep_rounded,
|
||||
label: 'album_viewer_appbar_share_remove'.tr(),
|
||||
onPressed: enabled ? onRemoveFromAlbum : null,
|
||||
),
|
||||
ControlBoxButton(
|
||||
iconData: Icons.delete_sweep_rounded,
|
||||
label: 'album_viewer_appbar_share_remove'.tr(),
|
||||
onPressed: enabled ? onRemoveFromAlbum : null,
|
||||
),
|
||||
if (selectionAssetState.hasLocal)
|
||||
ControlBoxButton(
|
||||
@@ -242,9 +230,9 @@ class ControlBottomAppBar extends ConsumerWidget {
|
||||
}
|
||||
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: hasRemote ? 0.35 : bottomPadding,
|
||||
initialChildSize: hasRemote ? 0.30 : bottomPadding,
|
||||
minChildSize: bottomPadding,
|
||||
maxChildSize: hasRemote ? 0.65 : bottomPadding,
|
||||
maxChildSize: hasRemote ? 0.60 : bottomPadding,
|
||||
snap: true,
|
||||
builder: (
|
||||
BuildContext context,
|
||||
@@ -269,9 +257,9 @@ class ControlBottomAppBar extends ConsumerWidget {
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 12),
|
||||
const CustomDraggingHandle(),
|
||||
const SizedBox(height: 12),
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(
|
||||
height: 100,
|
||||
height: 90,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
scrollDirection: Axis.horizontal,
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'package:auto_route/auto_route.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
|
||||
import 'package:immich_mobile/modules/memories/providers/memory.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/shared/ui/immich_image.dart';
|
||||
@@ -61,10 +60,7 @@ class MemoryLane extends HookConsumerWidget {
|
||||
fit: BoxFit.cover,
|
||||
width: 130,
|
||||
height: 200,
|
||||
placeholder: const ThumbnailPlaceholder(
|
||||
width: 130,
|
||||
height: 200,
|
||||
),
|
||||
useGrayBoxPlaceholder: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:flutter/services.dart';
|
||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||
import 'package:immich_mobile/modules/asset_viewer/image_providers/immich_local_image_provider.dart';
|
||||
import 'package:immich_mobile/modules/asset_viewer/image_providers/immich_remote_image_provider.dart';
|
||||
import 'package:immich_mobile/modules/home/ui/asset_grid/thumbnail_placeholder.dart';
|
||||
import 'package:immich_mobile/shared/models/asset.dart';
|
||||
import 'package:immich_mobile/shared/models/store.dart';
|
||||
import 'package:octo_image/octo_image.dart';
|
||||
@@ -18,14 +17,14 @@ class ImmichImage extends StatelessWidget {
|
||||
this.width,
|
||||
this.height,
|
||||
this.fit = BoxFit.cover,
|
||||
this.placeholder = const ThumbnailPlaceholder(),
|
||||
this.useGrayBoxPlaceholder = false,
|
||||
this.isThumbnail = false,
|
||||
this.thumbnailSize = 250,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final Asset? asset;
|
||||
final Widget? placeholder;
|
||||
final bool useGrayBoxPlaceholder;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final BoxFit fit;
|
||||
@@ -48,10 +47,7 @@ class ImmichImage extends StatelessWidget {
|
||||
fit: fit,
|
||||
width: width,
|
||||
height: height,
|
||||
placeholder: ThumbnailPlaceholder(
|
||||
height: thumbnailSize.toDouble(),
|
||||
width: thumbnailSize.toDouble(),
|
||||
),
|
||||
useGrayBoxPlaceholder: true,
|
||||
thumbnailSize: thumbnailSize,
|
||||
);
|
||||
}
|
||||
@@ -103,6 +99,7 @@ class ImmichImage extends StatelessWidget {
|
||||
asset.isLocal && !Store.get(StoreKey.preferRemoteImage, false);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
if (asset == null) {
|
||||
return Container(
|
||||
decoration: const BoxDecoration(
|
||||
@@ -122,9 +119,13 @@ class ImmichImage extends StatelessWidget {
|
||||
fadeInDuration: const Duration(milliseconds: 0),
|
||||
fadeOutDuration: const Duration(milliseconds: 400),
|
||||
placeholderBuilder: (context) {
|
||||
if (placeholder != null) {
|
||||
if (useGrayBoxPlaceholder) {
|
||||
// Use the gray box placeholder
|
||||
return placeholder!;
|
||||
return const SizedBox.expand(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(color: Colors.grey),
|
||||
),
|
||||
);
|
||||
}
|
||||
// No placeholder
|
||||
return const SizedBox();
|
||||
|
||||
Generated
-6
@@ -90,7 +90,6 @@ doc/MapMarkerResponseDto.md
|
||||
doc/MapTheme.md
|
||||
doc/MemoryLaneResponseDto.md
|
||||
doc/MergePersonDto.md
|
||||
doc/MetadataSearchDto.md
|
||||
doc/ModelType.md
|
||||
doc/OAuthApi.md
|
||||
doc/OAuthAuthorizeResponseDto.md
|
||||
@@ -138,7 +137,6 @@ doc/SharedLinkResponseDto.md
|
||||
doc/SharedLinkType.md
|
||||
doc/SignUpDto.md
|
||||
doc/SmartInfoResponseDto.md
|
||||
doc/SmartSearchDto.md
|
||||
doc/SystemConfigApi.md
|
||||
doc/SystemConfigDto.md
|
||||
doc/SystemConfigFFmpegDto.md
|
||||
@@ -290,7 +288,6 @@ lib/model/map_marker_response_dto.dart
|
||||
lib/model/map_theme.dart
|
||||
lib/model/memory_lane_response_dto.dart
|
||||
lib/model/merge_person_dto.dart
|
||||
lib/model/metadata_search_dto.dart
|
||||
lib/model/model_type.dart
|
||||
lib/model/o_auth_authorize_response_dto.dart
|
||||
lib/model/o_auth_callback_dto.dart
|
||||
@@ -332,7 +329,6 @@ lib/model/shared_link_response_dto.dart
|
||||
lib/model/shared_link_type.dart
|
||||
lib/model/sign_up_dto.dart
|
||||
lib/model/smart_info_response_dto.dart
|
||||
lib/model/smart_search_dto.dart
|
||||
lib/model/system_config_dto.dart
|
||||
lib/model/system_config_f_fmpeg_dto.dart
|
||||
lib/model/system_config_job_dto.dart
|
||||
@@ -461,7 +457,6 @@ test/map_marker_response_dto_test.dart
|
||||
test/map_theme_test.dart
|
||||
test/memory_lane_response_dto_test.dart
|
||||
test/merge_person_dto_test.dart
|
||||
test/metadata_search_dto_test.dart
|
||||
test/model_type_test.dart
|
||||
test/o_auth_api_test.dart
|
||||
test/o_auth_authorize_response_dto_test.dart
|
||||
@@ -509,7 +504,6 @@ test/shared_link_response_dto_test.dart
|
||||
test/shared_link_type_test.dart
|
||||
test/sign_up_dto_test.dart
|
||||
test/smart_info_response_dto_test.dart
|
||||
test/smart_search_dto_test.dart
|
||||
test/system_config_api_test.dart
|
||||
test/system_config_dto_test.dart
|
||||
test/system_config_f_fmpeg_dto_test.dart
|
||||
|
||||
Generated
+2
-4
@@ -163,9 +163,9 @@ Class | Method | HTTP request | Description
|
||||
*SearchApi* | [**getExploreData**](doc//SearchApi.md#getexploredata) | **GET** /search/explore |
|
||||
*SearchApi* | [**getSearchSuggestions**](doc//SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions |
|
||||
*SearchApi* | [**search**](doc//SearchApi.md#search) | **GET** /search |
|
||||
*SearchApi* | [**searchMetadata**](doc//SearchApi.md#searchmetadata) | **POST** /search/metadata |
|
||||
*SearchApi* | [**searchMetadata**](doc//SearchApi.md#searchmetadata) | **GET** /search/metadata |
|
||||
*SearchApi* | [**searchPerson**](doc//SearchApi.md#searchperson) | **GET** /search/person |
|
||||
*SearchApi* | [**searchSmart**](doc//SearchApi.md#searchsmart) | **POST** /search/smart |
|
||||
*SearchApi* | [**searchSmart**](doc//SearchApi.md#searchsmart) | **GET** /search/smart |
|
||||
*ServerInfoApi* | [**getServerConfig**](doc//ServerInfoApi.md#getserverconfig) | **GET** /server-info/config |
|
||||
*ServerInfoApi* | [**getServerFeatures**](doc//ServerInfoApi.md#getserverfeatures) | **GET** /server-info/features |
|
||||
*ServerInfoApi* | [**getServerInfo**](doc//ServerInfoApi.md#getserverinfo) | **GET** /server-info |
|
||||
@@ -290,7 +290,6 @@ Class | Method | HTTP request | Description
|
||||
- [MapTheme](doc//MapTheme.md)
|
||||
- [MemoryLaneResponseDto](doc//MemoryLaneResponseDto.md)
|
||||
- [MergePersonDto](doc//MergePersonDto.md)
|
||||
- [MetadataSearchDto](doc//MetadataSearchDto.md)
|
||||
- [ModelType](doc//ModelType.md)
|
||||
- [OAuthAuthorizeResponseDto](doc//OAuthAuthorizeResponseDto.md)
|
||||
- [OAuthCallbackDto](doc//OAuthCallbackDto.md)
|
||||
@@ -332,7 +331,6 @@ Class | Method | HTTP request | Description
|
||||
- [SharedLinkType](doc//SharedLinkType.md)
|
||||
- [SignUpDto](doc//SignUpDto.md)
|
||||
- [SmartInfoResponseDto](doc//SmartInfoResponseDto.md)
|
||||
- [SmartSearchDto](doc//SmartSearchDto.md)
|
||||
- [SystemConfigDto](doc//SystemConfigDto.md)
|
||||
- [SystemConfigFFmpegDto](doc//SystemConfigFFmpegDto.md)
|
||||
- [SystemConfigJobDto](doc//SystemConfigJobDto.md)
|
||||
|
||||
Generated
+4
-10
@@ -659,7 +659,7 @@ This endpoint does not need any parameter.
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **getMapMarkers**
|
||||
> List<MapMarkerResponseDto> getMapMarkers(fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite, withPartners)
|
||||
> List<MapMarkerResponseDto> getMapMarkers(fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite)
|
||||
|
||||
|
||||
|
||||
@@ -686,10 +686,9 @@ final fileCreatedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final fileCreatedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final isArchived = true; // bool |
|
||||
final isFavorite = true; // bool |
|
||||
final withPartners = true; // bool |
|
||||
|
||||
try {
|
||||
final result = api_instance.getMapMarkers(fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite, withPartners);
|
||||
final result = api_instance.getMapMarkers(fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling AssetApi->getMapMarkers: $e\n');
|
||||
@@ -704,7 +703,6 @@ Name | Type | Description | Notes
|
||||
**fileCreatedBefore** | **DateTime**| | [optional]
|
||||
**isArchived** | **bool**| | [optional]
|
||||
**isFavorite** | **bool**| | [optional]
|
||||
**withPartners** | **bool**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -1036,7 +1034,7 @@ void (empty response body)
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **searchAssets**
|
||||
> List<AssetResponseDto> searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked)
|
||||
> List<AssetResponseDto> searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked)
|
||||
|
||||
|
||||
|
||||
@@ -1073,7 +1071,6 @@ final isEncoded = true; // bool |
|
||||
final isExternal = true; // bool |
|
||||
final isFavorite = true; // bool |
|
||||
final isMotion = true; // bool |
|
||||
final isNotInAlbum = true; // bool |
|
||||
final isOffline = true; // bool |
|
||||
final isReadOnly = true; // bool |
|
||||
final isVisible = true; // bool |
|
||||
@@ -1085,7 +1082,6 @@ final order = ; // AssetOrder |
|
||||
final originalFileName = originalFileName_example; // String |
|
||||
final originalPath = originalPath_example; // String |
|
||||
final page = 8.14; // num |
|
||||
final personIds = []; // List<String> |
|
||||
final resizePath = resizePath_example; // String |
|
||||
final size = 8.14; // num |
|
||||
final state = state_example; // String |
|
||||
@@ -1104,7 +1100,7 @@ final withPeople = true; // bool |
|
||||
final withStacked = true; // bool |
|
||||
|
||||
try {
|
||||
final result = api_instance.searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked);
|
||||
final result = api_instance.searchAssets(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling AssetApi->searchAssets: $e\n');
|
||||
@@ -1129,7 +1125,6 @@ Name | Type | Description | Notes
|
||||
**isExternal** | **bool**| | [optional]
|
||||
**isFavorite** | **bool**| | [optional]
|
||||
**isMotion** | **bool**| | [optional]
|
||||
**isNotInAlbum** | **bool**| | [optional]
|
||||
**isOffline** | **bool**| | [optional]
|
||||
**isReadOnly** | **bool**| | [optional]
|
||||
**isVisible** | **bool**| | [optional]
|
||||
@@ -1141,7 +1136,6 @@ Name | Type | Description | Notes
|
||||
**originalFileName** | **String**| | [optional]
|
||||
**originalPath** | **String**| | [optional]
|
||||
**page** | **num**| | [optional]
|
||||
**personIds** | [**List<String>**](String.md)| | [optional] [default to const []]
|
||||
**resizePath** | **String**| | [optional]
|
||||
**size** | **num**| | [optional]
|
||||
**state** | **String**| | [optional]
|
||||
|
||||
Generated
-57
@@ -1,57 +0,0 @@
|
||||
# openapi.model.MetadataSearchDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**checksum** | **String** | | [optional]
|
||||
**city** | **String** | | [optional]
|
||||
**country** | **String** | | [optional]
|
||||
**createdAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**createdBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**deviceAssetId** | **String** | | [optional]
|
||||
**deviceId** | **String** | | [optional]
|
||||
**encodedVideoPath** | **String** | | [optional]
|
||||
**id** | **String** | | [optional]
|
||||
**isArchived** | **bool** | | [optional]
|
||||
**isEncoded** | **bool** | | [optional]
|
||||
**isExternal** | **bool** | | [optional]
|
||||
**isFavorite** | **bool** | | [optional]
|
||||
**isMotion** | **bool** | | [optional]
|
||||
**isNotInAlbum** | **bool** | | [optional]
|
||||
**isOffline** | **bool** | | [optional]
|
||||
**isReadOnly** | **bool** | | [optional]
|
||||
**isVisible** | **bool** | | [optional]
|
||||
**lensModel** | **String** | | [optional]
|
||||
**libraryId** | **String** | | [optional]
|
||||
**make** | **String** | | [optional]
|
||||
**model** | **String** | | [optional]
|
||||
**order** | [**AssetOrder**](AssetOrder.md) | | [optional]
|
||||
**originalFileName** | **String** | | [optional]
|
||||
**originalPath** | **String** | | [optional]
|
||||
**page** | **num** | | [optional]
|
||||
**personIds** | **List<String>** | | [optional] [default to const []]
|
||||
**resizePath** | **String** | | [optional]
|
||||
**size** | **num** | | [optional]
|
||||
**state** | **String** | | [optional]
|
||||
**takenAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**takenBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**trashedAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**trashedBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**type** | [**AssetTypeEnum**](AssetTypeEnum.md) | | [optional]
|
||||
**updatedAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**updatedBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**webpPath** | **String** | | [optional]
|
||||
**withArchived** | **bool** | | [optional]
|
||||
**withDeleted** | **bool** | | [optional]
|
||||
**withExif** | **bool** | | [optional]
|
||||
**withPeople** | **bool** | | [optional]
|
||||
**withStacked** | **bool** | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
Generated
+152
-12
@@ -12,9 +12,9 @@ Method | HTTP request | Description
|
||||
[**getExploreData**](SearchApi.md#getexploredata) | **GET** /search/explore |
|
||||
[**getSearchSuggestions**](SearchApi.md#getsearchsuggestions) | **GET** /search/suggestions |
|
||||
[**search**](SearchApi.md#search) | **GET** /search |
|
||||
[**searchMetadata**](SearchApi.md#searchmetadata) | **POST** /search/metadata |
|
||||
[**searchMetadata**](SearchApi.md#searchmetadata) | **GET** /search/metadata |
|
||||
[**searchPerson**](SearchApi.md#searchperson) | **GET** /search/person |
|
||||
[**searchSmart**](SearchApi.md#searchsmart) | **POST** /search/smart |
|
||||
[**searchSmart**](SearchApi.md#searchsmart) | **GET** /search/smart |
|
||||
|
||||
|
||||
# **getExploreData**
|
||||
@@ -205,7 +205,7 @@ Name | Type | Description | Notes
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **searchMetadata**
|
||||
> SearchResponseDto searchMetadata(metadataSearchDto)
|
||||
> SearchResponseDto searchMetadata(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked)
|
||||
|
||||
|
||||
|
||||
@@ -228,10 +228,50 @@ import 'package:openapi/api.dart';
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||
|
||||
final api_instance = SearchApi();
|
||||
final metadataSearchDto = MetadataSearchDto(); // MetadataSearchDto |
|
||||
final checksum = checksum_example; // String |
|
||||
final city = city_example; // String |
|
||||
final country = country_example; // String |
|
||||
final createdAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final createdBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final deviceAssetId = deviceAssetId_example; // String |
|
||||
final deviceId = deviceId_example; // String |
|
||||
final encodedVideoPath = encodedVideoPath_example; // String |
|
||||
final id = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
|
||||
final isArchived = true; // bool |
|
||||
final isEncoded = true; // bool |
|
||||
final isExternal = true; // bool |
|
||||
final isFavorite = true; // bool |
|
||||
final isMotion = true; // bool |
|
||||
final isOffline = true; // bool |
|
||||
final isReadOnly = true; // bool |
|
||||
final isVisible = true; // bool |
|
||||
final lensModel = lensModel_example; // String |
|
||||
final libraryId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
|
||||
final make = make_example; // String |
|
||||
final model = model_example; // String |
|
||||
final order = ; // AssetOrder |
|
||||
final originalFileName = originalFileName_example; // String |
|
||||
final originalPath = originalPath_example; // String |
|
||||
final page = 8.14; // num |
|
||||
final resizePath = resizePath_example; // String |
|
||||
final size = 8.14; // num |
|
||||
final state = state_example; // String |
|
||||
final takenAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final takenBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final trashedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final trashedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final type = ; // AssetTypeEnum |
|
||||
final updatedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final updatedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final webpPath = webpPath_example; // String |
|
||||
final withArchived = true; // bool |
|
||||
final withDeleted = true; // bool |
|
||||
final withExif = true; // bool |
|
||||
final withPeople = true; // bool |
|
||||
final withStacked = true; // bool |
|
||||
|
||||
try {
|
||||
final result = api_instance.searchMetadata(metadataSearchDto);
|
||||
final result = api_instance.searchMetadata(checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling SearchApi->searchMetadata: $e\n');
|
||||
@@ -242,7 +282,47 @@ try {
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**metadataSearchDto** | [**MetadataSearchDto**](MetadataSearchDto.md)| |
|
||||
**checksum** | **String**| | [optional]
|
||||
**city** | **String**| | [optional]
|
||||
**country** | **String**| | [optional]
|
||||
**createdAfter** | **DateTime**| | [optional]
|
||||
**createdBefore** | **DateTime**| | [optional]
|
||||
**deviceAssetId** | **String**| | [optional]
|
||||
**deviceId** | **String**| | [optional]
|
||||
**encodedVideoPath** | **String**| | [optional]
|
||||
**id** | **String**| | [optional]
|
||||
**isArchived** | **bool**| | [optional]
|
||||
**isEncoded** | **bool**| | [optional]
|
||||
**isExternal** | **bool**| | [optional]
|
||||
**isFavorite** | **bool**| | [optional]
|
||||
**isMotion** | **bool**| | [optional]
|
||||
**isOffline** | **bool**| | [optional]
|
||||
**isReadOnly** | **bool**| | [optional]
|
||||
**isVisible** | **bool**| | [optional]
|
||||
**lensModel** | **String**| | [optional]
|
||||
**libraryId** | **String**| | [optional]
|
||||
**make** | **String**| | [optional]
|
||||
**model** | **String**| | [optional]
|
||||
**order** | [**AssetOrder**](.md)| | [optional]
|
||||
**originalFileName** | **String**| | [optional]
|
||||
**originalPath** | **String**| | [optional]
|
||||
**page** | **num**| | [optional]
|
||||
**resizePath** | **String**| | [optional]
|
||||
**size** | **num**| | [optional]
|
||||
**state** | **String**| | [optional]
|
||||
**takenAfter** | **DateTime**| | [optional]
|
||||
**takenBefore** | **DateTime**| | [optional]
|
||||
**trashedAfter** | **DateTime**| | [optional]
|
||||
**trashedBefore** | **DateTime**| | [optional]
|
||||
**type** | [**AssetTypeEnum**](.md)| | [optional]
|
||||
**updatedAfter** | **DateTime**| | [optional]
|
||||
**updatedBefore** | **DateTime**| | [optional]
|
||||
**webpPath** | **String**| | [optional]
|
||||
**withArchived** | **bool**| | [optional]
|
||||
**withDeleted** | **bool**| | [optional]
|
||||
**withExif** | **bool**| | [optional]
|
||||
**withPeople** | **bool**| | [optional]
|
||||
**withStacked** | **bool**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -254,7 +334,7 @@ Name | Type | Description | Notes
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
@@ -317,7 +397,7 @@ Name | Type | Description | Notes
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **searchSmart**
|
||||
> SearchResponseDto searchSmart(smartSearchDto)
|
||||
> SearchResponseDto searchSmart(query, city, country, createdAfter, createdBefore, deviceId, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, page, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, withArchived, withDeleted, withExif)
|
||||
|
||||
|
||||
|
||||
@@ -340,10 +420,40 @@ import 'package:openapi/api.dart';
|
||||
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
|
||||
|
||||
final api_instance = SearchApi();
|
||||
final smartSearchDto = SmartSearchDto(); // SmartSearchDto |
|
||||
final query = query_example; // String |
|
||||
final city = city_example; // String |
|
||||
final country = country_example; // String |
|
||||
final createdAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final createdBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final deviceId = deviceId_example; // String |
|
||||
final isArchived = true; // bool |
|
||||
final isEncoded = true; // bool |
|
||||
final isExternal = true; // bool |
|
||||
final isFavorite = true; // bool |
|
||||
final isMotion = true; // bool |
|
||||
final isOffline = true; // bool |
|
||||
final isReadOnly = true; // bool |
|
||||
final isVisible = true; // bool |
|
||||
final lensModel = lensModel_example; // String |
|
||||
final libraryId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
|
||||
final make = make_example; // String |
|
||||
final model = model_example; // String |
|
||||
final page = 8.14; // num |
|
||||
final size = 8.14; // num |
|
||||
final state = state_example; // String |
|
||||
final takenAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final takenBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final trashedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final trashedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final type = ; // AssetTypeEnum |
|
||||
final updatedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final updatedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
|
||||
final withArchived = true; // bool |
|
||||
final withDeleted = true; // bool |
|
||||
final withExif = true; // bool |
|
||||
|
||||
try {
|
||||
final result = api_instance.searchSmart(smartSearchDto);
|
||||
final result = api_instance.searchSmart(query, city, country, createdAfter, createdBefore, deviceId, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, page, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, type, updatedAfter, updatedBefore, withArchived, withDeleted, withExif);
|
||||
print(result);
|
||||
} catch (e) {
|
||||
print('Exception when calling SearchApi->searchSmart: $e\n');
|
||||
@@ -354,7 +464,37 @@ try {
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**smartSearchDto** | [**SmartSearchDto**](SmartSearchDto.md)| |
|
||||
**query** | **String**| |
|
||||
**city** | **String**| | [optional]
|
||||
**country** | **String**| | [optional]
|
||||
**createdAfter** | **DateTime**| | [optional]
|
||||
**createdBefore** | **DateTime**| | [optional]
|
||||
**deviceId** | **String**| | [optional]
|
||||
**isArchived** | **bool**| | [optional]
|
||||
**isEncoded** | **bool**| | [optional]
|
||||
**isExternal** | **bool**| | [optional]
|
||||
**isFavorite** | **bool**| | [optional]
|
||||
**isMotion** | **bool**| | [optional]
|
||||
**isOffline** | **bool**| | [optional]
|
||||
**isReadOnly** | **bool**| | [optional]
|
||||
**isVisible** | **bool**| | [optional]
|
||||
**lensModel** | **String**| | [optional]
|
||||
**libraryId** | **String**| | [optional]
|
||||
**make** | **String**| | [optional]
|
||||
**model** | **String**| | [optional]
|
||||
**page** | **num**| | [optional]
|
||||
**size** | **num**| | [optional]
|
||||
**state** | **String**| | [optional]
|
||||
**takenAfter** | **DateTime**| | [optional]
|
||||
**takenBefore** | **DateTime**| | [optional]
|
||||
**trashedAfter** | **DateTime**| | [optional]
|
||||
**trashedBefore** | **DateTime**| | [optional]
|
||||
**type** | [**AssetTypeEnum**](.md)| | [optional]
|
||||
**updatedAfter** | **DateTime**| | [optional]
|
||||
**updatedBefore** | **DateTime**| | [optional]
|
||||
**withArchived** | **bool**| | [optional]
|
||||
**withDeleted** | **bool**| | [optional]
|
||||
**withExif** | **bool**| | [optional]
|
||||
|
||||
### Return type
|
||||
|
||||
@@ -366,7 +506,7 @@ Name | Type | Description | Notes
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
Generated
-45
@@ -1,45 +0,0 @@
|
||||
# openapi.model.SmartSearchDto
|
||||
|
||||
## Load the model package
|
||||
```dart
|
||||
import 'package:openapi/api.dart';
|
||||
```
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**city** | **String** | | [optional]
|
||||
**country** | **String** | | [optional]
|
||||
**createdAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**createdBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**deviceId** | **String** | | [optional]
|
||||
**isArchived** | **bool** | | [optional]
|
||||
**isEncoded** | **bool** | | [optional]
|
||||
**isExternal** | **bool** | | [optional]
|
||||
**isFavorite** | **bool** | | [optional]
|
||||
**isMotion** | **bool** | | [optional]
|
||||
**isOffline** | **bool** | | [optional]
|
||||
**isReadOnly** | **bool** | | [optional]
|
||||
**isVisible** | **bool** | | [optional]
|
||||
**lensModel** | **String** | | [optional]
|
||||
**libraryId** | **String** | | [optional]
|
||||
**make** | **String** | | [optional]
|
||||
**model** | **String** | | [optional]
|
||||
**page** | **num** | | [optional]
|
||||
**query** | **String** | |
|
||||
**size** | **num** | | [optional]
|
||||
**state** | **String** | | [optional]
|
||||
**takenAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**takenBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**trashedAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**trashedBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**type** | [**AssetTypeEnum**](AssetTypeEnum.md) | | [optional]
|
||||
**updatedAfter** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**updatedBefore** | [**DateTime**](DateTime.md) | | [optional]
|
||||
**withArchived** | **bool** | | [optional]
|
||||
**withDeleted** | **bool** | | [optional]
|
||||
**withExif** | **bool** | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
Generated
-2
@@ -127,7 +127,6 @@ part 'model/map_marker_response_dto.dart';
|
||||
part 'model/map_theme.dart';
|
||||
part 'model/memory_lane_response_dto.dart';
|
||||
part 'model/merge_person_dto.dart';
|
||||
part 'model/metadata_search_dto.dart';
|
||||
part 'model/model_type.dart';
|
||||
part 'model/o_auth_authorize_response_dto.dart';
|
||||
part 'model/o_auth_callback_dto.dart';
|
||||
@@ -169,7 +168,6 @@ part 'model/shared_link_response_dto.dart';
|
||||
part 'model/shared_link_type.dart';
|
||||
part 'model/sign_up_dto.dart';
|
||||
part 'model/smart_info_response_dto.dart';
|
||||
part 'model/smart_search_dto.dart';
|
||||
part 'model/system_config_dto.dart';
|
||||
part 'model/system_config_f_fmpeg_dto.dart';
|
||||
part 'model/system_config_job_dto.dart';
|
||||
|
||||
Generated
+6
-27
@@ -652,9 +652,7 @@ class AssetApi {
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] withPartners:
|
||||
Future<Response> getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, }) async {
|
||||
Future<Response> getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/asset/map-marker';
|
||||
|
||||
@@ -677,9 +675,6 @@ class AssetApi {
|
||||
if (isFavorite != null) {
|
||||
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
|
||||
}
|
||||
if (withPartners != null) {
|
||||
queryParams.addAll(_queryParams('', 'withPartners', withPartners));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
@@ -704,10 +699,8 @@ class AssetApi {
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] withPartners:
|
||||
Future<List<MapMarkerResponseDto>?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, }) async {
|
||||
final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, );
|
||||
Future<List<MapMarkerResponseDto>?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, }) async {
|
||||
final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -1140,8 +1133,6 @@ class AssetApi {
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isNotInAlbum:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
@@ -1164,8 +1155,6 @@ class AssetApi {
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [List<String>] personIds:
|
||||
///
|
||||
/// * [String] resizePath:
|
||||
///
|
||||
/// * [num] size:
|
||||
@@ -1197,7 +1186,7 @@ class AssetApi {
|
||||
/// * [bool] withPeople:
|
||||
///
|
||||
/// * [bool] withStacked:
|
||||
Future<Response> searchAssetsWithHttpInfo({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, List<String>? personIds, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
Future<Response> searchAssetsWithHttpInfo({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/assets';
|
||||
|
||||
@@ -1250,9 +1239,6 @@ class AssetApi {
|
||||
if (isMotion != null) {
|
||||
queryParams.addAll(_queryParams('', 'isMotion', isMotion));
|
||||
}
|
||||
if (isNotInAlbum != null) {
|
||||
queryParams.addAll(_queryParams('', 'isNotInAlbum', isNotInAlbum));
|
||||
}
|
||||
if (isOffline != null) {
|
||||
queryParams.addAll(_queryParams('', 'isOffline', isOffline));
|
||||
}
|
||||
@@ -1286,9 +1272,6 @@ class AssetApi {
|
||||
if (page != null) {
|
||||
queryParams.addAll(_queryParams('', 'page', page));
|
||||
}
|
||||
if (personIds != null) {
|
||||
queryParams.addAll(_queryParams('multi', 'personIds', personIds));
|
||||
}
|
||||
if (resizePath != null) {
|
||||
queryParams.addAll(_queryParams('', 'resizePath', resizePath));
|
||||
}
|
||||
@@ -1382,8 +1365,6 @@ class AssetApi {
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isNotInAlbum:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
@@ -1406,8 +1387,6 @@ class AssetApi {
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [List<String>] personIds:
|
||||
///
|
||||
/// * [String] resizePath:
|
||||
///
|
||||
/// * [num] size:
|
||||
@@ -1439,8 +1418,8 @@ class AssetApi {
|
||||
/// * [bool] withPeople:
|
||||
///
|
||||
/// * [bool] withStacked:
|
||||
Future<List<AssetResponseDto>?> searchAssets({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, List<String>? personIds, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
final response = await searchAssetsWithHttpInfo( checksum: checksum, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceAssetId: deviceAssetId, deviceId: deviceId, encodedVideoPath: encodedVideoPath, id: id, isArchived: isArchived, isEncoded: isEncoded, isExternal: isExternal, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, isReadOnly: isReadOnly, isVisible: isVisible, lensModel: lensModel, libraryId: libraryId, make: make, model: model, order: order, originalFileName: originalFileName, originalPath: originalPath, page: page, personIds: personIds, resizePath: resizePath, size: size, state: state, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, webpPath: webpPath, withArchived: withArchived, withDeleted: withDeleted, withExif: withExif, withPeople: withPeople, withStacked: withStacked, );
|
||||
Future<List<AssetResponseDto>?> searchAssets({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
final response = await searchAssetsWithHttpInfo( checksum: checksum, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceAssetId: deviceAssetId, deviceId: deviceId, encodedVideoPath: encodedVideoPath, id: id, isArchived: isArchived, isEncoded: isEncoded, isExternal: isExternal, isFavorite: isFavorite, isMotion: isMotion, isOffline: isOffline, isReadOnly: isReadOnly, isVisible: isVisible, lensModel: lensModel, libraryId: libraryId, make: make, model: model, order: order, originalFileName: originalFileName, originalPath: originalPath, page: page, resizePath: resizePath, size: size, state: state, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, webpPath: webpPath, withArchived: withArchived, withDeleted: withDeleted, withExif: withExif, withPeople: withPeople, withStacked: withStacked, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
|
||||
Generated
+514
-18
@@ -254,27 +254,231 @@ class SearchApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /search/metadata' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /search/metadata' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [MetadataSearchDto] metadataSearchDto (required):
|
||||
Future<Response> searchMetadataWithHttpInfo(MetadataSearchDto metadataSearchDto,) async {
|
||||
/// * [String] checksum:
|
||||
///
|
||||
/// * [String] city:
|
||||
///
|
||||
/// * [String] country:
|
||||
///
|
||||
/// * [DateTime] createdAfter:
|
||||
///
|
||||
/// * [DateTime] createdBefore:
|
||||
///
|
||||
/// * [String] deviceAssetId:
|
||||
///
|
||||
/// * [String] deviceId:
|
||||
///
|
||||
/// * [String] encodedVideoPath:
|
||||
///
|
||||
/// * [String] id:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isEncoded:
|
||||
///
|
||||
/// * [bool] isExternal:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
///
|
||||
/// * [bool] isVisible:
|
||||
///
|
||||
/// * [String] lensModel:
|
||||
///
|
||||
/// * [String] libraryId:
|
||||
///
|
||||
/// * [String] make:
|
||||
///
|
||||
/// * [String] model:
|
||||
///
|
||||
/// * [AssetOrder] order:
|
||||
///
|
||||
/// * [String] originalFileName:
|
||||
///
|
||||
/// * [String] originalPath:
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [String] resizePath:
|
||||
///
|
||||
/// * [num] size:
|
||||
///
|
||||
/// * [String] state:
|
||||
///
|
||||
/// * [DateTime] takenAfter:
|
||||
///
|
||||
/// * [DateTime] takenBefore:
|
||||
///
|
||||
/// * [DateTime] trashedAfter:
|
||||
///
|
||||
/// * [DateTime] trashedBefore:
|
||||
///
|
||||
/// * [AssetTypeEnum] type:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [String] webpPath:
|
||||
///
|
||||
/// * [bool] withArchived:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
///
|
||||
/// * [bool] withExif:
|
||||
///
|
||||
/// * [bool] withPeople:
|
||||
///
|
||||
/// * [bool] withStacked:
|
||||
Future<Response> searchMetadataWithHttpInfo({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/search/metadata';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = metadataSearchDto;
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>['application/json'];
|
||||
if (checksum != null) {
|
||||
queryParams.addAll(_queryParams('', 'checksum', checksum));
|
||||
}
|
||||
if (city != null) {
|
||||
queryParams.addAll(_queryParams('', 'city', city));
|
||||
}
|
||||
if (country != null) {
|
||||
queryParams.addAll(_queryParams('', 'country', country));
|
||||
}
|
||||
if (createdAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'createdAfter', createdAfter));
|
||||
}
|
||||
if (createdBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'createdBefore', createdBefore));
|
||||
}
|
||||
if (deviceAssetId != null) {
|
||||
queryParams.addAll(_queryParams('', 'deviceAssetId', deviceAssetId));
|
||||
}
|
||||
if (deviceId != null) {
|
||||
queryParams.addAll(_queryParams('', 'deviceId', deviceId));
|
||||
}
|
||||
if (encodedVideoPath != null) {
|
||||
queryParams.addAll(_queryParams('', 'encodedVideoPath', encodedVideoPath));
|
||||
}
|
||||
if (id != null) {
|
||||
queryParams.addAll(_queryParams('', 'id', id));
|
||||
}
|
||||
if (isArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'isArchived', isArchived));
|
||||
}
|
||||
if (isEncoded != null) {
|
||||
queryParams.addAll(_queryParams('', 'isEncoded', isEncoded));
|
||||
}
|
||||
if (isExternal != null) {
|
||||
queryParams.addAll(_queryParams('', 'isExternal', isExternal));
|
||||
}
|
||||
if (isFavorite != null) {
|
||||
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
|
||||
}
|
||||
if (isMotion != null) {
|
||||
queryParams.addAll(_queryParams('', 'isMotion', isMotion));
|
||||
}
|
||||
if (isOffline != null) {
|
||||
queryParams.addAll(_queryParams('', 'isOffline', isOffline));
|
||||
}
|
||||
if (isReadOnly != null) {
|
||||
queryParams.addAll(_queryParams('', 'isReadOnly', isReadOnly));
|
||||
}
|
||||
if (isVisible != null) {
|
||||
queryParams.addAll(_queryParams('', 'isVisible', isVisible));
|
||||
}
|
||||
if (lensModel != null) {
|
||||
queryParams.addAll(_queryParams('', 'lensModel', lensModel));
|
||||
}
|
||||
if (libraryId != null) {
|
||||
queryParams.addAll(_queryParams('', 'libraryId', libraryId));
|
||||
}
|
||||
if (make != null) {
|
||||
queryParams.addAll(_queryParams('', 'make', make));
|
||||
}
|
||||
if (model != null) {
|
||||
queryParams.addAll(_queryParams('', 'model', model));
|
||||
}
|
||||
if (order != null) {
|
||||
queryParams.addAll(_queryParams('', 'order', order));
|
||||
}
|
||||
if (originalFileName != null) {
|
||||
queryParams.addAll(_queryParams('', 'originalFileName', originalFileName));
|
||||
}
|
||||
if (originalPath != null) {
|
||||
queryParams.addAll(_queryParams('', 'originalPath', originalPath));
|
||||
}
|
||||
if (page != null) {
|
||||
queryParams.addAll(_queryParams('', 'page', page));
|
||||
}
|
||||
if (resizePath != null) {
|
||||
queryParams.addAll(_queryParams('', 'resizePath', resizePath));
|
||||
}
|
||||
if (size != null) {
|
||||
queryParams.addAll(_queryParams('', 'size', size));
|
||||
}
|
||||
if (state != null) {
|
||||
queryParams.addAll(_queryParams('', 'state', state));
|
||||
}
|
||||
if (takenAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'takenAfter', takenAfter));
|
||||
}
|
||||
if (takenBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'takenBefore', takenBefore));
|
||||
}
|
||||
if (trashedAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'trashedAfter', trashedAfter));
|
||||
}
|
||||
if (trashedBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'trashedBefore', trashedBefore));
|
||||
}
|
||||
if (type != null) {
|
||||
queryParams.addAll(_queryParams('', 'type', type));
|
||||
}
|
||||
if (updatedAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter));
|
||||
}
|
||||
if (updatedBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedBefore', updatedBefore));
|
||||
}
|
||||
if (webpPath != null) {
|
||||
queryParams.addAll(_queryParams('', 'webpPath', webpPath));
|
||||
}
|
||||
if (withArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'withArchived', withArchived));
|
||||
}
|
||||
if (withDeleted != null) {
|
||||
queryParams.addAll(_queryParams('', 'withDeleted', withDeleted));
|
||||
}
|
||||
if (withExif != null) {
|
||||
queryParams.addAll(_queryParams('', 'withExif', withExif));
|
||||
}
|
||||
if (withPeople != null) {
|
||||
queryParams.addAll(_queryParams('', 'withPeople', withPeople));
|
||||
}
|
||||
if (withStacked != null) {
|
||||
queryParams.addAll(_queryParams('', 'withStacked', withStacked));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'POST',
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
@@ -285,9 +489,89 @@ class SearchApi {
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [MetadataSearchDto] metadataSearchDto (required):
|
||||
Future<SearchResponseDto?> searchMetadata(MetadataSearchDto metadataSearchDto,) async {
|
||||
final response = await searchMetadataWithHttpInfo(metadataSearchDto,);
|
||||
/// * [String] checksum:
|
||||
///
|
||||
/// * [String] city:
|
||||
///
|
||||
/// * [String] country:
|
||||
///
|
||||
/// * [DateTime] createdAfter:
|
||||
///
|
||||
/// * [DateTime] createdBefore:
|
||||
///
|
||||
/// * [String] deviceAssetId:
|
||||
///
|
||||
/// * [String] deviceId:
|
||||
///
|
||||
/// * [String] encodedVideoPath:
|
||||
///
|
||||
/// * [String] id:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isEncoded:
|
||||
///
|
||||
/// * [bool] isExternal:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
///
|
||||
/// * [bool] isVisible:
|
||||
///
|
||||
/// * [String] lensModel:
|
||||
///
|
||||
/// * [String] libraryId:
|
||||
///
|
||||
/// * [String] make:
|
||||
///
|
||||
/// * [String] model:
|
||||
///
|
||||
/// * [AssetOrder] order:
|
||||
///
|
||||
/// * [String] originalFileName:
|
||||
///
|
||||
/// * [String] originalPath:
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [String] resizePath:
|
||||
///
|
||||
/// * [num] size:
|
||||
///
|
||||
/// * [String] state:
|
||||
///
|
||||
/// * [DateTime] takenAfter:
|
||||
///
|
||||
/// * [DateTime] takenBefore:
|
||||
///
|
||||
/// * [DateTime] trashedAfter:
|
||||
///
|
||||
/// * [DateTime] trashedBefore:
|
||||
///
|
||||
/// * [AssetTypeEnum] type:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [String] webpPath:
|
||||
///
|
||||
/// * [bool] withArchived:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
///
|
||||
/// * [bool] withExif:
|
||||
///
|
||||
/// * [bool] withPeople:
|
||||
///
|
||||
/// * [bool] withStacked:
|
||||
Future<SearchResponseDto?> searchMetadata({ String? checksum, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceAssetId, String? deviceId, String? encodedVideoPath, String? id, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, AssetOrder? order, String? originalFileName, String? originalPath, num? page, String? resizePath, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, String? webpPath, bool? withArchived, bool? withDeleted, bool? withExif, bool? withPeople, bool? withStacked, }) async {
|
||||
final response = await searchMetadataWithHttpInfo( checksum: checksum, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceAssetId: deviceAssetId, deviceId: deviceId, encodedVideoPath: encodedVideoPath, id: id, isArchived: isArchived, isEncoded: isEncoded, isExternal: isExternal, isFavorite: isFavorite, isMotion: isMotion, isOffline: isOffline, isReadOnly: isReadOnly, isVisible: isVisible, lensModel: lensModel, libraryId: libraryId, make: make, model: model, order: order, originalFileName: originalFileName, originalPath: originalPath, page: page, resizePath: resizePath, size: size, state: state, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, webpPath: webpPath, withArchived: withArchived, withDeleted: withDeleted, withExif: withExif, withPeople: withPeople, withStacked: withStacked, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
@@ -360,27 +644,179 @@ class SearchApi {
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Performs an HTTP 'POST /search/smart' operation and returns the [Response].
|
||||
/// Performs an HTTP 'GET /search/smart' operation and returns the [Response].
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [SmartSearchDto] smartSearchDto (required):
|
||||
Future<Response> searchSmartWithHttpInfo(SmartSearchDto smartSearchDto,) async {
|
||||
/// * [String] query (required):
|
||||
///
|
||||
/// * [String] city:
|
||||
///
|
||||
/// * [String] country:
|
||||
///
|
||||
/// * [DateTime] createdAfter:
|
||||
///
|
||||
/// * [DateTime] createdBefore:
|
||||
///
|
||||
/// * [String] deviceId:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isEncoded:
|
||||
///
|
||||
/// * [bool] isExternal:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
///
|
||||
/// * [bool] isVisible:
|
||||
///
|
||||
/// * [String] lensModel:
|
||||
///
|
||||
/// * [String] libraryId:
|
||||
///
|
||||
/// * [String] make:
|
||||
///
|
||||
/// * [String] model:
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [num] size:
|
||||
///
|
||||
/// * [String] state:
|
||||
///
|
||||
/// * [DateTime] takenAfter:
|
||||
///
|
||||
/// * [DateTime] takenBefore:
|
||||
///
|
||||
/// * [DateTime] trashedAfter:
|
||||
///
|
||||
/// * [DateTime] trashedBefore:
|
||||
///
|
||||
/// * [AssetTypeEnum] type:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [bool] withArchived:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
///
|
||||
/// * [bool] withExif:
|
||||
Future<Response> searchSmartWithHttpInfo(String query, { String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, num? page, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, bool? withArchived, bool? withDeleted, bool? withExif, }) async {
|
||||
// ignore: prefer_const_declarations
|
||||
final path = r'/search/smart';
|
||||
|
||||
// ignore: prefer_final_locals
|
||||
Object? postBody = smartSearchDto;
|
||||
Object? postBody;
|
||||
|
||||
final queryParams = <QueryParam>[];
|
||||
final headerParams = <String, String>{};
|
||||
final formParams = <String, String>{};
|
||||
|
||||
const contentTypes = <String>['application/json'];
|
||||
if (city != null) {
|
||||
queryParams.addAll(_queryParams('', 'city', city));
|
||||
}
|
||||
if (country != null) {
|
||||
queryParams.addAll(_queryParams('', 'country', country));
|
||||
}
|
||||
if (createdAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'createdAfter', createdAfter));
|
||||
}
|
||||
if (createdBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'createdBefore', createdBefore));
|
||||
}
|
||||
if (deviceId != null) {
|
||||
queryParams.addAll(_queryParams('', 'deviceId', deviceId));
|
||||
}
|
||||
if (isArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'isArchived', isArchived));
|
||||
}
|
||||
if (isEncoded != null) {
|
||||
queryParams.addAll(_queryParams('', 'isEncoded', isEncoded));
|
||||
}
|
||||
if (isExternal != null) {
|
||||
queryParams.addAll(_queryParams('', 'isExternal', isExternal));
|
||||
}
|
||||
if (isFavorite != null) {
|
||||
queryParams.addAll(_queryParams('', 'isFavorite', isFavorite));
|
||||
}
|
||||
if (isMotion != null) {
|
||||
queryParams.addAll(_queryParams('', 'isMotion', isMotion));
|
||||
}
|
||||
if (isOffline != null) {
|
||||
queryParams.addAll(_queryParams('', 'isOffline', isOffline));
|
||||
}
|
||||
if (isReadOnly != null) {
|
||||
queryParams.addAll(_queryParams('', 'isReadOnly', isReadOnly));
|
||||
}
|
||||
if (isVisible != null) {
|
||||
queryParams.addAll(_queryParams('', 'isVisible', isVisible));
|
||||
}
|
||||
if (lensModel != null) {
|
||||
queryParams.addAll(_queryParams('', 'lensModel', lensModel));
|
||||
}
|
||||
if (libraryId != null) {
|
||||
queryParams.addAll(_queryParams('', 'libraryId', libraryId));
|
||||
}
|
||||
if (make != null) {
|
||||
queryParams.addAll(_queryParams('', 'make', make));
|
||||
}
|
||||
if (model != null) {
|
||||
queryParams.addAll(_queryParams('', 'model', model));
|
||||
}
|
||||
if (page != null) {
|
||||
queryParams.addAll(_queryParams('', 'page', page));
|
||||
}
|
||||
queryParams.addAll(_queryParams('', 'query', query));
|
||||
if (size != null) {
|
||||
queryParams.addAll(_queryParams('', 'size', size));
|
||||
}
|
||||
if (state != null) {
|
||||
queryParams.addAll(_queryParams('', 'state', state));
|
||||
}
|
||||
if (takenAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'takenAfter', takenAfter));
|
||||
}
|
||||
if (takenBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'takenBefore', takenBefore));
|
||||
}
|
||||
if (trashedAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'trashedAfter', trashedAfter));
|
||||
}
|
||||
if (trashedBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'trashedBefore', trashedBefore));
|
||||
}
|
||||
if (type != null) {
|
||||
queryParams.addAll(_queryParams('', 'type', type));
|
||||
}
|
||||
if (updatedAfter != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter));
|
||||
}
|
||||
if (updatedBefore != null) {
|
||||
queryParams.addAll(_queryParams('', 'updatedBefore', updatedBefore));
|
||||
}
|
||||
if (withArchived != null) {
|
||||
queryParams.addAll(_queryParams('', 'withArchived', withArchived));
|
||||
}
|
||||
if (withDeleted != null) {
|
||||
queryParams.addAll(_queryParams('', 'withDeleted', withDeleted));
|
||||
}
|
||||
if (withExif != null) {
|
||||
queryParams.addAll(_queryParams('', 'withExif', withExif));
|
||||
}
|
||||
|
||||
const contentTypes = <String>[];
|
||||
|
||||
|
||||
return apiClient.invokeAPI(
|
||||
path,
|
||||
'POST',
|
||||
'GET',
|
||||
queryParams,
|
||||
postBody,
|
||||
headerParams,
|
||||
@@ -391,9 +827,69 @@ class SearchApi {
|
||||
|
||||
/// Parameters:
|
||||
///
|
||||
/// * [SmartSearchDto] smartSearchDto (required):
|
||||
Future<SearchResponseDto?> searchSmart(SmartSearchDto smartSearchDto,) async {
|
||||
final response = await searchSmartWithHttpInfo(smartSearchDto,);
|
||||
/// * [String] query (required):
|
||||
///
|
||||
/// * [String] city:
|
||||
///
|
||||
/// * [String] country:
|
||||
///
|
||||
/// * [DateTime] createdAfter:
|
||||
///
|
||||
/// * [DateTime] createdBefore:
|
||||
///
|
||||
/// * [String] deviceId:
|
||||
///
|
||||
/// * [bool] isArchived:
|
||||
///
|
||||
/// * [bool] isEncoded:
|
||||
///
|
||||
/// * [bool] isExternal:
|
||||
///
|
||||
/// * [bool] isFavorite:
|
||||
///
|
||||
/// * [bool] isMotion:
|
||||
///
|
||||
/// * [bool] isOffline:
|
||||
///
|
||||
/// * [bool] isReadOnly:
|
||||
///
|
||||
/// * [bool] isVisible:
|
||||
///
|
||||
/// * [String] lensModel:
|
||||
///
|
||||
/// * [String] libraryId:
|
||||
///
|
||||
/// * [String] make:
|
||||
///
|
||||
/// * [String] model:
|
||||
///
|
||||
/// * [num] page:
|
||||
///
|
||||
/// * [num] size:
|
||||
///
|
||||
/// * [String] state:
|
||||
///
|
||||
/// * [DateTime] takenAfter:
|
||||
///
|
||||
/// * [DateTime] takenBefore:
|
||||
///
|
||||
/// * [DateTime] trashedAfter:
|
||||
///
|
||||
/// * [DateTime] trashedBefore:
|
||||
///
|
||||
/// * [AssetTypeEnum] type:
|
||||
///
|
||||
/// * [DateTime] updatedAfter:
|
||||
///
|
||||
/// * [DateTime] updatedBefore:
|
||||
///
|
||||
/// * [bool] withArchived:
|
||||
///
|
||||
/// * [bool] withDeleted:
|
||||
///
|
||||
/// * [bool] withExif:
|
||||
Future<SearchResponseDto?> searchSmart(String query, { String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isArchived, bool? isEncoded, bool? isExternal, bool? isFavorite, bool? isMotion, bool? isOffline, bool? isReadOnly, bool? isVisible, String? lensModel, String? libraryId, String? make, String? model, num? page, num? size, String? state, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, bool? withArchived, bool? withDeleted, bool? withExif, }) async {
|
||||
final response = await searchSmartWithHttpInfo(query, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceId: deviceId, isArchived: isArchived, isEncoded: isEncoded, isExternal: isExternal, isFavorite: isFavorite, isMotion: isMotion, isOffline: isOffline, isReadOnly: isReadOnly, isVisible: isVisible, lensModel: lensModel, libraryId: libraryId, make: make, model: model, page: page, size: size, state: state, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, withArchived: withArchived, withDeleted: withDeleted, withExif: withExif, );
|
||||
if (response.statusCode >= HttpStatus.badRequest) {
|
||||
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
|
||||
}
|
||||
|
||||
Generated
-4
@@ -336,8 +336,6 @@ class ApiClient {
|
||||
return MemoryLaneResponseDto.fromJson(value);
|
||||
case 'MergePersonDto':
|
||||
return MergePersonDto.fromJson(value);
|
||||
case 'MetadataSearchDto':
|
||||
return MetadataSearchDto.fromJson(value);
|
||||
case 'ModelType':
|
||||
return ModelTypeTypeTransformer().decode(value);
|
||||
case 'OAuthAuthorizeResponseDto':
|
||||
@@ -420,8 +418,6 @@ class ApiClient {
|
||||
return SignUpDto.fromJson(value);
|
||||
case 'SmartInfoResponseDto':
|
||||
return SmartInfoResponseDto.fromJson(value);
|
||||
case 'SmartSearchDto':
|
||||
return SmartSearchDto.fromJson(value);
|
||||
case 'SystemConfigDto':
|
||||
return SystemConfigDto.fromJson(value);
|
||||
case 'SystemConfigFFmpegDto':
|
||||
|
||||
-813
@@ -1,813 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class MetadataSearchDto {
|
||||
/// Returns a new [MetadataSearchDto] instance.
|
||||
MetadataSearchDto({
|
||||
this.checksum,
|
||||
this.city,
|
||||
this.country,
|
||||
this.createdAfter,
|
||||
this.createdBefore,
|
||||
this.deviceAssetId,
|
||||
this.deviceId,
|
||||
this.encodedVideoPath,
|
||||
this.id,
|
||||
this.isArchived,
|
||||
this.isEncoded,
|
||||
this.isExternal,
|
||||
this.isFavorite,
|
||||
this.isMotion,
|
||||
this.isNotInAlbum,
|
||||
this.isOffline,
|
||||
this.isReadOnly,
|
||||
this.isVisible,
|
||||
this.lensModel,
|
||||
this.libraryId,
|
||||
this.make,
|
||||
this.model,
|
||||
this.order,
|
||||
this.originalFileName,
|
||||
this.originalPath,
|
||||
this.page,
|
||||
this.personIds = const [],
|
||||
this.resizePath,
|
||||
this.size,
|
||||
this.state,
|
||||
this.takenAfter,
|
||||
this.takenBefore,
|
||||
this.trashedAfter,
|
||||
this.trashedBefore,
|
||||
this.type,
|
||||
this.updatedAfter,
|
||||
this.updatedBefore,
|
||||
this.webpPath,
|
||||
this.withArchived,
|
||||
this.withDeleted,
|
||||
this.withExif,
|
||||
this.withPeople,
|
||||
this.withStacked,
|
||||
});
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? checksum;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? city;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? country;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? createdAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? createdBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? deviceAssetId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? deviceId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? encodedVideoPath;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? id;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isArchived;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isEncoded;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isExternal;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isMotion;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isNotInAlbum;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isOffline;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isReadOnly;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isVisible;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? lensModel;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? libraryId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? make;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? model;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
AssetOrder? order;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? originalFileName;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? originalPath;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
num? page;
|
||||
|
||||
List<String> personIds;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? resizePath;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
num? size;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? state;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? takenAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? takenBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? trashedAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? trashedBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
AssetTypeEnum? type;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? updatedAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? updatedBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? webpPath;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withArchived;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withDeleted;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withExif;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withPeople;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withStacked;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is MetadataSearchDto &&
|
||||
other.checksum == checksum &&
|
||||
other.city == city &&
|
||||
other.country == country &&
|
||||
other.createdAfter == createdAfter &&
|
||||
other.createdBefore == createdBefore &&
|
||||
other.deviceAssetId == deviceAssetId &&
|
||||
other.deviceId == deviceId &&
|
||||
other.encodedVideoPath == encodedVideoPath &&
|
||||
other.id == id &&
|
||||
other.isArchived == isArchived &&
|
||||
other.isEncoded == isEncoded &&
|
||||
other.isExternal == isExternal &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isMotion == isMotion &&
|
||||
other.isNotInAlbum == isNotInAlbum &&
|
||||
other.isOffline == isOffline &&
|
||||
other.isReadOnly == isReadOnly &&
|
||||
other.isVisible == isVisible &&
|
||||
other.lensModel == lensModel &&
|
||||
other.libraryId == libraryId &&
|
||||
other.make == make &&
|
||||
other.model == model &&
|
||||
other.order == order &&
|
||||
other.originalFileName == originalFileName &&
|
||||
other.originalPath == originalPath &&
|
||||
other.page == page &&
|
||||
_deepEquality.equals(other.personIds, personIds) &&
|
||||
other.resizePath == resizePath &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
other.takenAfter == takenAfter &&
|
||||
other.takenBefore == takenBefore &&
|
||||
other.trashedAfter == trashedAfter &&
|
||||
other.trashedBefore == trashedBefore &&
|
||||
other.type == type &&
|
||||
other.updatedAfter == updatedAfter &&
|
||||
other.updatedBefore == updatedBefore &&
|
||||
other.webpPath == webpPath &&
|
||||
other.withArchived == withArchived &&
|
||||
other.withDeleted == withDeleted &&
|
||||
other.withExif == withExif &&
|
||||
other.withPeople == withPeople &&
|
||||
other.withStacked == withStacked;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(checksum == null ? 0 : checksum!.hashCode) +
|
||||
(city == null ? 0 : city!.hashCode) +
|
||||
(country == null ? 0 : country!.hashCode) +
|
||||
(createdAfter == null ? 0 : createdAfter!.hashCode) +
|
||||
(createdBefore == null ? 0 : createdBefore!.hashCode) +
|
||||
(deviceAssetId == null ? 0 : deviceAssetId!.hashCode) +
|
||||
(deviceId == null ? 0 : deviceId!.hashCode) +
|
||||
(encodedVideoPath == null ? 0 : encodedVideoPath!.hashCode) +
|
||||
(id == null ? 0 : id!.hashCode) +
|
||||
(isArchived == null ? 0 : isArchived!.hashCode) +
|
||||
(isEncoded == null ? 0 : isEncoded!.hashCode) +
|
||||
(isExternal == null ? 0 : isExternal!.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isMotion == null ? 0 : isMotion!.hashCode) +
|
||||
(isNotInAlbum == null ? 0 : isNotInAlbum!.hashCode) +
|
||||
(isOffline == null ? 0 : isOffline!.hashCode) +
|
||||
(isReadOnly == null ? 0 : isReadOnly!.hashCode) +
|
||||
(isVisible == null ? 0 : isVisible!.hashCode) +
|
||||
(lensModel == null ? 0 : lensModel!.hashCode) +
|
||||
(libraryId == null ? 0 : libraryId!.hashCode) +
|
||||
(make == null ? 0 : make!.hashCode) +
|
||||
(model == null ? 0 : model!.hashCode) +
|
||||
(order == null ? 0 : order!.hashCode) +
|
||||
(originalFileName == null ? 0 : originalFileName!.hashCode) +
|
||||
(originalPath == null ? 0 : originalPath!.hashCode) +
|
||||
(page == null ? 0 : page!.hashCode) +
|
||||
(personIds.hashCode) +
|
||||
(resizePath == null ? 0 : resizePath!.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
(takenBefore == null ? 0 : takenBefore!.hashCode) +
|
||||
(trashedAfter == null ? 0 : trashedAfter!.hashCode) +
|
||||
(trashedBefore == null ? 0 : trashedBefore!.hashCode) +
|
||||
(type == null ? 0 : type!.hashCode) +
|
||||
(updatedAfter == null ? 0 : updatedAfter!.hashCode) +
|
||||
(updatedBefore == null ? 0 : updatedBefore!.hashCode) +
|
||||
(webpPath == null ? 0 : webpPath!.hashCode) +
|
||||
(withArchived == null ? 0 : withArchived!.hashCode) +
|
||||
(withDeleted == null ? 0 : withDeleted!.hashCode) +
|
||||
(withExif == null ? 0 : withExif!.hashCode) +
|
||||
(withPeople == null ? 0 : withPeople!.hashCode) +
|
||||
(withStacked == null ? 0 : withStacked!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'MetadataSearchDto[checksum=$checksum, city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceAssetId=$deviceAssetId, deviceId=$deviceId, encodedVideoPath=$encodedVideoPath, id=$id, isArchived=$isArchived, isEncoded=$isEncoded, isExternal=$isExternal, isFavorite=$isFavorite, isMotion=$isMotion, isNotInAlbum=$isNotInAlbum, isOffline=$isOffline, isReadOnly=$isReadOnly, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, order=$order, originalFileName=$originalFileName, originalPath=$originalPath, page=$page, personIds=$personIds, resizePath=$resizePath, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, webpPath=$webpPath, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif, withPeople=$withPeople, withStacked=$withStacked]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
if (this.checksum != null) {
|
||||
json[r'checksum'] = this.checksum;
|
||||
} else {
|
||||
// json[r'checksum'] = null;
|
||||
}
|
||||
if (this.city != null) {
|
||||
json[r'city'] = this.city;
|
||||
} else {
|
||||
// json[r'city'] = null;
|
||||
}
|
||||
if (this.country != null) {
|
||||
json[r'country'] = this.country;
|
||||
} else {
|
||||
// json[r'country'] = null;
|
||||
}
|
||||
if (this.createdAfter != null) {
|
||||
json[r'createdAfter'] = this.createdAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'createdAfter'] = null;
|
||||
}
|
||||
if (this.createdBefore != null) {
|
||||
json[r'createdBefore'] = this.createdBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'createdBefore'] = null;
|
||||
}
|
||||
if (this.deviceAssetId != null) {
|
||||
json[r'deviceAssetId'] = this.deviceAssetId;
|
||||
} else {
|
||||
// json[r'deviceAssetId'] = null;
|
||||
}
|
||||
if (this.deviceId != null) {
|
||||
json[r'deviceId'] = this.deviceId;
|
||||
} else {
|
||||
// json[r'deviceId'] = null;
|
||||
}
|
||||
if (this.encodedVideoPath != null) {
|
||||
json[r'encodedVideoPath'] = this.encodedVideoPath;
|
||||
} else {
|
||||
// json[r'encodedVideoPath'] = null;
|
||||
}
|
||||
if (this.id != null) {
|
||||
json[r'id'] = this.id;
|
||||
} else {
|
||||
// json[r'id'] = null;
|
||||
}
|
||||
if (this.isArchived != null) {
|
||||
json[r'isArchived'] = this.isArchived;
|
||||
} else {
|
||||
// json[r'isArchived'] = null;
|
||||
}
|
||||
if (this.isEncoded != null) {
|
||||
json[r'isEncoded'] = this.isEncoded;
|
||||
} else {
|
||||
// json[r'isEncoded'] = null;
|
||||
}
|
||||
if (this.isExternal != null) {
|
||||
json[r'isExternal'] = this.isExternal;
|
||||
} else {
|
||||
// json[r'isExternal'] = null;
|
||||
}
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
if (this.isMotion != null) {
|
||||
json[r'isMotion'] = this.isMotion;
|
||||
} else {
|
||||
// json[r'isMotion'] = null;
|
||||
}
|
||||
if (this.isNotInAlbum != null) {
|
||||
json[r'isNotInAlbum'] = this.isNotInAlbum;
|
||||
} else {
|
||||
// json[r'isNotInAlbum'] = null;
|
||||
}
|
||||
if (this.isOffline != null) {
|
||||
json[r'isOffline'] = this.isOffline;
|
||||
} else {
|
||||
// json[r'isOffline'] = null;
|
||||
}
|
||||
if (this.isReadOnly != null) {
|
||||
json[r'isReadOnly'] = this.isReadOnly;
|
||||
} else {
|
||||
// json[r'isReadOnly'] = null;
|
||||
}
|
||||
if (this.isVisible != null) {
|
||||
json[r'isVisible'] = this.isVisible;
|
||||
} else {
|
||||
// json[r'isVisible'] = null;
|
||||
}
|
||||
if (this.lensModel != null) {
|
||||
json[r'lensModel'] = this.lensModel;
|
||||
} else {
|
||||
// json[r'lensModel'] = null;
|
||||
}
|
||||
if (this.libraryId != null) {
|
||||
json[r'libraryId'] = this.libraryId;
|
||||
} else {
|
||||
// json[r'libraryId'] = null;
|
||||
}
|
||||
if (this.make != null) {
|
||||
json[r'make'] = this.make;
|
||||
} else {
|
||||
// json[r'make'] = null;
|
||||
}
|
||||
if (this.model != null) {
|
||||
json[r'model'] = this.model;
|
||||
} else {
|
||||
// json[r'model'] = null;
|
||||
}
|
||||
if (this.order != null) {
|
||||
json[r'order'] = this.order;
|
||||
} else {
|
||||
// json[r'order'] = null;
|
||||
}
|
||||
if (this.originalFileName != null) {
|
||||
json[r'originalFileName'] = this.originalFileName;
|
||||
} else {
|
||||
// json[r'originalFileName'] = null;
|
||||
}
|
||||
if (this.originalPath != null) {
|
||||
json[r'originalPath'] = this.originalPath;
|
||||
} else {
|
||||
// json[r'originalPath'] = null;
|
||||
}
|
||||
if (this.page != null) {
|
||||
json[r'page'] = this.page;
|
||||
} else {
|
||||
// json[r'page'] = null;
|
||||
}
|
||||
json[r'personIds'] = this.personIds;
|
||||
if (this.resizePath != null) {
|
||||
json[r'resizePath'] = this.resizePath;
|
||||
} else {
|
||||
// json[r'resizePath'] = null;
|
||||
}
|
||||
if (this.size != null) {
|
||||
json[r'size'] = this.size;
|
||||
} else {
|
||||
// json[r'size'] = null;
|
||||
}
|
||||
if (this.state != null) {
|
||||
json[r'state'] = this.state;
|
||||
} else {
|
||||
// json[r'state'] = null;
|
||||
}
|
||||
if (this.takenAfter != null) {
|
||||
json[r'takenAfter'] = this.takenAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'takenAfter'] = null;
|
||||
}
|
||||
if (this.takenBefore != null) {
|
||||
json[r'takenBefore'] = this.takenBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'takenBefore'] = null;
|
||||
}
|
||||
if (this.trashedAfter != null) {
|
||||
json[r'trashedAfter'] = this.trashedAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'trashedAfter'] = null;
|
||||
}
|
||||
if (this.trashedBefore != null) {
|
||||
json[r'trashedBefore'] = this.trashedBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'trashedBefore'] = null;
|
||||
}
|
||||
if (this.type != null) {
|
||||
json[r'type'] = this.type;
|
||||
} else {
|
||||
// json[r'type'] = null;
|
||||
}
|
||||
if (this.updatedAfter != null) {
|
||||
json[r'updatedAfter'] = this.updatedAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'updatedAfter'] = null;
|
||||
}
|
||||
if (this.updatedBefore != null) {
|
||||
json[r'updatedBefore'] = this.updatedBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'updatedBefore'] = null;
|
||||
}
|
||||
if (this.webpPath != null) {
|
||||
json[r'webpPath'] = this.webpPath;
|
||||
} else {
|
||||
// json[r'webpPath'] = null;
|
||||
}
|
||||
if (this.withArchived != null) {
|
||||
json[r'withArchived'] = this.withArchived;
|
||||
} else {
|
||||
// json[r'withArchived'] = null;
|
||||
}
|
||||
if (this.withDeleted != null) {
|
||||
json[r'withDeleted'] = this.withDeleted;
|
||||
} else {
|
||||
// json[r'withDeleted'] = null;
|
||||
}
|
||||
if (this.withExif != null) {
|
||||
json[r'withExif'] = this.withExif;
|
||||
} else {
|
||||
// json[r'withExif'] = null;
|
||||
}
|
||||
if (this.withPeople != null) {
|
||||
json[r'withPeople'] = this.withPeople;
|
||||
} else {
|
||||
// json[r'withPeople'] = null;
|
||||
}
|
||||
if (this.withStacked != null) {
|
||||
json[r'withStacked'] = this.withStacked;
|
||||
} else {
|
||||
// json[r'withStacked'] = null;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [MetadataSearchDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static MetadataSearchDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return MetadataSearchDto(
|
||||
checksum: mapValueOfType<String>(json, r'checksum'),
|
||||
city: mapValueOfType<String>(json, r'city'),
|
||||
country: mapValueOfType<String>(json, r'country'),
|
||||
createdAfter: mapDateTime(json, r'createdAfter', r''),
|
||||
createdBefore: mapDateTime(json, r'createdBefore', r''),
|
||||
deviceAssetId: mapValueOfType<String>(json, r'deviceAssetId'),
|
||||
deviceId: mapValueOfType<String>(json, r'deviceId'),
|
||||
encodedVideoPath: mapValueOfType<String>(json, r'encodedVideoPath'),
|
||||
id: mapValueOfType<String>(json, r'id'),
|
||||
isArchived: mapValueOfType<bool>(json, r'isArchived'),
|
||||
isEncoded: mapValueOfType<bool>(json, r'isEncoded'),
|
||||
isExternal: mapValueOfType<bool>(json, r'isExternal'),
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isMotion: mapValueOfType<bool>(json, r'isMotion'),
|
||||
isNotInAlbum: mapValueOfType<bool>(json, r'isNotInAlbum'),
|
||||
isOffline: mapValueOfType<bool>(json, r'isOffline'),
|
||||
isReadOnly: mapValueOfType<bool>(json, r'isReadOnly'),
|
||||
isVisible: mapValueOfType<bool>(json, r'isVisible'),
|
||||
lensModel: mapValueOfType<String>(json, r'lensModel'),
|
||||
libraryId: mapValueOfType<String>(json, r'libraryId'),
|
||||
make: mapValueOfType<String>(json, r'make'),
|
||||
model: mapValueOfType<String>(json, r'model'),
|
||||
order: AssetOrder.fromJson(json[r'order']),
|
||||
originalFileName: mapValueOfType<String>(json, r'originalFileName'),
|
||||
originalPath: mapValueOfType<String>(json, r'originalPath'),
|
||||
page: num.parse('${json[r'page']}'),
|
||||
personIds: json[r'personIds'] is Iterable
|
||||
? (json[r'personIds'] as Iterable).cast<String>().toList(growable: false)
|
||||
: const [],
|
||||
resizePath: mapValueOfType<String>(json, r'resizePath'),
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
takenBefore: mapDateTime(json, r'takenBefore', r''),
|
||||
trashedAfter: mapDateTime(json, r'trashedAfter', r''),
|
||||
trashedBefore: mapDateTime(json, r'trashedBefore', r''),
|
||||
type: AssetTypeEnum.fromJson(json[r'type']),
|
||||
updatedAfter: mapDateTime(json, r'updatedAfter', r''),
|
||||
updatedBefore: mapDateTime(json, r'updatedBefore', r''),
|
||||
webpPath: mapValueOfType<String>(json, r'webpPath'),
|
||||
withArchived: mapValueOfType<bool>(json, r'withArchived'),
|
||||
withDeleted: mapValueOfType<bool>(json, r'withDeleted'),
|
||||
withExif: mapValueOfType<bool>(json, r'withExif'),
|
||||
withPeople: mapValueOfType<bool>(json, r'withPeople'),
|
||||
withStacked: mapValueOfType<bool>(json, r'withStacked'),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<MetadataSearchDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <MetadataSearchDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = MetadataSearchDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, MetadataSearchDto> mapFromJson(dynamic json) {
|
||||
final map = <String, MetadataSearchDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = MetadataSearchDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of MetadataSearchDto-objects as value to a dart map
|
||||
static Map<String, List<MetadataSearchDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<MetadataSearchDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = MetadataSearchDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
};
|
||||
}
|
||||
|
||||
-608
@@ -1,608 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
part of openapi.api;
|
||||
|
||||
class SmartSearchDto {
|
||||
/// Returns a new [SmartSearchDto] instance.
|
||||
SmartSearchDto({
|
||||
this.city,
|
||||
this.country,
|
||||
this.createdAfter,
|
||||
this.createdBefore,
|
||||
this.deviceId,
|
||||
this.isArchived,
|
||||
this.isEncoded,
|
||||
this.isExternal,
|
||||
this.isFavorite,
|
||||
this.isMotion,
|
||||
this.isOffline,
|
||||
this.isReadOnly,
|
||||
this.isVisible,
|
||||
this.lensModel,
|
||||
this.libraryId,
|
||||
this.make,
|
||||
this.model,
|
||||
this.page,
|
||||
required this.query,
|
||||
this.size,
|
||||
this.state,
|
||||
this.takenAfter,
|
||||
this.takenBefore,
|
||||
this.trashedAfter,
|
||||
this.trashedBefore,
|
||||
this.type,
|
||||
this.updatedAfter,
|
||||
this.updatedBefore,
|
||||
this.withArchived,
|
||||
this.withDeleted,
|
||||
this.withExif,
|
||||
});
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? city;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? country;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? createdAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? createdBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? deviceId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isArchived;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isEncoded;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isExternal;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isFavorite;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isMotion;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isOffline;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isReadOnly;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? isVisible;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? lensModel;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? libraryId;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? make;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? model;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
num? page;
|
||||
|
||||
String query;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
num? size;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
String? state;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? takenAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? takenBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? trashedAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? trashedBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
AssetTypeEnum? type;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? updatedAfter;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
DateTime? updatedBefore;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withArchived;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withDeleted;
|
||||
|
||||
///
|
||||
/// Please note: This property should have been non-nullable! Since the specification file
|
||||
/// does not include a default value (using the "default:" property), however, the generated
|
||||
/// source code must fall back to having a nullable type.
|
||||
/// Consider adding a "default:" property in the specification file to hide this note.
|
||||
///
|
||||
bool? withExif;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) => identical(this, other) || other is SmartSearchDto &&
|
||||
other.city == city &&
|
||||
other.country == country &&
|
||||
other.createdAfter == createdAfter &&
|
||||
other.createdBefore == createdBefore &&
|
||||
other.deviceId == deviceId &&
|
||||
other.isArchived == isArchived &&
|
||||
other.isEncoded == isEncoded &&
|
||||
other.isExternal == isExternal &&
|
||||
other.isFavorite == isFavorite &&
|
||||
other.isMotion == isMotion &&
|
||||
other.isOffline == isOffline &&
|
||||
other.isReadOnly == isReadOnly &&
|
||||
other.isVisible == isVisible &&
|
||||
other.lensModel == lensModel &&
|
||||
other.libraryId == libraryId &&
|
||||
other.make == make &&
|
||||
other.model == model &&
|
||||
other.page == page &&
|
||||
other.query == query &&
|
||||
other.size == size &&
|
||||
other.state == state &&
|
||||
other.takenAfter == takenAfter &&
|
||||
other.takenBefore == takenBefore &&
|
||||
other.trashedAfter == trashedAfter &&
|
||||
other.trashedBefore == trashedBefore &&
|
||||
other.type == type &&
|
||||
other.updatedAfter == updatedAfter &&
|
||||
other.updatedBefore == updatedBefore &&
|
||||
other.withArchived == withArchived &&
|
||||
other.withDeleted == withDeleted &&
|
||||
other.withExif == withExif;
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
// ignore: unnecessary_parenthesis
|
||||
(city == null ? 0 : city!.hashCode) +
|
||||
(country == null ? 0 : country!.hashCode) +
|
||||
(createdAfter == null ? 0 : createdAfter!.hashCode) +
|
||||
(createdBefore == null ? 0 : createdBefore!.hashCode) +
|
||||
(deviceId == null ? 0 : deviceId!.hashCode) +
|
||||
(isArchived == null ? 0 : isArchived!.hashCode) +
|
||||
(isEncoded == null ? 0 : isEncoded!.hashCode) +
|
||||
(isExternal == null ? 0 : isExternal!.hashCode) +
|
||||
(isFavorite == null ? 0 : isFavorite!.hashCode) +
|
||||
(isMotion == null ? 0 : isMotion!.hashCode) +
|
||||
(isOffline == null ? 0 : isOffline!.hashCode) +
|
||||
(isReadOnly == null ? 0 : isReadOnly!.hashCode) +
|
||||
(isVisible == null ? 0 : isVisible!.hashCode) +
|
||||
(lensModel == null ? 0 : lensModel!.hashCode) +
|
||||
(libraryId == null ? 0 : libraryId!.hashCode) +
|
||||
(make == null ? 0 : make!.hashCode) +
|
||||
(model == null ? 0 : model!.hashCode) +
|
||||
(page == null ? 0 : page!.hashCode) +
|
||||
(query.hashCode) +
|
||||
(size == null ? 0 : size!.hashCode) +
|
||||
(state == null ? 0 : state!.hashCode) +
|
||||
(takenAfter == null ? 0 : takenAfter!.hashCode) +
|
||||
(takenBefore == null ? 0 : takenBefore!.hashCode) +
|
||||
(trashedAfter == null ? 0 : trashedAfter!.hashCode) +
|
||||
(trashedBefore == null ? 0 : trashedBefore!.hashCode) +
|
||||
(type == null ? 0 : type!.hashCode) +
|
||||
(updatedAfter == null ? 0 : updatedAfter!.hashCode) +
|
||||
(updatedBefore == null ? 0 : updatedBefore!.hashCode) +
|
||||
(withArchived == null ? 0 : withArchived!.hashCode) +
|
||||
(withDeleted == null ? 0 : withDeleted!.hashCode) +
|
||||
(withExif == null ? 0 : withExif!.hashCode);
|
||||
|
||||
@override
|
||||
String toString() => 'SmartSearchDto[city=$city, country=$country, createdAfter=$createdAfter, createdBefore=$createdBefore, deviceId=$deviceId, isArchived=$isArchived, isEncoded=$isEncoded, isExternal=$isExternal, isFavorite=$isFavorite, isMotion=$isMotion, isOffline=$isOffline, isReadOnly=$isReadOnly, isVisible=$isVisible, lensModel=$lensModel, libraryId=$libraryId, make=$make, model=$model, page=$page, query=$query, size=$size, state=$state, takenAfter=$takenAfter, takenBefore=$takenBefore, trashedAfter=$trashedAfter, trashedBefore=$trashedBefore, type=$type, updatedAfter=$updatedAfter, updatedBefore=$updatedBefore, withArchived=$withArchived, withDeleted=$withDeleted, withExif=$withExif]';
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final json = <String, dynamic>{};
|
||||
if (this.city != null) {
|
||||
json[r'city'] = this.city;
|
||||
} else {
|
||||
// json[r'city'] = null;
|
||||
}
|
||||
if (this.country != null) {
|
||||
json[r'country'] = this.country;
|
||||
} else {
|
||||
// json[r'country'] = null;
|
||||
}
|
||||
if (this.createdAfter != null) {
|
||||
json[r'createdAfter'] = this.createdAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'createdAfter'] = null;
|
||||
}
|
||||
if (this.createdBefore != null) {
|
||||
json[r'createdBefore'] = this.createdBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'createdBefore'] = null;
|
||||
}
|
||||
if (this.deviceId != null) {
|
||||
json[r'deviceId'] = this.deviceId;
|
||||
} else {
|
||||
// json[r'deviceId'] = null;
|
||||
}
|
||||
if (this.isArchived != null) {
|
||||
json[r'isArchived'] = this.isArchived;
|
||||
} else {
|
||||
// json[r'isArchived'] = null;
|
||||
}
|
||||
if (this.isEncoded != null) {
|
||||
json[r'isEncoded'] = this.isEncoded;
|
||||
} else {
|
||||
// json[r'isEncoded'] = null;
|
||||
}
|
||||
if (this.isExternal != null) {
|
||||
json[r'isExternal'] = this.isExternal;
|
||||
} else {
|
||||
// json[r'isExternal'] = null;
|
||||
}
|
||||
if (this.isFavorite != null) {
|
||||
json[r'isFavorite'] = this.isFavorite;
|
||||
} else {
|
||||
// json[r'isFavorite'] = null;
|
||||
}
|
||||
if (this.isMotion != null) {
|
||||
json[r'isMotion'] = this.isMotion;
|
||||
} else {
|
||||
// json[r'isMotion'] = null;
|
||||
}
|
||||
if (this.isOffline != null) {
|
||||
json[r'isOffline'] = this.isOffline;
|
||||
} else {
|
||||
// json[r'isOffline'] = null;
|
||||
}
|
||||
if (this.isReadOnly != null) {
|
||||
json[r'isReadOnly'] = this.isReadOnly;
|
||||
} else {
|
||||
// json[r'isReadOnly'] = null;
|
||||
}
|
||||
if (this.isVisible != null) {
|
||||
json[r'isVisible'] = this.isVisible;
|
||||
} else {
|
||||
// json[r'isVisible'] = null;
|
||||
}
|
||||
if (this.lensModel != null) {
|
||||
json[r'lensModel'] = this.lensModel;
|
||||
} else {
|
||||
// json[r'lensModel'] = null;
|
||||
}
|
||||
if (this.libraryId != null) {
|
||||
json[r'libraryId'] = this.libraryId;
|
||||
} else {
|
||||
// json[r'libraryId'] = null;
|
||||
}
|
||||
if (this.make != null) {
|
||||
json[r'make'] = this.make;
|
||||
} else {
|
||||
// json[r'make'] = null;
|
||||
}
|
||||
if (this.model != null) {
|
||||
json[r'model'] = this.model;
|
||||
} else {
|
||||
// json[r'model'] = null;
|
||||
}
|
||||
if (this.page != null) {
|
||||
json[r'page'] = this.page;
|
||||
} else {
|
||||
// json[r'page'] = null;
|
||||
}
|
||||
json[r'query'] = this.query;
|
||||
if (this.size != null) {
|
||||
json[r'size'] = this.size;
|
||||
} else {
|
||||
// json[r'size'] = null;
|
||||
}
|
||||
if (this.state != null) {
|
||||
json[r'state'] = this.state;
|
||||
} else {
|
||||
// json[r'state'] = null;
|
||||
}
|
||||
if (this.takenAfter != null) {
|
||||
json[r'takenAfter'] = this.takenAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'takenAfter'] = null;
|
||||
}
|
||||
if (this.takenBefore != null) {
|
||||
json[r'takenBefore'] = this.takenBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'takenBefore'] = null;
|
||||
}
|
||||
if (this.trashedAfter != null) {
|
||||
json[r'trashedAfter'] = this.trashedAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'trashedAfter'] = null;
|
||||
}
|
||||
if (this.trashedBefore != null) {
|
||||
json[r'trashedBefore'] = this.trashedBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'trashedBefore'] = null;
|
||||
}
|
||||
if (this.type != null) {
|
||||
json[r'type'] = this.type;
|
||||
} else {
|
||||
// json[r'type'] = null;
|
||||
}
|
||||
if (this.updatedAfter != null) {
|
||||
json[r'updatedAfter'] = this.updatedAfter!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'updatedAfter'] = null;
|
||||
}
|
||||
if (this.updatedBefore != null) {
|
||||
json[r'updatedBefore'] = this.updatedBefore!.toUtc().toIso8601String();
|
||||
} else {
|
||||
// json[r'updatedBefore'] = null;
|
||||
}
|
||||
if (this.withArchived != null) {
|
||||
json[r'withArchived'] = this.withArchived;
|
||||
} else {
|
||||
// json[r'withArchived'] = null;
|
||||
}
|
||||
if (this.withDeleted != null) {
|
||||
json[r'withDeleted'] = this.withDeleted;
|
||||
} else {
|
||||
// json[r'withDeleted'] = null;
|
||||
}
|
||||
if (this.withExif != null) {
|
||||
json[r'withExif'] = this.withExif;
|
||||
} else {
|
||||
// json[r'withExif'] = null;
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/// Returns a new [SmartSearchDto] instance and imports its values from
|
||||
/// [value] if it's a [Map], null otherwise.
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static SmartSearchDto? fromJson(dynamic value) {
|
||||
if (value is Map) {
|
||||
final json = value.cast<String, dynamic>();
|
||||
|
||||
return SmartSearchDto(
|
||||
city: mapValueOfType<String>(json, r'city'),
|
||||
country: mapValueOfType<String>(json, r'country'),
|
||||
createdAfter: mapDateTime(json, r'createdAfter', r''),
|
||||
createdBefore: mapDateTime(json, r'createdBefore', r''),
|
||||
deviceId: mapValueOfType<String>(json, r'deviceId'),
|
||||
isArchived: mapValueOfType<bool>(json, r'isArchived'),
|
||||
isEncoded: mapValueOfType<bool>(json, r'isEncoded'),
|
||||
isExternal: mapValueOfType<bool>(json, r'isExternal'),
|
||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
|
||||
isMotion: mapValueOfType<bool>(json, r'isMotion'),
|
||||
isOffline: mapValueOfType<bool>(json, r'isOffline'),
|
||||
isReadOnly: mapValueOfType<bool>(json, r'isReadOnly'),
|
||||
isVisible: mapValueOfType<bool>(json, r'isVisible'),
|
||||
lensModel: mapValueOfType<String>(json, r'lensModel'),
|
||||
libraryId: mapValueOfType<String>(json, r'libraryId'),
|
||||
make: mapValueOfType<String>(json, r'make'),
|
||||
model: mapValueOfType<String>(json, r'model'),
|
||||
page: num.parse('${json[r'page']}'),
|
||||
query: mapValueOfType<String>(json, r'query')!,
|
||||
size: num.parse('${json[r'size']}'),
|
||||
state: mapValueOfType<String>(json, r'state'),
|
||||
takenAfter: mapDateTime(json, r'takenAfter', r''),
|
||||
takenBefore: mapDateTime(json, r'takenBefore', r''),
|
||||
trashedAfter: mapDateTime(json, r'trashedAfter', r''),
|
||||
trashedBefore: mapDateTime(json, r'trashedBefore', r''),
|
||||
type: AssetTypeEnum.fromJson(json[r'type']),
|
||||
updatedAfter: mapDateTime(json, r'updatedAfter', r''),
|
||||
updatedBefore: mapDateTime(json, r'updatedBefore', r''),
|
||||
withArchived: mapValueOfType<bool>(json, r'withArchived'),
|
||||
withDeleted: mapValueOfType<bool>(json, r'withDeleted'),
|
||||
withExif: mapValueOfType<bool>(json, r'withExif'),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static List<SmartSearchDto> listFromJson(dynamic json, {bool growable = false,}) {
|
||||
final result = <SmartSearchDto>[];
|
||||
if (json is List && json.isNotEmpty) {
|
||||
for (final row in json) {
|
||||
final value = SmartSearchDto.fromJson(row);
|
||||
if (value != null) {
|
||||
result.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toList(growable: growable);
|
||||
}
|
||||
|
||||
static Map<String, SmartSearchDto> mapFromJson(dynamic json) {
|
||||
final map = <String, SmartSearchDto>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
json = json.cast<String, dynamic>(); // ignore: parameter_assignments
|
||||
for (final entry in json.entries) {
|
||||
final value = SmartSearchDto.fromJson(entry.value);
|
||||
if (value != null) {
|
||||
map[entry.key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
// maps a json object with a list of SmartSearchDto-objects as value to a dart map
|
||||
static Map<String, List<SmartSearchDto>> mapListFromJson(dynamic json, {bool growable = false,}) {
|
||||
final map = <String, List<SmartSearchDto>>{};
|
||||
if (json is Map && json.isNotEmpty) {
|
||||
// ignore: parameter_assignments
|
||||
json = json.cast<String, dynamic>();
|
||||
for (final entry in json.entries) {
|
||||
map[entry.key] = SmartSearchDto.listFromJson(entry.value, growable: growable,);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/// The list of required keys that must be present in a JSON.
|
||||
static const requiredKeys = <String>{
|
||||
'query',
|
||||
};
|
||||
}
|
||||
|
||||
Generated
+2
-2
@@ -80,7 +80,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
//Future<List<MapMarkerResponseDto>> getMapMarkers({ DateTime fileCreatedAfter, DateTime fileCreatedBefore, bool isArchived, bool isFavorite, bool withPartners }) async
|
||||
//Future<List<MapMarkerResponseDto>> getMapMarkers({ DateTime fileCreatedAfter, DateTime fileCreatedBefore, bool isArchived, bool isFavorite }) async
|
||||
test('test getMapMarkers', () async {
|
||||
// TODO
|
||||
});
|
||||
@@ -110,7 +110,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
//Future<List<AssetResponseDto>> searchAssets({ String checksum, String city, String country, DateTime createdAfter, DateTime createdBefore, String deviceAssetId, String deviceId, String encodedVideoPath, String id, bool isArchived, bool isEncoded, bool isExternal, bool isFavorite, bool isMotion, bool isNotInAlbum, bool isOffline, bool isReadOnly, bool isVisible, String lensModel, String libraryId, String make, String model, AssetOrder order, String originalFileName, String originalPath, num page, List<String> personIds, String resizePath, num size, String state, DateTime takenAfter, DateTime takenBefore, DateTime trashedAfter, DateTime trashedBefore, AssetTypeEnum type, DateTime updatedAfter, DateTime updatedBefore, String webpPath, bool withArchived, bool withDeleted, bool withExif, bool withPeople, bool withStacked }) async
|
||||
//Future<List<AssetResponseDto>> searchAssets({ String checksum, String city, String country, DateTime createdAfter, DateTime createdBefore, String deviceAssetId, String deviceId, String encodedVideoPath, String id, bool isArchived, bool isEncoded, bool isExternal, bool isFavorite, bool isMotion, bool isOffline, bool isReadOnly, bool isVisible, String lensModel, String libraryId, String make, String model, AssetOrder order, String originalFileName, String originalPath, num page, String resizePath, num size, String state, DateTime takenAfter, DateTime takenBefore, DateTime trashedAfter, DateTime trashedBefore, AssetTypeEnum type, DateTime updatedAfter, DateTime updatedBefore, String webpPath, bool withArchived, bool withDeleted, bool withExif, bool withPeople, bool withStacked }) async
|
||||
test('test searchAssets', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
-237
@@ -1,237 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// tests for MetadataSearchDto
|
||||
void main() {
|
||||
// final instance = MetadataSearchDto();
|
||||
|
||||
group('test MetadataSearchDto', () {
|
||||
// String checksum
|
||||
test('to test the property `checksum`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String city
|
||||
test('to test the property `city`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String country
|
||||
test('to test the property `country`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime createdAfter
|
||||
test('to test the property `createdAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime createdBefore
|
||||
test('to test the property `createdBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String deviceAssetId
|
||||
test('to test the property `deviceAssetId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String deviceId
|
||||
test('to test the property `deviceId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String encodedVideoPath
|
||||
test('to test the property `encodedVideoPath`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String id
|
||||
test('to test the property `id`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isArchived
|
||||
test('to test the property `isArchived`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isEncoded
|
||||
test('to test the property `isEncoded`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isExternal
|
||||
test('to test the property `isExternal`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isFavorite
|
||||
test('to test the property `isFavorite`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isMotion
|
||||
test('to test the property `isMotion`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isNotInAlbum
|
||||
test('to test the property `isNotInAlbum`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isOffline
|
||||
test('to test the property `isOffline`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isReadOnly
|
||||
test('to test the property `isReadOnly`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isVisible
|
||||
test('to test the property `isVisible`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String lensModel
|
||||
test('to test the property `lensModel`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String libraryId
|
||||
test('to test the property `libraryId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String make
|
||||
test('to test the property `make`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String model
|
||||
test('to test the property `model`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// AssetOrder order
|
||||
test('to test the property `order`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String originalFileName
|
||||
test('to test the property `originalFileName`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String originalPath
|
||||
test('to test the property `originalPath`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// num page
|
||||
test('to test the property `page`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// List<String> personIds (default value: const [])
|
||||
test('to test the property `personIds`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String resizePath
|
||||
test('to test the property `resizePath`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// num size
|
||||
test('to test the property `size`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String state
|
||||
test('to test the property `state`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime takenAfter
|
||||
test('to test the property `takenAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime takenBefore
|
||||
test('to test the property `takenBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime trashedAfter
|
||||
test('to test the property `trashedAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime trashedBefore
|
||||
test('to test the property `trashedBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// AssetTypeEnum type
|
||||
test('to test the property `type`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime updatedAfter
|
||||
test('to test the property `updatedAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime updatedBefore
|
||||
test('to test the property `updatedBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String webpPath
|
||||
test('to test the property `webpPath`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withArchived
|
||||
test('to test the property `withArchived`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withDeleted
|
||||
test('to test the property `withDeleted`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withExif
|
||||
test('to test the property `withExif`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withPeople
|
||||
test('to test the property `withPeople`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withStacked
|
||||
test('to test the property `withStacked`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
Generated
+2
-2
@@ -32,7 +32,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
//Future<SearchResponseDto> searchMetadata(MetadataSearchDto metadataSearchDto) async
|
||||
//Future<SearchResponseDto> searchMetadata({ String checksum, String city, String country, DateTime createdAfter, DateTime createdBefore, String deviceAssetId, String deviceId, String encodedVideoPath, String id, bool isArchived, bool isEncoded, bool isExternal, bool isFavorite, bool isMotion, bool isOffline, bool isReadOnly, bool isVisible, String lensModel, String libraryId, String make, String model, AssetOrder order, String originalFileName, String originalPath, num page, String resizePath, num size, String state, DateTime takenAfter, DateTime takenBefore, DateTime trashedAfter, DateTime trashedBefore, AssetTypeEnum type, DateTime updatedAfter, DateTime updatedBefore, String webpPath, bool withArchived, bool withDeleted, bool withExif, bool withPeople, bool withStacked }) async
|
||||
test('test searchMetadata', () async {
|
||||
// TODO
|
||||
});
|
||||
@@ -42,7 +42,7 @@ void main() {
|
||||
// TODO
|
||||
});
|
||||
|
||||
//Future<SearchResponseDto> searchSmart(SmartSearchDto smartSearchDto) async
|
||||
//Future<SearchResponseDto> searchSmart(String query, { String city, String country, DateTime createdAfter, DateTime createdBefore, String deviceId, bool isArchived, bool isEncoded, bool isExternal, bool isFavorite, bool isMotion, bool isOffline, bool isReadOnly, bool isVisible, String lensModel, String libraryId, String make, String model, num page, num size, String state, DateTime takenAfter, DateTime takenBefore, DateTime trashedAfter, DateTime trashedBefore, AssetTypeEnum type, DateTime updatedAfter, DateTime updatedBefore, bool withArchived, bool withDeleted, bool withExif }) async
|
||||
test('test searchSmart', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
-177
@@ -1,177 +0,0 @@
|
||||
//
|
||||
// AUTO-GENERATED FILE, DO NOT MODIFY!
|
||||
//
|
||||
// @dart=2.12
|
||||
|
||||
// ignore_for_file: unused_element, unused_import
|
||||
// ignore_for_file: always_put_required_named_parameters_first
|
||||
// ignore_for_file: constant_identifier_names
|
||||
// ignore_for_file: lines_longer_than_80_chars
|
||||
|
||||
import 'package:openapi/api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
// tests for SmartSearchDto
|
||||
void main() {
|
||||
// final instance = SmartSearchDto();
|
||||
|
||||
group('test SmartSearchDto', () {
|
||||
// String city
|
||||
test('to test the property `city`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String country
|
||||
test('to test the property `country`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime createdAfter
|
||||
test('to test the property `createdAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime createdBefore
|
||||
test('to test the property `createdBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String deviceId
|
||||
test('to test the property `deviceId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isArchived
|
||||
test('to test the property `isArchived`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isEncoded
|
||||
test('to test the property `isEncoded`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isExternal
|
||||
test('to test the property `isExternal`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isFavorite
|
||||
test('to test the property `isFavorite`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isMotion
|
||||
test('to test the property `isMotion`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isOffline
|
||||
test('to test the property `isOffline`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isReadOnly
|
||||
test('to test the property `isReadOnly`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool isVisible
|
||||
test('to test the property `isVisible`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String lensModel
|
||||
test('to test the property `lensModel`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String libraryId
|
||||
test('to test the property `libraryId`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String make
|
||||
test('to test the property `make`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String model
|
||||
test('to test the property `model`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// num page
|
||||
test('to test the property `page`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String query
|
||||
test('to test the property `query`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// num size
|
||||
test('to test the property `size`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// String state
|
||||
test('to test the property `state`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime takenAfter
|
||||
test('to test the property `takenAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime takenBefore
|
||||
test('to test the property `takenBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime trashedAfter
|
||||
test('to test the property `trashedAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime trashedBefore
|
||||
test('to test the property `trashedBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// AssetTypeEnum type
|
||||
test('to test the property `type`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime updatedAfter
|
||||
test('to test the property `updatedAfter`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// DateTime updatedBefore
|
||||
test('to test the property `updatedBefore`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withArchived
|
||||
test('to test the property `withArchived`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withDeleted
|
||||
test('to test the property `withDeleted`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
// bool withExif
|
||||
test('to test the property `withExif`', () async {
|
||||
// TODO
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
@@ -19,7 +19,7 @@ function dart {
|
||||
function typescript {
|
||||
rm -rf ./typescript-sdk/client
|
||||
npx --yes @openapitools/openapi-generator-cli generate -g typescript-axios -i ./immich-openapi-specs.json -o ./typescript-sdk/axios-client --additional-properties=useSingleRequestParameter=true,supportsES6=true
|
||||
npx --yes oazapfts --optimistic --argumentStyle=object --useEnumType immich-openapi-specs.json typescript-sdk/fetch-client.ts
|
||||
npx --yes oazapfts --optimistic --argumentStyle=object immich-openapi-specs.json typescript-sdk/fetch-client.ts
|
||||
npm --prefix typescript-sdk ci && npm --prefix typescript-sdk run build
|
||||
}
|
||||
|
||||
|
||||
+599
-306
@@ -1397,14 +1397,6 @@
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withPartners",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@@ -2256,14 +2248,6 @@
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isNotInAlbum",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isOffline",
|
||||
"required": false,
|
||||
@@ -2353,17 +2337,6 @@
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "personIds",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "resizePath",
|
||||
"required": false,
|
||||
@@ -4545,21 +4518,350 @@
|
||||
}
|
||||
},
|
||||
"/search/metadata": {
|
||||
"post": {
|
||||
"get": {
|
||||
"operationId": "searchMetadata",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/MetadataSearchDto"
|
||||
}
|
||||
"parameters": [
|
||||
{
|
||||
"name": "checksum",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "city",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "country",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createdAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createdBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "deviceAssetId",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "deviceId",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "encodedVideoPath",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "id",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isArchived",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isEncoded",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isExternal",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isFavorite",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isMotion",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isOffline",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isReadOnly",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isVisible",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lensModel",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "libraryId",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "make",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "order",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetOrder"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "originalFileName",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "originalPath",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "resizePath",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "takenAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "takenBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "trashedAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "trashedBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetTypeEnum"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updatedAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updatedBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "webpPath",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withArchived",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withDeleted",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withExif",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withPeople",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withStacked",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
@@ -4639,21 +4941,269 @@
|
||||
}
|
||||
},
|
||||
"/search/smart": {
|
||||
"post": {
|
||||
"get": {
|
||||
"operationId": "searchSmart",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SmartSearchDto"
|
||||
}
|
||||
"parameters": [
|
||||
{
|
||||
"name": "city",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"name": "country",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createdAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "createdBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "deviceId",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isArchived",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isEncoded",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isExternal",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isFavorite",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isMotion",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isOffline",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isReadOnly",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "isVisible",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lensModel",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "libraryId",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "make",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "model",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "page",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "query",
|
||||
"required": true,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "size",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "state",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "takenAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "takenBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "trashedAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "trashedBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AssetTypeEnum"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updatedAfter",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "updatedBefore",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withArchived",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withDeleted",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "withExif",
|
||||
"required": false,
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
@@ -8247,153 +8797,6 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"MetadataSearchDto": {
|
||||
"properties": {
|
||||
"checksum": {
|
||||
"type": "string"
|
||||
},
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"createdBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"deviceAssetId": {
|
||||
"type": "string"
|
||||
},
|
||||
"deviceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"encodedVideoPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"isArchived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isEncoded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isExternal": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isFavorite": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isMotion": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isNotInAlbum": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isOffline": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isReadOnly": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isVisible": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lensModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"libraryId": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"make": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"order": {
|
||||
"$ref": "#/components/schemas/AssetOrder"
|
||||
},
|
||||
"originalFileName": {
|
||||
"type": "string"
|
||||
},
|
||||
"originalPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"page": {
|
||||
"type": "number"
|
||||
},
|
||||
"personIds": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"resizePath": {
|
||||
"type": "string"
|
||||
},
|
||||
"size": {
|
||||
"type": "number"
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"takenAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"takenBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"trashedAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"trashedBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/components/schemas/AssetTypeEnum"
|
||||
},
|
||||
"updatedAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"webpPath": {
|
||||
"type": "string"
|
||||
},
|
||||
"withArchived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withDeleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withExif": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withPeople": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withStacked": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"ModelType": {
|
||||
"enum": [
|
||||
"facial-recognition",
|
||||
@@ -9349,116 +9752,6 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"SmartSearchDto": {
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": "string"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"createdAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"createdBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"deviceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"isArchived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isEncoded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isExternal": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isFavorite": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isMotion": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isOffline": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isReadOnly": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isVisible": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"lensModel": {
|
||||
"type": "string"
|
||||
},
|
||||
"libraryId": {
|
||||
"format": "uuid",
|
||||
"type": "string"
|
||||
},
|
||||
"make": {
|
||||
"type": "string"
|
||||
},
|
||||
"model": {
|
||||
"type": "string"
|
||||
},
|
||||
"page": {
|
||||
"type": "number"
|
||||
},
|
||||
"query": {
|
||||
"type": "string"
|
||||
},
|
||||
"size": {
|
||||
"type": "number"
|
||||
},
|
||||
"state": {
|
||||
"type": "string"
|
||||
},
|
||||
"takenAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"takenBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"trashedAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"trashedBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"$ref": "#/components/schemas/AssetTypeEnum"
|
||||
},
|
||||
"updatedAfter": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"updatedBefore": {
|
||||
"format": "date-time",
|
||||
"type": "string"
|
||||
},
|
||||
"withArchived": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withDeleted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"withExif": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"query"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SystemConfigDto": {
|
||||
"properties": {
|
||||
"ffmpeg": {
|
||||
|
||||
+984
-543
File diff suppressed because it is too large
Load Diff
Generated
+195
-295
@@ -14,6 +14,9 @@ const oazapfts = Oazapfts.runtime(defaults);
|
||||
export const servers = {
|
||||
server1: "/api"
|
||||
};
|
||||
export type ReactionLevel = "album" | "asset";
|
||||
export type ReactionType = "comment" | "like";
|
||||
export type UserAvatarColor = "primary" | "pink" | "red" | "yellow" | "blue" | "green" | "purple" | "orange" | "gray" | "amber";
|
||||
export type UserDto = {
|
||||
avatarColor: UserAvatarColor;
|
||||
email: string;
|
||||
@@ -26,7 +29,7 @@ export type ActivityResponseDto = {
|
||||
comment?: string | null;
|
||||
createdAt: string;
|
||||
id: string;
|
||||
"type": Type;
|
||||
"type": "comment" | "like";
|
||||
user: UserDto;
|
||||
};
|
||||
export type ActivityCreateDto = {
|
||||
@@ -100,12 +103,14 @@ export type SmartInfoResponseDto = {
|
||||
objects?: string[] | null;
|
||||
tags?: string[] | null;
|
||||
};
|
||||
export type TagTypeEnum = "OBJECT" | "FACE" | "CUSTOM";
|
||||
export type TagResponseDto = {
|
||||
id: string;
|
||||
name: string;
|
||||
"type": TagTypeEnum;
|
||||
userId: string;
|
||||
};
|
||||
export type AssetTypeEnum = "IMAGE" | "VIDEO" | "AUDIO" | "OTHER";
|
||||
export type AssetResponseDto = {
|
||||
/** base64 encoded sha1 hash */
|
||||
checksum: string;
|
||||
@@ -181,7 +186,7 @@ export type BulkIdsDto = {
|
||||
ids: string[];
|
||||
};
|
||||
export type BulkIdResponseDto = {
|
||||
error?: Error;
|
||||
error?: "duplicate" | "no_permission" | "not_found" | "unknown";
|
||||
id: string;
|
||||
success: boolean;
|
||||
};
|
||||
@@ -227,10 +232,10 @@ export type AssetBulkUploadCheckDto = {
|
||||
assets: AssetBulkUploadCheckItem[];
|
||||
};
|
||||
export type AssetBulkUploadCheckResult = {
|
||||
action: Action;
|
||||
action: "accept" | "reject";
|
||||
assetId?: string;
|
||||
id: string;
|
||||
reason?: Reason;
|
||||
reason?: "duplicate" | "unsupported-format";
|
||||
};
|
||||
export type AssetBulkUploadCheckResponseDto = {
|
||||
results: AssetBulkUploadCheckResult[];
|
||||
@@ -256,6 +261,7 @@ export type CheckExistingAssetsDto = {
|
||||
export type CheckExistingAssetsResponseDto = {
|
||||
existingIds: string[];
|
||||
};
|
||||
export type AssetJobName = "regenerate-thumbnail" | "refresh-metadata" | "transcode-video";
|
||||
export type AssetJobsDto = {
|
||||
assetIds: string[];
|
||||
name: AssetJobName;
|
||||
@@ -278,6 +284,8 @@ export type AssetStatsResponseDto = {
|
||||
total: number;
|
||||
videos: number;
|
||||
};
|
||||
export type ThumbnailFormat = "JPEG" | "WEBP";
|
||||
export type TimeBucketSize = "DAY" | "MONTH";
|
||||
export type TimeBucketResponseDto = {
|
||||
count: number;
|
||||
timeBucket: string;
|
||||
@@ -311,10 +319,14 @@ export type UpdateAssetDto = {
|
||||
latitude?: number;
|
||||
longitude?: number;
|
||||
};
|
||||
export type AssetOrder = "asc" | "desc";
|
||||
export type EntityType = "ASSET" | "ALBUM";
|
||||
export type AuditDeletesResponseDto = {
|
||||
ids: string[];
|
||||
needsFullSync: boolean;
|
||||
};
|
||||
export type PathEntityType = "asset" | "person" | "user";
|
||||
export type PathType = "original" | "jpeg_thumbnail" | "webp_thumbnail" | "encoded_video" | "sidecar" | "face" | "profile";
|
||||
export type FileReportItemDto = {
|
||||
checksum?: string;
|
||||
entityId: string;
|
||||
@@ -440,10 +452,13 @@ export type AllJobStatusResponseDto = {
|
||||
thumbnailGeneration: JobStatusDto;
|
||||
videoConversion: JobStatusDto;
|
||||
};
|
||||
export type JobName = "thumbnailGeneration" | "metadataExtraction" | "videoConversion" | "faceDetection" | "facialRecognition" | "smartSearch" | "backgroundTask" | "storageTemplateMigration" | "migration" | "search" | "sidecar" | "library";
|
||||
export type JobCommand = "start" | "pause" | "resume" | "empty" | "clear-failed";
|
||||
export type JobCommandDto = {
|
||||
command: JobCommand;
|
||||
force: boolean;
|
||||
};
|
||||
export type LibraryType = "UPLOAD" | "EXTERNAL";
|
||||
export type LibraryResponseDto = {
|
||||
assetCount: number;
|
||||
createdAt: string;
|
||||
@@ -588,84 +603,7 @@ export type SearchExploreResponseDto = {
|
||||
fieldName: string;
|
||||
items: SearchExploreItem[];
|
||||
};
|
||||
export type MetadataSearchDto = {
|
||||
checksum?: string;
|
||||
city?: string;
|
||||
country?: string;
|
||||
createdAfter?: string;
|
||||
createdBefore?: string;
|
||||
deviceAssetId?: string;
|
||||
deviceId?: string;
|
||||
encodedVideoPath?: string;
|
||||
id?: string;
|
||||
isArchived?: boolean;
|
||||
isEncoded?: boolean;
|
||||
isExternal?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isMotion?: boolean;
|
||||
isNotInAlbum?: boolean;
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
lensModel?: string;
|
||||
libraryId?: string;
|
||||
make?: string;
|
||||
model?: string;
|
||||
order?: AssetOrder;
|
||||
originalFileName?: string;
|
||||
originalPath?: string;
|
||||
page?: number;
|
||||
personIds?: string[];
|
||||
resizePath?: string;
|
||||
size?: number;
|
||||
state?: string;
|
||||
takenAfter?: string;
|
||||
takenBefore?: string;
|
||||
trashedAfter?: string;
|
||||
trashedBefore?: string;
|
||||
"type"?: AssetTypeEnum;
|
||||
updatedAfter?: string;
|
||||
updatedBefore?: string;
|
||||
webpPath?: string;
|
||||
withArchived?: boolean;
|
||||
withDeleted?: boolean;
|
||||
withExif?: boolean;
|
||||
withPeople?: boolean;
|
||||
withStacked?: boolean;
|
||||
};
|
||||
export type SmartSearchDto = {
|
||||
city?: string;
|
||||
country?: string;
|
||||
createdAfter?: string;
|
||||
createdBefore?: string;
|
||||
deviceId?: string;
|
||||
isArchived?: boolean;
|
||||
isEncoded?: boolean;
|
||||
isExternal?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isMotion?: boolean;
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
lensModel?: string;
|
||||
libraryId?: string;
|
||||
make?: string;
|
||||
model?: string;
|
||||
page?: number;
|
||||
query: string;
|
||||
size?: number;
|
||||
state?: string;
|
||||
takenAfter?: string;
|
||||
takenBefore?: string;
|
||||
trashedAfter?: string;
|
||||
trashedBefore?: string;
|
||||
"type"?: AssetTypeEnum;
|
||||
updatedAfter?: string;
|
||||
updatedBefore?: string;
|
||||
withArchived?: boolean;
|
||||
withDeleted?: boolean;
|
||||
withExif?: boolean;
|
||||
};
|
||||
export type SearchSuggestionType = "country" | "state" | "city" | "camera-make" | "camera-model";
|
||||
export type ServerInfoResponseDto = {
|
||||
diskAvailable: string;
|
||||
diskAvailableRaw: number;
|
||||
@@ -727,6 +665,7 @@ export type ServerVersionResponseDto = {
|
||||
minor: number;
|
||||
patch: number;
|
||||
};
|
||||
export type SharedLinkType = "ALBUM" | "INDIVIDUAL";
|
||||
export type SharedLinkResponseDto = {
|
||||
album?: AlbumResponseDto;
|
||||
allowDownload: boolean;
|
||||
@@ -768,15 +707,21 @@ export type SharedLinkEditDto = {
|
||||
};
|
||||
export type AssetIdsResponseDto = {
|
||||
assetId: string;
|
||||
error?: Error2;
|
||||
error?: "duplicate" | "no_permission" | "not_found";
|
||||
success: boolean;
|
||||
};
|
||||
export type TranscodeHwAccel = "nvenc" | "qsv" | "vaapi" | "rkmpp" | "disabled";
|
||||
export type AudioCodec = "mp3" | "aac" | "libopus";
|
||||
export type VideoCodec = "h264" | "hevc" | "vp9";
|
||||
export type CqMode = "auto" | "cqp" | "icq";
|
||||
export type ToneMapping = "hable" | "mobius" | "reinhard" | "disabled";
|
||||
export type TranscodePolicy = "all" | "optimal" | "bitrate" | "required" | "disabled";
|
||||
export type SystemConfigFFmpegDto = {
|
||||
accel: TranscodeHWAccel;
|
||||
accel: TranscodeHwAccel;
|
||||
acceptedAudioCodecs: AudioCodec[];
|
||||
acceptedVideoCodecs: VideoCodec[];
|
||||
bframes: number;
|
||||
cqMode: CQMode;
|
||||
cqMode: CqMode;
|
||||
crf: number;
|
||||
gopSize: number;
|
||||
maxBitrate: string;
|
||||
@@ -821,13 +766,16 @@ export type SystemConfigLibraryDto = {
|
||||
scan: SystemConfigLibraryScanDto;
|
||||
watch: SystemConfigLibraryWatchDto;
|
||||
};
|
||||
export type LogLevel = "verbose" | "debug" | "log" | "warn" | "error" | "fatal";
|
||||
export type SystemConfigLoggingDto = {
|
||||
enabled: boolean;
|
||||
level: LogLevel;
|
||||
};
|
||||
export type ClipMode = "vision" | "text";
|
||||
export type ModelType = "facial-recognition" | "clip";
|
||||
export type ClipConfig = {
|
||||
enabled: boolean;
|
||||
mode?: CLIPMode;
|
||||
mode?: ClipMode;
|
||||
modelName: string;
|
||||
modelType?: ModelType;
|
||||
};
|
||||
@@ -885,6 +833,7 @@ export type SystemConfigStorageTemplateDto = {
|
||||
export type SystemConfigThemeDto = {
|
||||
customCss: string;
|
||||
};
|
||||
export type Colorspace = "srgb" | "p3";
|
||||
export type SystemConfigThumbnailDto = {
|
||||
colorspace: Colorspace;
|
||||
jpegSize: number;
|
||||
@@ -912,6 +861,7 @@ export type SystemConfigDto = {
|
||||
thumbnail: SystemConfigThumbnailDto;
|
||||
trash: SystemConfigTrashDto;
|
||||
};
|
||||
export type MapTheme = "light" | "dark";
|
||||
export type SystemConfigTemplateStorageOptionDto = {
|
||||
dayOptions: string[];
|
||||
hourOptions: string[];
|
||||
@@ -1318,12 +1268,11 @@ export function runAssetJobs({ assetJobsDto }: {
|
||||
body: assetJobsDto
|
||||
})));
|
||||
}
|
||||
export function getMapMarkers({ fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite, withPartners }: {
|
||||
export function getMapMarkers({ fileCreatedAfter, fileCreatedBefore, isArchived, isFavorite }: {
|
||||
fileCreatedAfter?: string;
|
||||
fileCreatedBefore?: string;
|
||||
isArchived?: boolean;
|
||||
isFavorite?: boolean;
|
||||
withPartners?: boolean;
|
||||
}, opts?: Oazapfts.RequestOpts) {
|
||||
return oazapfts.ok(oazapfts.fetchJson<{
|
||||
status: 200;
|
||||
@@ -1332,8 +1281,7 @@ export function getMapMarkers({ fileCreatedAfter, fileCreatedBefore, isArchived,
|
||||
fileCreatedAfter,
|
||||
fileCreatedBefore,
|
||||
isArchived,
|
||||
isFavorite,
|
||||
withPartners
|
||||
isFavorite
|
||||
}))}`, {
|
||||
...opts
|
||||
}));
|
||||
@@ -1515,7 +1463,7 @@ export function updateAsset({ id, updateAssetDto }: {
|
||||
body: updateAssetDto
|
||||
})));
|
||||
}
|
||||
export function searchAssets({ checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isNotInAlbum, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, personIds, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked }: {
|
||||
export function searchAssets({ checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked }: {
|
||||
checksum?: string;
|
||||
city?: string;
|
||||
country?: string;
|
||||
@@ -1530,7 +1478,6 @@ export function searchAssets({ checksum, city, country, createdAfter, createdBef
|
||||
isExternal?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isMotion?: boolean;
|
||||
isNotInAlbum?: boolean;
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
@@ -1542,7 +1489,6 @@ export function searchAssets({ checksum, city, country, createdAfter, createdBef
|
||||
originalFileName?: string;
|
||||
originalPath?: string;
|
||||
page?: number;
|
||||
personIds?: string[];
|
||||
resizePath?: string;
|
||||
size?: number;
|
||||
state?: string;
|
||||
@@ -1578,7 +1524,6 @@ export function searchAssets({ checksum, city, country, createdAfter, createdBef
|
||||
isExternal,
|
||||
isFavorite,
|
||||
isMotion,
|
||||
isNotInAlbum,
|
||||
isOffline,
|
||||
isReadOnly,
|
||||
isVisible,
|
||||
@@ -1590,7 +1535,6 @@ export function searchAssets({ checksum, city, country, createdAfter, createdBef
|
||||
originalFileName,
|
||||
originalPath,
|
||||
page,
|
||||
personIds,
|
||||
resizePath,
|
||||
size,
|
||||
state,
|
||||
@@ -2145,17 +2089,97 @@ export function getExploreData(opts?: Oazapfts.RequestOpts) {
|
||||
...opts
|
||||
}));
|
||||
}
|
||||
export function searchMetadata({ metadataSearchDto }: {
|
||||
metadataSearchDto: MetadataSearchDto;
|
||||
export function searchMetadata({ checksum, city, country, createdAfter, createdBefore, deviceAssetId, deviceId, encodedVideoPath, id, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, order, originalFileName, originalPath, page, resizePath, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, webpPath, withArchived, withDeleted, withExif, withPeople, withStacked }: {
|
||||
checksum?: string;
|
||||
city?: string;
|
||||
country?: string;
|
||||
createdAfter?: string;
|
||||
createdBefore?: string;
|
||||
deviceAssetId?: string;
|
||||
deviceId?: string;
|
||||
encodedVideoPath?: string;
|
||||
id?: string;
|
||||
isArchived?: boolean;
|
||||
isEncoded?: boolean;
|
||||
isExternal?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isMotion?: boolean;
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
lensModel?: string;
|
||||
libraryId?: string;
|
||||
make?: string;
|
||||
model?: string;
|
||||
order?: AssetOrder;
|
||||
originalFileName?: string;
|
||||
originalPath?: string;
|
||||
page?: number;
|
||||
resizePath?: string;
|
||||
size?: number;
|
||||
state?: string;
|
||||
takenAfter?: string;
|
||||
takenBefore?: string;
|
||||
trashedAfter?: string;
|
||||
trashedBefore?: string;
|
||||
$type?: AssetTypeEnum;
|
||||
updatedAfter?: string;
|
||||
updatedBefore?: string;
|
||||
webpPath?: string;
|
||||
withArchived?: boolean;
|
||||
withDeleted?: boolean;
|
||||
withExif?: boolean;
|
||||
withPeople?: boolean;
|
||||
withStacked?: boolean;
|
||||
}, opts?: Oazapfts.RequestOpts) {
|
||||
return oazapfts.ok(oazapfts.fetchJson<{
|
||||
status: 201;
|
||||
status: 200;
|
||||
data: SearchResponseDto;
|
||||
}>("/search/metadata", oazapfts.json({
|
||||
...opts,
|
||||
method: "POST",
|
||||
body: metadataSearchDto
|
||||
})));
|
||||
}>(`/search/metadata${QS.query(QS.explode({
|
||||
checksum,
|
||||
city,
|
||||
country,
|
||||
createdAfter,
|
||||
createdBefore,
|
||||
deviceAssetId,
|
||||
deviceId,
|
||||
encodedVideoPath,
|
||||
id,
|
||||
isArchived,
|
||||
isEncoded,
|
||||
isExternal,
|
||||
isFavorite,
|
||||
isMotion,
|
||||
isOffline,
|
||||
isReadOnly,
|
||||
isVisible,
|
||||
lensModel,
|
||||
libraryId,
|
||||
make,
|
||||
model,
|
||||
order,
|
||||
originalFileName,
|
||||
originalPath,
|
||||
page,
|
||||
resizePath,
|
||||
size,
|
||||
state,
|
||||
takenAfter,
|
||||
takenBefore,
|
||||
trashedAfter,
|
||||
trashedBefore,
|
||||
"type": $type,
|
||||
updatedAfter,
|
||||
updatedBefore,
|
||||
webpPath,
|
||||
withArchived,
|
||||
withDeleted,
|
||||
withExif,
|
||||
withPeople,
|
||||
withStacked
|
||||
}))}`, {
|
||||
...opts
|
||||
}));
|
||||
}
|
||||
export function searchPerson({ name, withHidden }: {
|
||||
name: string;
|
||||
@@ -2171,17 +2195,77 @@ export function searchPerson({ name, withHidden }: {
|
||||
...opts
|
||||
}));
|
||||
}
|
||||
export function searchSmart({ smartSearchDto }: {
|
||||
smartSearchDto: SmartSearchDto;
|
||||
export function searchSmart({ city, country, createdAfter, createdBefore, deviceId, isArchived, isEncoded, isExternal, isFavorite, isMotion, isOffline, isReadOnly, isVisible, lensModel, libraryId, make, model, page, query, size, state, takenAfter, takenBefore, trashedAfter, trashedBefore, $type, updatedAfter, updatedBefore, withArchived, withDeleted, withExif }: {
|
||||
city?: string;
|
||||
country?: string;
|
||||
createdAfter?: string;
|
||||
createdBefore?: string;
|
||||
deviceId?: string;
|
||||
isArchived?: boolean;
|
||||
isEncoded?: boolean;
|
||||
isExternal?: boolean;
|
||||
isFavorite?: boolean;
|
||||
isMotion?: boolean;
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
lensModel?: string;
|
||||
libraryId?: string;
|
||||
make?: string;
|
||||
model?: string;
|
||||
page?: number;
|
||||
query: string;
|
||||
size?: number;
|
||||
state?: string;
|
||||
takenAfter?: string;
|
||||
takenBefore?: string;
|
||||
trashedAfter?: string;
|
||||
trashedBefore?: string;
|
||||
$type?: AssetTypeEnum;
|
||||
updatedAfter?: string;
|
||||
updatedBefore?: string;
|
||||
withArchived?: boolean;
|
||||
withDeleted?: boolean;
|
||||
withExif?: boolean;
|
||||
}, opts?: Oazapfts.RequestOpts) {
|
||||
return oazapfts.ok(oazapfts.fetchJson<{
|
||||
status: 201;
|
||||
status: 200;
|
||||
data: SearchResponseDto;
|
||||
}>("/search/smart", oazapfts.json({
|
||||
...opts,
|
||||
method: "POST",
|
||||
body: smartSearchDto
|
||||
})));
|
||||
}>(`/search/smart${QS.query(QS.explode({
|
||||
city,
|
||||
country,
|
||||
createdAfter,
|
||||
createdBefore,
|
||||
deviceId,
|
||||
isArchived,
|
||||
isEncoded,
|
||||
isExternal,
|
||||
isFavorite,
|
||||
isMotion,
|
||||
isOffline,
|
||||
isReadOnly,
|
||||
isVisible,
|
||||
lensModel,
|
||||
libraryId,
|
||||
make,
|
||||
model,
|
||||
page,
|
||||
query,
|
||||
size,
|
||||
state,
|
||||
takenAfter,
|
||||
takenBefore,
|
||||
trashedAfter,
|
||||
trashedBefore,
|
||||
"type": $type,
|
||||
updatedAfter,
|
||||
updatedBefore,
|
||||
withArchived,
|
||||
withDeleted,
|
||||
withExif
|
||||
}))}`, {
|
||||
...opts
|
||||
}));
|
||||
}
|
||||
export function getSearchSuggestions({ country, make, model, state, $type }: {
|
||||
country?: string;
|
||||
@@ -2632,187 +2716,3 @@ export function restoreUser({ id }: {
|
||||
method: "POST"
|
||||
}));
|
||||
}
|
||||
export enum ReactionLevel {
|
||||
Album = "album",
|
||||
Asset = "asset"
|
||||
}
|
||||
export enum ReactionType {
|
||||
Comment = "comment",
|
||||
Like = "like"
|
||||
}
|
||||
export enum Type {
|
||||
Comment = "comment",
|
||||
Like = "like"
|
||||
}
|
||||
export enum UserAvatarColor {
|
||||
Primary = "primary",
|
||||
Pink = "pink",
|
||||
Red = "red",
|
||||
Yellow = "yellow",
|
||||
Blue = "blue",
|
||||
Green = "green",
|
||||
Purple = "purple",
|
||||
Orange = "orange",
|
||||
Gray = "gray",
|
||||
Amber = "amber"
|
||||
}
|
||||
export enum TagTypeEnum {
|
||||
Object = "OBJECT",
|
||||
Face = "FACE",
|
||||
Custom = "CUSTOM"
|
||||
}
|
||||
export enum AssetTypeEnum {
|
||||
Image = "IMAGE",
|
||||
Video = "VIDEO",
|
||||
Audio = "AUDIO",
|
||||
Other = "OTHER"
|
||||
}
|
||||
export enum Error {
|
||||
Duplicate = "duplicate",
|
||||
NoPermission = "no_permission",
|
||||
NotFound = "not_found",
|
||||
Unknown = "unknown"
|
||||
}
|
||||
export enum Action {
|
||||
Accept = "accept",
|
||||
Reject = "reject"
|
||||
}
|
||||
export enum Reason {
|
||||
Duplicate = "duplicate",
|
||||
UnsupportedFormat = "unsupported-format"
|
||||
}
|
||||
export enum AssetJobName {
|
||||
RegenerateThumbnail = "regenerate-thumbnail",
|
||||
RefreshMetadata = "refresh-metadata",
|
||||
TranscodeVideo = "transcode-video"
|
||||
}
|
||||
export enum ThumbnailFormat {
|
||||
Jpeg = "JPEG",
|
||||
Webp = "WEBP"
|
||||
}
|
||||
export enum TimeBucketSize {
|
||||
Day = "DAY",
|
||||
Month = "MONTH"
|
||||
}
|
||||
export enum AssetOrder {
|
||||
Asc = "asc",
|
||||
Desc = "desc"
|
||||
}
|
||||
export enum EntityType {
|
||||
Asset = "ASSET",
|
||||
Album = "ALBUM"
|
||||
}
|
||||
export enum PathEntityType {
|
||||
Asset = "asset",
|
||||
Person = "person",
|
||||
User = "user"
|
||||
}
|
||||
export enum PathType {
|
||||
Original = "original",
|
||||
JpegThumbnail = "jpeg_thumbnail",
|
||||
WebpThumbnail = "webp_thumbnail",
|
||||
EncodedVideo = "encoded_video",
|
||||
Sidecar = "sidecar",
|
||||
Face = "face",
|
||||
Profile = "profile"
|
||||
}
|
||||
export enum JobName {
|
||||
ThumbnailGeneration = "thumbnailGeneration",
|
||||
MetadataExtraction = "metadataExtraction",
|
||||
VideoConversion = "videoConversion",
|
||||
FaceDetection = "faceDetection",
|
||||
FacialRecognition = "facialRecognition",
|
||||
SmartSearch = "smartSearch",
|
||||
BackgroundTask = "backgroundTask",
|
||||
StorageTemplateMigration = "storageTemplateMigration",
|
||||
Migration = "migration",
|
||||
Search = "search",
|
||||
Sidecar = "sidecar",
|
||||
Library = "library"
|
||||
}
|
||||
export enum JobCommand {
|
||||
Start = "start",
|
||||
Pause = "pause",
|
||||
Resume = "resume",
|
||||
Empty = "empty",
|
||||
ClearFailed = "clear-failed"
|
||||
}
|
||||
export enum LibraryType {
|
||||
Upload = "UPLOAD",
|
||||
External = "EXTERNAL"
|
||||
}
|
||||
export enum SearchSuggestionType {
|
||||
Country = "country",
|
||||
State = "state",
|
||||
City = "city",
|
||||
CameraMake = "camera-make",
|
||||
CameraModel = "camera-model"
|
||||
}
|
||||
export enum SharedLinkType {
|
||||
Album = "ALBUM",
|
||||
Individual = "INDIVIDUAL"
|
||||
}
|
||||
export enum Error2 {
|
||||
Duplicate = "duplicate",
|
||||
NoPermission = "no_permission",
|
||||
NotFound = "not_found"
|
||||
}
|
||||
export enum TranscodeHWAccel {
|
||||
Nvenc = "nvenc",
|
||||
Qsv = "qsv",
|
||||
Vaapi = "vaapi",
|
||||
Rkmpp = "rkmpp",
|
||||
Disabled = "disabled"
|
||||
}
|
||||
export enum AudioCodec {
|
||||
Mp3 = "mp3",
|
||||
Aac = "aac",
|
||||
Libopus = "libopus"
|
||||
}
|
||||
export enum VideoCodec {
|
||||
H264 = "h264",
|
||||
Hevc = "hevc",
|
||||
Vp9 = "vp9"
|
||||
}
|
||||
export enum CQMode {
|
||||
Auto = "auto",
|
||||
Cqp = "cqp",
|
||||
Icq = "icq"
|
||||
}
|
||||
export enum ToneMapping {
|
||||
Hable = "hable",
|
||||
Mobius = "mobius",
|
||||
Reinhard = "reinhard",
|
||||
Disabled = "disabled"
|
||||
}
|
||||
export enum TranscodePolicy {
|
||||
All = "all",
|
||||
Optimal = "optimal",
|
||||
Bitrate = "bitrate",
|
||||
Required = "required",
|
||||
Disabled = "disabled"
|
||||
}
|
||||
export enum LogLevel {
|
||||
Verbose = "verbose",
|
||||
Debug = "debug",
|
||||
Log = "log",
|
||||
Warn = "warn",
|
||||
Error = "error",
|
||||
Fatal = "fatal"
|
||||
}
|
||||
export enum CLIPMode {
|
||||
Vision = "vision",
|
||||
Text = "text"
|
||||
}
|
||||
export enum ModelType {
|
||||
FacialRecognition = "facial-recognition",
|
||||
Clip = "clip"
|
||||
}
|
||||
export enum Colorspace {
|
||||
Srgb = "srgb",
|
||||
P3 = "p3"
|
||||
}
|
||||
export enum MapTheme {
|
||||
Light = "light",
|
||||
Dark = "dark"
|
||||
}
|
||||
|
||||
+3
-3
@@ -29,9 +29,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.11.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz",
|
||||
"integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==",
|
||||
"version": "20.11.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz",
|
||||
"integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"include": ["fetch.ts", "fetch-client.ts"],
|
||||
"include": ["fetch.ts"],
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"strict": true,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AssetBulkDeleteDto, AssetResponseDto } from '@app/domain';
|
||||
import { AssetResponseDto } from '@app/domain';
|
||||
import { CreateAssetDto } from '@app/immich/api-v1/asset/dto/create-asset.dto';
|
||||
import { AssetFileUploadResponseDto } from '@app/immich/api-v1/asset/response-dto/asset-file-upload-response.dto';
|
||||
import { randomBytes } from 'node:crypto';
|
||||
@@ -74,8 +74,4 @@ export const assetApi = {
|
||||
expect(status).toBe(200);
|
||||
return body;
|
||||
},
|
||||
delete: async (server: any, accessToken: string, dto: AssetBulkDeleteDto) => {
|
||||
const { status } = await request(server).delete('/asset').set('Authorization', `Bearer ${accessToken}`).send(dto);
|
||||
expect(status).toBe(204);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ import { libraryApi } from './library-api';
|
||||
import { partnerApi } from './partner-api';
|
||||
import { serverInfoApi } from './server-info-api';
|
||||
import { sharedLinkApi } from './shared-link-api';
|
||||
import { trashApi } from './trash-api';
|
||||
import { userApi } from './user-api';
|
||||
|
||||
export const api = {
|
||||
@@ -18,7 +17,6 @@ export const api = {
|
||||
libraryApi,
|
||||
serverInfoApi,
|
||||
sharedLinkApi,
|
||||
trashApi,
|
||||
albumApi,
|
||||
userApi,
|
||||
partnerApi,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import request from 'supertest';
|
||||
import type { App } from 'supertest/types';
|
||||
|
||||
export const trashApi = {
|
||||
async empty(server: App, accessToken: string) {
|
||||
const { status } = await request(server).post('/trash/empty').set('Authorization', `Bearer ${accessToken}`);
|
||||
expect(status).toBe(204);
|
||||
},
|
||||
async restore(server: App, accessToken: string) {
|
||||
const { status } = await request(server).post('/trash/restore').set('Authorization', `Bearer ${accessToken}`);
|
||||
expect(status).toBe(204);
|
||||
},
|
||||
};
|
||||
@@ -1,80 +0,0 @@
|
||||
import { LoginResponseDto } from '@app/domain';
|
||||
import { api } from 'e2e/client';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { basename, join } from 'node:path';
|
||||
import type { App } from 'supertest/types';
|
||||
import { IMMICH_TEST_ASSET_PATH, testApp } from '../../../src/test-utils/utils';
|
||||
|
||||
const assetFilePath = join(IMMICH_TEST_ASSET_PATH, 'formats/png/density_plot.png');
|
||||
|
||||
describe(`Trash (e2e)`, () => {
|
||||
let server: App;
|
||||
let admin: LoginResponseDto;
|
||||
|
||||
beforeAll(async () => {
|
||||
const app = await testApp.create();
|
||||
server = app.getHttpServer();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await testApp.reset();
|
||||
await api.authApi.adminSignUp(server);
|
||||
admin = await api.authApi.adminLogin(server);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await testApp.teardown();
|
||||
});
|
||||
|
||||
it('should move an asset to trash', async () => {
|
||||
const content = await readFile(assetFilePath);
|
||||
const { id: assetId } = await api.assetApi.upload(server, admin.accessToken, 'test-device-id', {
|
||||
content,
|
||||
filename: basename(assetFilePath),
|
||||
});
|
||||
|
||||
const uploadedAsset = await api.assetApi.get(server, admin.accessToken, assetId);
|
||||
expect(uploadedAsset.isTrashed).toBe(false);
|
||||
|
||||
await api.assetApi.delete(server, admin.accessToken, { ids: [assetId] });
|
||||
|
||||
const deletedAsset = await api.assetApi.get(server, admin.accessToken, assetId);
|
||||
expect(deletedAsset.isTrashed).toBe(true);
|
||||
});
|
||||
|
||||
it('should delete all trashed assets', async () => {
|
||||
const content = await readFile(assetFilePath);
|
||||
const { id: assetId } = await api.assetApi.upload(server, admin.accessToken, 'test-device-id', {
|
||||
content,
|
||||
filename: basename(assetFilePath),
|
||||
});
|
||||
|
||||
await api.assetApi.delete(server, admin.accessToken, { ids: [assetId] });
|
||||
|
||||
const assetsBeforeEmpty = await api.assetApi.getAllAssets(server, admin.accessToken);
|
||||
expect(assetsBeforeEmpty.length).toBe(1);
|
||||
|
||||
await api.trashApi.empty(server, admin.accessToken);
|
||||
|
||||
const assetsAfterEmpty = await api.assetApi.getAllAssets(server, admin.accessToken);
|
||||
expect(assetsAfterEmpty.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should restore all trashed assets', async () => {
|
||||
const content = await readFile(assetFilePath);
|
||||
const { id: assetId } = await api.assetApi.upload(server, admin.accessToken, 'test-device-id', {
|
||||
content,
|
||||
filename: basename(assetFilePath),
|
||||
});
|
||||
|
||||
await api.assetApi.delete(server, admin.accessToken, { ids: [assetId] });
|
||||
|
||||
const deletedAsset = await api.assetApi.get(server, admin.accessToken, assetId);
|
||||
expect(deletedAsset.isTrashed).toBe(true);
|
||||
|
||||
await api.trashApi.restore(server, admin.accessToken);
|
||||
|
||||
const restoredAsset = await api.assetApi.get(server, admin.accessToken, assetId);
|
||||
expect(restoredAsset.isTrashed).toBe(false);
|
||||
});
|
||||
});
|
||||
Generated
+9
-2802
File diff suppressed because it is too large
Load Diff
@@ -34,8 +34,6 @@
|
||||
"sql:generate": "node ./dist/infra/sql-generator/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.515.0",
|
||||
"@aws-sdk/lib-storage": "^3.515.0",
|
||||
"@babel/runtime": "^7.22.11",
|
||||
"@immich/cli": "^2.0.7",
|
||||
"@nestjs/bullmq": "^10.0.1",
|
||||
|
||||
@@ -286,7 +286,6 @@ describe(AssetService.name, () => {
|
||||
|
||||
describe('getMapMarkers', () => {
|
||||
it('should get geo information of assets', async () => {
|
||||
partnerMock.getAll.mockResolvedValue([]);
|
||||
assetMock.getMapMarkers.mockResolvedValue(
|
||||
[assetStub.withLocation].map((asset) => ({
|
||||
id: asset.id,
|
||||
|
||||
@@ -157,16 +157,8 @@ export class AssetService {
|
||||
return folder;
|
||||
}
|
||||
|
||||
async getMapMarkers(auth: AuthDto, options: MapMarkerDto): Promise<MapMarkerResponseDto[]> {
|
||||
const userIds: string[] = [auth.user.id];
|
||||
if (options.withPartners) {
|
||||
const partners = await this.partnerRepository.getAll(auth.user.id);
|
||||
const partnersIds = partners
|
||||
.filter((partner) => partner.sharedBy && partner.sharedWith && partner.sharedById != auth.user.id)
|
||||
.map((partner) => partner.sharedById);
|
||||
userIds.push(...partnersIds);
|
||||
}
|
||||
return this.assetRepository.getMapMarkers(userIds, options);
|
||||
getMapMarkers(auth: AuthDto, options: MapMarkerDto): Promise<MapMarkerResponseDto[]> {
|
||||
return this.assetRepository.getMapMarkers(auth.user.id, options);
|
||||
}
|
||||
|
||||
async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise<MemoryLaneResponseDto[]> {
|
||||
|
||||
@@ -25,10 +25,4 @@ export class MapMarkerDto {
|
||||
@IsDate()
|
||||
@Type(() => Date)
|
||||
fileCreatedBefore?: Date;
|
||||
|
||||
@ApiProperty()
|
||||
@Optional()
|
||||
@IsBoolean()
|
||||
@Transform(toBoolean)
|
||||
withPartners?: boolean;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { Readable, Writable } from "node:stream";
|
||||
|
||||
export interface FS {
|
||||
// create creates an object with the given name.
|
||||
create(name: string): Promise<Writable>;
|
||||
|
||||
// open opens the named object.
|
||||
open(name: string): Promise<Readable>;
|
||||
|
||||
// remove removes the named object.
|
||||
remove(name: string): Promise<void>;
|
||||
}
|
||||
|
||||
// export interface FS {
|
||||
// // create creates an object with the given name.
|
||||
// create(name: string): Promise<WritableFile>;
|
||||
|
||||
// // open opens the object with the given name.
|
||||
// open(name: string): Promise<ReadableFile>;
|
||||
|
||||
// // remove removes the named object.
|
||||
// remove(name: string): Promise<void>;
|
||||
// }
|
||||
|
||||
// export interface File {
|
||||
// createReadableStream(): Promise<Readable>;
|
||||
// }
|
||||
@@ -1,21 +0,0 @@
|
||||
import { constants, open, unlink } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { Readable, Writable } from "node:stream";
|
||||
|
||||
export class LocalFS {
|
||||
constructor(private dir: string) { }
|
||||
|
||||
async create(name: string): Promise<Writable> {
|
||||
const file = await open(join(this.dir, name), constants.O_WRONLY);
|
||||
return file.createWriteStream();
|
||||
}
|
||||
|
||||
async open(name: string): Promise<Readable> {
|
||||
const file = await open(join(this.dir, name), constants.O_RDONLY);
|
||||
return file.createReadStream();
|
||||
}
|
||||
|
||||
async remove(name: string): Promise<void> {
|
||||
await unlink(join(this.dir, name));
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
import { PassThrough, Readable, Writable } from "node:stream";
|
||||
import { S3 } from "@aws-sdk/client-s3";
|
||||
import { FS } from "./fs";
|
||||
import { Upload } from "@aws-sdk/lib-storage";
|
||||
|
||||
export class S3FS implements FS {
|
||||
s3: S3;
|
||||
|
||||
constructor(private bucket: string) {
|
||||
this.s3 = new S3();
|
||||
}
|
||||
|
||||
async create(name: string): Promise<Writable> {
|
||||
const stream = new PassThrough();
|
||||
const upload = new Upload({
|
||||
client: this.s3,
|
||||
params: {
|
||||
Body: stream,
|
||||
Bucket: this.bucket,
|
||||
Key: name,
|
||||
},
|
||||
});
|
||||
|
||||
// Abort the upload if the stream has finished. Should be a
|
||||
// no-op if the upload has already finished.
|
||||
stream.on('close', () => upload.abort());
|
||||
|
||||
// Close the stream when the upload is finished, or if it
|
||||
// failed.
|
||||
//
|
||||
// TODO: Find a way to bubble up this error.
|
||||
upload.done().then(() => void stream.end(), error => {
|
||||
console.log(`s3 upload failed: ${error}`);
|
||||
stream.end();
|
||||
});
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
async open(name: string): Promise<Readable> {
|
||||
const obj = await this.s3.getObject({
|
||||
Bucket: this.bucket,
|
||||
Key: name,
|
||||
});
|
||||
return obj.Body as Readable;
|
||||
// const stream = obj.Body?.transformToWebStream();
|
||||
// if (!stream) {
|
||||
// throw new Error("no body");
|
||||
// }
|
||||
// return Readable.fromWeb(new ReadableStream(stream));
|
||||
}
|
||||
|
||||
async remove(name: string): Promise<void> {
|
||||
await this.s3.deleteObject({
|
||||
Bucket: this.bucket,
|
||||
Key: name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// class ObjectReadable extends Readable {
|
||||
// constructor(private s3: S3, private bucket: string) { }
|
||||
|
||||
|
||||
// }
|
||||
@@ -704,35 +704,8 @@ describe(MediaService.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should copy video stream when video matches target', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);
|
||||
configMock.load.mockResolvedValue([{ key: SystemConfigKey.FFMPEG_TARGET_VIDEO_CODEC, value: VideoCodec.HEVC }]);
|
||||
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mediaMock.transcode).toHaveBeenCalledWith(
|
||||
'/original/path.ext',
|
||||
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||
{
|
||||
inputOptions: [],
|
||||
outputOptions: [
|
||||
'-c:v copy',
|
||||
'-c:a aac',
|
||||
'-movflags faststart',
|
||||
'-fps_mode passthrough',
|
||||
'-map 0:0',
|
||||
'-map 0:1',
|
||||
'-tag:v hvc1',
|
||||
'-v verbose',
|
||||
'-preset ultrafast',
|
||||
'-crf 23',
|
||||
],
|
||||
twoPass: false,
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('should copy audio stream when audio matches target', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.audioStreamAac);
|
||||
it('should transcode when audio doesnt match target', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.audioStreamMp3);
|
||||
configMock.load.mockResolvedValue([{ key: SystemConfigKey.FFMPEG_TRANSCODE, value: TranscodePolicy.OPTIMAL }]);
|
||||
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
@@ -743,7 +716,7 @@ describe(MediaService.name, () => {
|
||||
inputOptions: [],
|
||||
outputOptions: [
|
||||
'-c:v h264',
|
||||
'-c:a copy',
|
||||
'-c:a aac',
|
||||
'-movflags faststart',
|
||||
'-fps_mode passthrough',
|
||||
'-map 0:0',
|
||||
@@ -785,11 +758,11 @@ describe(MediaService.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an exception if transcode value is invalid', async () => {
|
||||
it('should not transcode an invalid transcode value', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.videoStream2160p);
|
||||
configMock.load.mockResolvedValue([{ key: SystemConfigKey.FFMPEG_TRANSCODE, value: 'invalid' }]);
|
||||
|
||||
await expect(sut.handleVideoConversion({ id: assetStub.video.id })).rejects.toThrow();
|
||||
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||
expect(mediaMock.transcode).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -1133,7 +1106,7 @@ describe(MediaService.name, () => {
|
||||
});
|
||||
|
||||
it('should disable thread pooling for hevc if thread limit is above 0', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.videoStreamVp9);
|
||||
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);
|
||||
configMock.load.mockResolvedValue([
|
||||
{ key: SystemConfigKey.FFMPEG_THREADS, value: 2 },
|
||||
{ key: SystemConfigKey.FFMPEG_TARGET_VIDEO_CODEC, value: VideoCodec.HEVC },
|
||||
@@ -1167,7 +1140,7 @@ describe(MediaService.name, () => {
|
||||
});
|
||||
|
||||
it('should omit thread flags for hevc if thread limit is at or below 0', async () => {
|
||||
mediaMock.probe.mockResolvedValue(probeStub.videoStreamVp9);
|
||||
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);
|
||||
configMock.load.mockResolvedValue([
|
||||
{ key: SystemConfigKey.FFMPEG_THREADS, value: 0 },
|
||||
{ key: SystemConfigKey.FFMPEG_TARGET_VIDEO_CODEC, value: VideoCodec.HEVC },
|
||||
@@ -1783,7 +1756,7 @@ describe(MediaService.name, () => {
|
||||
|
||||
it('should set vbr options for rkmpp when max bitrate is enabled', async () => {
|
||||
storageMock.readdir.mockResolvedValue(['renderD128']);
|
||||
mediaMock.probe.mockResolvedValue(probeStub.videoStreamVp9);
|
||||
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);
|
||||
configMock.load.mockResolvedValue([
|
||||
{ key: SystemConfigKey.FFMPEG_ACCEL, value: TranscodeHWAccel.RKMPP },
|
||||
{ key: SystemConfigKey.FFMPEG_MAX_BITRATE, value: '10000k' },
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
Colorspace,
|
||||
TranscodeHWAccel,
|
||||
TranscodePolicy,
|
||||
TranscodeTarget,
|
||||
VideoCodec,
|
||||
} from '@app/infra/entities';
|
||||
import { ImmichLogger } from '@app/infra/logger';
|
||||
@@ -198,7 +197,7 @@ export class MediaService {
|
||||
}
|
||||
const mainAudioStream = this.getMainStream(audioStreams);
|
||||
const config = { ...ffmpeg, targetResolution: size.toString() };
|
||||
const options = new ThumbnailConfig(config).getOptions(TranscodeTarget.VIDEO, mainVideoStream, mainAudioStream);
|
||||
const options = new ThumbnailConfig(config).getOptions(mainVideoStream, mainAudioStream);
|
||||
await this.mediaRepository.transcode(asset.originalPath, path, options);
|
||||
break;
|
||||
}
|
||||
@@ -268,6 +267,7 @@ export class MediaService {
|
||||
const mainVideoStream = this.getMainStream(videoStreams);
|
||||
const mainAudioStream = this.getMainStream(audioStreams);
|
||||
const containerExtension = format.formatName;
|
||||
const bitrate = format.bitrate;
|
||||
if (!mainVideoStream || !containerExtension) {
|
||||
return false;
|
||||
}
|
||||
@@ -279,8 +279,15 @@ export class MediaService {
|
||||
|
||||
const { ffmpeg: config } = await this.configCore.getConfig();
|
||||
|
||||
const target = this.getTranscodeTarget(config, mainVideoStream, mainAudioStream);
|
||||
if (target === TranscodeTarget.NONE) {
|
||||
const required = this.isTranscodeRequired(
|
||||
asset,
|
||||
mainVideoStream,
|
||||
mainAudioStream,
|
||||
containerExtension,
|
||||
config,
|
||||
bitrate,
|
||||
);
|
||||
if (!required) {
|
||||
if (asset.encodedVideoPath) {
|
||||
this.logger.log(`Transcoded video exists for asset ${asset.id}, but is no longer required. Deleting...`);
|
||||
await this.jobRepository.queue({ name: JobName.DELETE_FILES, data: { files: [asset.encodedVideoPath] } });
|
||||
@@ -292,15 +299,13 @@ export class MediaService {
|
||||
|
||||
let transcodeOptions;
|
||||
try {
|
||||
transcodeOptions = await this.getCodecConfig(config).then((c) =>
|
||||
c.getOptions(target, mainVideoStream, mainAudioStream),
|
||||
);
|
||||
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream, mainAudioStream));
|
||||
} catch (error) {
|
||||
this.logger.error(`An error occurred while configuring transcoding options: ${error}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.logger.log(`Started encoding video ${asset.id} ${JSON.stringify(transcodeOptions)}`);
|
||||
this.logger.log(`Start encoding video ${asset.id} ${JSON.stringify(transcodeOptions)}`);
|
||||
try {
|
||||
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
||||
} catch (error) {
|
||||
@@ -311,13 +316,11 @@ export class MediaService {
|
||||
);
|
||||
}
|
||||
config.accel = TranscodeHWAccel.DISABLED;
|
||||
transcodeOptions = await this.getCodecConfig(config).then((c) =>
|
||||
c.getOptions(target, mainVideoStream, mainAudioStream),
|
||||
);
|
||||
transcodeOptions = await this.getCodecConfig(config).then((c) => c.getOptions(mainVideoStream, mainAudioStream));
|
||||
await this.mediaRepository.transcode(input, output, transcodeOptions);
|
||||
}
|
||||
|
||||
this.logger.log(`Successfully encoded ${asset.id}`);
|
||||
this.logger.log(`Encoding success ${asset.id}`);
|
||||
|
||||
await this.assetRepository.save({ id: asset.id, encodedVideoPath: output });
|
||||
|
||||
@@ -328,87 +331,54 @@ export class MediaService {
|
||||
return streams.sort((stream1, stream2) => stream2.frameCount - stream1.frameCount)[0];
|
||||
}
|
||||
|
||||
private getTranscodeTarget(
|
||||
config: SystemConfigFFmpegDto,
|
||||
videoStream: VideoStreamInfo | null,
|
||||
private isTranscodeRequired(
|
||||
asset: AssetEntity,
|
||||
videoStream: VideoStreamInfo,
|
||||
audioStream: AudioStreamInfo | null,
|
||||
): TranscodeTarget {
|
||||
if (videoStream == null && audioStream == null) {
|
||||
return TranscodeTarget.NONE;
|
||||
}
|
||||
containerExtension: string,
|
||||
ffmpegConfig: SystemConfigFFmpegDto,
|
||||
bitrate: number,
|
||||
): boolean {
|
||||
const isTargetVideoCodec = ffmpegConfig.acceptedVideoCodecs.includes(videoStream.codecName as VideoCodec);
|
||||
const isTargetContainer = ['mov,mp4,m4a,3gp,3g2,mj2', 'mp4', 'mov'].includes(containerExtension);
|
||||
const isTargetAudioCodec =
|
||||
audioStream == null || ffmpegConfig.acceptedAudioCodecs.includes(audioStream.codecName as AudioCodec);
|
||||
|
||||
const isAudioTranscodeRequired = this.isAudioTranscodeRequired(config, audioStream);
|
||||
const isVideoTranscodeRequired = this.isVideoTranscodeRequired(config, videoStream);
|
||||
|
||||
if (isAudioTranscodeRequired && isVideoTranscodeRequired) {
|
||||
return TranscodeTarget.ALL;
|
||||
}
|
||||
|
||||
if (isAudioTranscodeRequired) {
|
||||
return TranscodeTarget.AUDIO;
|
||||
}
|
||||
|
||||
if (isVideoTranscodeRequired) {
|
||||
return TranscodeTarget.VIDEO;
|
||||
}
|
||||
|
||||
return TranscodeTarget.NONE;
|
||||
}
|
||||
|
||||
private isAudioTranscodeRequired(ffmpegConfig: SystemConfigFFmpegDto, stream: AudioStreamInfo | null): boolean {
|
||||
if (stream == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (ffmpegConfig.transcode) {
|
||||
case TranscodePolicy.DISABLED: {
|
||||
return false;
|
||||
}
|
||||
case TranscodePolicy.ALL: {
|
||||
return true;
|
||||
}
|
||||
case TranscodePolicy.REQUIRED:
|
||||
case TranscodePolicy.OPTIMAL:
|
||||
case TranscodePolicy.BITRATE: {
|
||||
return !ffmpegConfig.acceptedAudioCodecs.includes(stream.codecName as AudioCodec);
|
||||
}
|
||||
default: {
|
||||
throw new Error(`Unsupported transcode policy: ${ffmpegConfig.transcode}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private isVideoTranscodeRequired(ffmpegConfig: SystemConfigFFmpegDto, stream: VideoStreamInfo | null): boolean {
|
||||
if (stream == null) {
|
||||
return false;
|
||||
}
|
||||
this.logger.verbose(
|
||||
`${asset.id}: AudioCodecName ${audioStream?.codecName ?? 'None'}, AudioStreamCodecType ${
|
||||
audioStream?.codecType ?? 'None'
|
||||
}, containerExtension ${containerExtension}`,
|
||||
);
|
||||
|
||||
const allTargetsMatching = isTargetVideoCodec && isTargetAudioCodec && isTargetContainer;
|
||||
const scalingEnabled = ffmpegConfig.targetResolution !== 'original';
|
||||
const targetRes = Number.parseInt(ffmpegConfig.targetResolution);
|
||||
const isLargerThanTargetRes = scalingEnabled && Math.min(stream.height, stream.width) > targetRes;
|
||||
const isLargerThanTargetBitrate = stream.bitrate > this.parseBitrateToBps(ffmpegConfig.maxBitrate);
|
||||
|
||||
const isTargetVideoCodec = ffmpegConfig.acceptedVideoCodecs.includes(stream.codecName as VideoCodec);
|
||||
const isRequired = !isTargetVideoCodec || stream.isHDR;
|
||||
const isLargerThanTargetRes = scalingEnabled && Math.min(videoStream.height, videoStream.width) > targetRes;
|
||||
const isLargerThanTargetBitrate = bitrate > this.parseBitrateToBps(ffmpegConfig.maxBitrate);
|
||||
|
||||
switch (ffmpegConfig.transcode) {
|
||||
case TranscodePolicy.DISABLED: {
|
||||
return false;
|
||||
}
|
||||
|
||||
case TranscodePolicy.ALL: {
|
||||
return true;
|
||||
}
|
||||
|
||||
case TranscodePolicy.REQUIRED: {
|
||||
return isRequired;
|
||||
return !allTargetsMatching || videoStream.isHDR;
|
||||
}
|
||||
|
||||
case TranscodePolicy.OPTIMAL: {
|
||||
return isRequired || isLargerThanTargetRes;
|
||||
return !allTargetsMatching || isLargerThanTargetRes || videoStream.isHDR;
|
||||
}
|
||||
|
||||
case TranscodePolicy.BITRATE: {
|
||||
return isRequired || isLargerThanTargetBitrate;
|
||||
return !allTargetsMatching || isLargerThanTargetBitrate || videoStream.isHDR;
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new Error(`Unsupported transcode policy: ${ffmpegConfig.transcode}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CQMode, ToneMapping, TranscodeHWAccel, TranscodeTarget, VideoCodec } from '@app/infra/entities';
|
||||
import { CQMode, ToneMapping, TranscodeHWAccel, VideoCodec } from '@app/infra/entities';
|
||||
import {
|
||||
AudioStreamInfo,
|
||||
BitrateDistribution,
|
||||
@@ -12,19 +12,16 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||
presets = ['veryslow', 'slower', 'slow', 'medium', 'fast', 'faster', 'veryfast', 'superfast', 'ultrafast'];
|
||||
constructor(protected config: SystemConfigFFmpegDto) {}
|
||||
|
||||
getOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
getOptions(videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
const options = {
|
||||
inputOptions: this.getBaseInputOptions(),
|
||||
outputOptions: [...this.getBaseOutputOptions(target, videoStream, audioStream), '-v verbose'],
|
||||
outputOptions: [...this.getBaseOutputOptions(videoStream, audioStream), '-v verbose'],
|
||||
twoPass: this.eligibleForTwoPass(),
|
||||
} as TranscodeOptions;
|
||||
if ([TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target)) {
|
||||
const filters = this.getFilterOptions(videoStream);
|
||||
if (filters.length > 0) {
|
||||
options.outputOptions.push(`-vf ${filters.join(',')}`);
|
||||
}
|
||||
const filters = this.getFilterOptions(videoStream);
|
||||
if (filters.length > 0) {
|
||||
options.outputOptions.push(`-vf ${filters.join(',')}`);
|
||||
}
|
||||
|
||||
options.outputOptions.push(...this.getPresetOptions(), ...this.getThreadOptions(), ...this.getBitrateOptions());
|
||||
|
||||
return options;
|
||||
@@ -34,10 +31,10 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||
return [];
|
||||
}
|
||||
|
||||
getBaseOutputOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
const options = [
|
||||
`-c:v ${[TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target) ? this.getVideoCodec() : 'copy'}`,
|
||||
`-c:a ${[TranscodeTarget.ALL, TranscodeTarget.AUDIO].includes(target) ? this.getAudioCodec() : 'copy'}`,
|
||||
`-c:v ${this.getVideoCodec()}`,
|
||||
`-c:a ${this.getAudioCodec()}`,
|
||||
// Makes a second pass moving the moov atom to the
|
||||
// beginning of the file for improved playback speed.
|
||||
'-movflags faststart',
|
||||
@@ -401,14 +398,14 @@ export class NVENCConfig extends BaseHWConfig {
|
||||
return ['-init_hw_device cuda=cuda:0', '-filter_hw_device cuda'];
|
||||
}
|
||||
|
||||
getBaseOutputOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
const options = [
|
||||
// below settings recommended from https://docs.nvidia.com/video-technologies/video-codec-sdk/12.0/ffmpeg-with-nvidia-gpu/index.html#command-line-for-latency-tolerant-high-quality-transcoding
|
||||
'-tune hq',
|
||||
'-qmin 0',
|
||||
'-rc-lookahead 20',
|
||||
'-i_qfactor 0.75',
|
||||
...super.getBaseOutputOptions(target, videoStream, audioStream),
|
||||
...super.getBaseOutputOptions(videoStream, audioStream),
|
||||
];
|
||||
if (this.getBFrames() > 0) {
|
||||
options.push('-b_ref_mode middle', '-b_qfactor 1.1');
|
||||
@@ -486,8 +483,8 @@ export class QSVConfig extends BaseHWConfig {
|
||||
return [`-init_hw_device qsv=hw${qsvString}`, '-filter_hw_device hw'];
|
||||
}
|
||||
|
||||
getBaseOutputOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
const options = super.getBaseOutputOptions(target, videoStream, audioStream);
|
||||
getBaseOutputOptions(videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||
const options = super.getBaseOutputOptions(videoStream, audioStream);
|
||||
// VP9 requires enabling low power mode https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/33583803e107b6d532def0f9d949364b01b6ad5a
|
||||
if (this.config.targetVideoCodec === VideoCodec.VP9) {
|
||||
options.push('-low_power 1');
|
||||
@@ -607,13 +604,11 @@ export class VAAPIConfig extends BaseHWConfig {
|
||||
}
|
||||
|
||||
export class RKMPPConfig extends BaseHWConfig {
|
||||
getOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo): TranscodeOptions {
|
||||
const options = super.getOptions(target, videoStream, audioStream);
|
||||
getOptions(videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo): TranscodeOptions {
|
||||
const options = super.getOptions(videoStream, audioStream);
|
||||
options.ffmpegPath = 'ffmpeg_mpp';
|
||||
options.ldLibraryPath = '/lib/aarch64-linux-gnu:/lib/ffmpeg-mpp';
|
||||
if ([TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target)) {
|
||||
options.outputOptions.push(...this.getSizeOptions(videoStream));
|
||||
}
|
||||
options.outputOptions.push(...this.getSizeOptions(videoStream));
|
||||
return options;
|
||||
}
|
||||
|
||||
|
||||
@@ -410,8 +410,8 @@ export class PersonService {
|
||||
});
|
||||
|
||||
// `matches` also includes the face itself
|
||||
if (machineLearning.facialRecognition.minFaces > 1 && matches.length <= 1) {
|
||||
this.logger.debug(`Face ${id} only matched the face itself, skipping`);
|
||||
if (matches.length <= 1) {
|
||||
this.logger.debug(`Face ${id} has no matches`);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ export interface IAssetRepository {
|
||||
softDeleteAll(ids: string[]): Promise<void>;
|
||||
restoreAll(ids: string[]): Promise<void>;
|
||||
findLivePhotoMatch(options: LivePhotoSearchOptions): Promise<AssetEntity | null>;
|
||||
getMapMarkers(ownerIds: string[], options?: MapMarkerSearchOptions): Promise<MapMarker[]>;
|
||||
getMapMarkers(ownerId: string, options?: MapMarkerSearchOptions): Promise<MapMarker[]>;
|
||||
getStatistics(ownerId: string, options: AssetStatsOptions): Promise<AssetStats>;
|
||||
getTimeBuckets(options: TimeBucketOptions): Promise<TimeBucketItem[]>;
|
||||
getTimeBucket(timeBucket: string, options: TimeBucketOptions): Promise<AssetEntity[]>;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TranscodeTarget, VideoCodec } from '@app/infra/entities';
|
||||
import { VideoCodec } from '@app/infra/entities';
|
||||
import { Writable } from 'node:stream';
|
||||
|
||||
export const IMediaRepository = 'IMediaRepository';
|
||||
@@ -16,14 +16,15 @@ export interface VideoStreamInfo {
|
||||
width: number;
|
||||
rotation: number;
|
||||
codecName?: string;
|
||||
codecType?: string;
|
||||
frameCount: number;
|
||||
isHDR: boolean;
|
||||
bitrate: number;
|
||||
}
|
||||
|
||||
export interface AudioStreamInfo {
|
||||
index: number;
|
||||
codecName?: string;
|
||||
codecType?: string;
|
||||
frameCount: number;
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ export interface BitrateDistribution {
|
||||
}
|
||||
|
||||
export interface VideoCodecSWConfig {
|
||||
getOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream: AudioStreamInfo): TranscodeOptions;
|
||||
getOptions(videoStream: VideoStreamInfo, audioStream: AudioStreamInfo): TranscodeOptions;
|
||||
}
|
||||
|
||||
export interface VideoCodecHWConfig extends VideoCodecSWConfig {
|
||||
|
||||
@@ -66,14 +66,13 @@ export interface SearchAssetIDOptions {
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface SearchUserIdOptions {
|
||||
export interface SearchUserIDOptions {
|
||||
deviceId?: string;
|
||||
libraryId?: string;
|
||||
ownerId?: string;
|
||||
userIds?: string[];
|
||||
}
|
||||
|
||||
export type SearchIdOptions = SearchAssetIDOptions & SearchUserIdOptions;
|
||||
export type SearchIDOptions = SearchAssetIDOptions & SearchUserIDOptions;
|
||||
|
||||
export interface SearchStatusOptions {
|
||||
isArchived?: boolean;
|
||||
@@ -84,7 +83,6 @@ export interface SearchStatusOptions {
|
||||
isOffline?: boolean;
|
||||
isReadOnly?: boolean;
|
||||
isVisible?: boolean;
|
||||
isNotInAlbum?: boolean;
|
||||
type?: AssetType;
|
||||
withArchived?: boolean;
|
||||
withDeleted?: boolean;
|
||||
@@ -134,10 +132,6 @@ export interface SearchEmbeddingOptions {
|
||||
userIds: string[];
|
||||
}
|
||||
|
||||
export interface SearchPeopleOptions {
|
||||
personIds?: string[];
|
||||
}
|
||||
|
||||
export interface SearchOrderOptions {
|
||||
orderDirection?: 'ASC' | 'DESC';
|
||||
}
|
||||
@@ -148,14 +142,12 @@ export interface SearchPaginationOptions {
|
||||
}
|
||||
|
||||
export type AssetSearchOptions = SearchDateOptions &
|
||||
SearchIdOptions &
|
||||
SearchIDOptions &
|
||||
SearchExifOptions &
|
||||
SearchOrderOptions &
|
||||
SearchPathOptions &
|
||||
SearchRelationOptions &
|
||||
SearchStatusOptions &
|
||||
SearchUserIdOptions &
|
||||
SearchPeopleOptions;
|
||||
SearchStatusOptions;
|
||||
|
||||
export type AssetSearchBuilderOptions = Omit<AssetSearchOptions, 'orderDirection'>;
|
||||
|
||||
@@ -164,8 +156,7 @@ export type SmartSearchOptions = SearchDateOptions &
|
||||
SearchExifOptions &
|
||||
SearchOneToOneRelationOptions &
|
||||
SearchStatusOptions &
|
||||
SearchUserIdOptions &
|
||||
SearchPeopleOptions;
|
||||
SearchUserIDOptions;
|
||||
|
||||
export interface FaceEmbeddingSearch extends SearchEmbeddingOptions {
|
||||
hasPerson?: boolean;
|
||||
|
||||
@@ -169,12 +169,6 @@ export class MetadataSearchDto extends BaseSearchDto {
|
||||
@Optional()
|
||||
@ApiProperty({ enumName: 'AssetOrder', enum: AssetOrder })
|
||||
order?: AssetOrder;
|
||||
|
||||
@QueryBoolean({ optional: true })
|
||||
isNotInAlbum?: boolean;
|
||||
|
||||
@Optional()
|
||||
personIds?: string[];
|
||||
}
|
||||
|
||||
export class SmartSearchDto extends BaseSearchDto {
|
||||
|
||||
@@ -60,7 +60,6 @@ export class SearchService {
|
||||
|
||||
async searchMetadata(auth: AuthDto, dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
||||
let checksum: Buffer | undefined;
|
||||
const userIds = await this.getUserIdsToSearch(auth);
|
||||
|
||||
if (dto.checksum) {
|
||||
const encoding = dto.checksum.length === 28 ? 'base64' : 'hex';
|
||||
@@ -75,7 +74,7 @@ export class SearchService {
|
||||
{
|
||||
...dto,
|
||||
checksum,
|
||||
userIds,
|
||||
ownerId: auth.user.id,
|
||||
orderDirection: dto.order ? enumToOrder[dto.order] : 'DESC',
|
||||
},
|
||||
);
|
||||
|
||||
@@ -140,12 +140,6 @@ export const defaults = Object.freeze<SystemConfig>({
|
||||
externalDomain: '',
|
||||
loginPageMessage: '',
|
||||
},
|
||||
storage: {
|
||||
kind: 'local',
|
||||
options: {
|
||||
path: process.env.UPLOAD_LOCATION ?? '',
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export enum FeatureFlag {
|
||||
@@ -174,7 +168,7 @@ export class SystemConfigCore {
|
||||
|
||||
public config$ = new Subject<SystemConfig>();
|
||||
|
||||
private constructor(private repository: ISystemConfigRepository) { }
|
||||
private constructor(private repository: ISystemConfigRepository) {}
|
||||
|
||||
static create(repository: ISystemConfigRepository) {
|
||||
if (!instance) {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
SmartSearchDto,
|
||||
} from '@app/domain';
|
||||
import { SearchSuggestionRequestDto } from '@app/domain/search/dto/search-suggestion.dto';
|
||||
import { Body, Controller, Get, Post, Query } from '@nestjs/common';
|
||||
import { Controller, Get, Query } from '@nestjs/common';
|
||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { Auth, Authenticated } from '../app.guard';
|
||||
import { UseValidation } from '../app.utils';
|
||||
@@ -22,13 +22,13 @@ import { UseValidation } from '../app.utils';
|
||||
export class SearchController {
|
||||
constructor(private service: SearchService) {}
|
||||
|
||||
@Post('metadata')
|
||||
searchMetadata(@Auth() auth: AuthDto, @Body() dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
||||
@Get('metadata')
|
||||
searchMetadata(@Auth() auth: AuthDto, @Query() dto: MetadataSearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.searchMetadata(auth, dto);
|
||||
}
|
||||
|
||||
@Post('smart')
|
||||
searchSmart(@Auth() auth: AuthDto, @Body() dto: SmartSearchDto): Promise<SearchResponseDto> {
|
||||
@Get('smart')
|
||||
searchSmart(@Auth() auth: AuthDto, @Query() dto: SmartSearchDto): Promise<SearchResponseDto> {
|
||||
return this.service.searchSmart(auth, dto);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,13 +118,6 @@ export enum TranscodePolicy {
|
||||
DISABLED = 'disabled',
|
||||
}
|
||||
|
||||
export enum TranscodeTarget {
|
||||
NONE,
|
||||
AUDIO,
|
||||
VIDEO,
|
||||
ALL,
|
||||
}
|
||||
|
||||
export enum VideoCodec {
|
||||
H264 = 'h264',
|
||||
HEVC = 'hevc',
|
||||
@@ -172,18 +165,6 @@ export enum LogLevel {
|
||||
FATAL = 'fatal',
|
||||
}
|
||||
|
||||
export interface StorageOptionsLocal {
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface StorageOptionsS3 {
|
||||
bucket: string;
|
||||
region: string;
|
||||
endpoint: string;
|
||||
accessKeyId: string;
|
||||
secretAccessKey: string;
|
||||
}
|
||||
|
||||
export interface SystemConfig {
|
||||
ffmpeg: {
|
||||
crf: number;
|
||||
@@ -288,10 +269,4 @@ export interface SystemConfig {
|
||||
externalDomain: string;
|
||||
loginPageMessage: string;
|
||||
};
|
||||
// TODO(uhthomas): Is this definitely the approach we want to take for
|
||||
// configuring storage?
|
||||
storage: {
|
||||
kind: string;
|
||||
options: StorageOptionsLocal | StorageOptionsS3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,27 +139,14 @@ export function searchAssetBuilder(
|
||||
);
|
||||
|
||||
const exifInfo = _.omitBy(_.pick(options, ['city', 'country', 'lensModel', 'make', 'model', 'state']), _.isUndefined);
|
||||
const hasExifQuery = Object.keys(exifInfo).length > 0;
|
||||
|
||||
if (options.withExif && !hasExifQuery) {
|
||||
builder.leftJoinAndSelect(`${builder.alias}.exifInfo`, 'exifInfo');
|
||||
}
|
||||
|
||||
if (hasExifQuery) {
|
||||
options.withExif
|
||||
? builder.leftJoinAndSelect(`${builder.alias}.exifInfo`, 'exifInfo')
|
||||
: builder.leftJoin(`${builder.alias}.exifInfo`, 'exifInfo');
|
||||
|
||||
if (Object.keys(exifInfo).length > 0) {
|
||||
builder.leftJoin(`${builder.alias}.exifInfo`, 'exifInfo');
|
||||
builder.andWhere({ exifInfo });
|
||||
}
|
||||
|
||||
const id = _.pick(options, ['checksum', 'deviceAssetId', 'deviceId', 'id', 'libraryId']);
|
||||
const id = _.pick(options, ['checksum', 'deviceAssetId', 'deviceId', 'id', 'libraryId', 'ownerId']);
|
||||
builder.andWhere(_.omitBy(id, _.isUndefined));
|
||||
|
||||
if (options.userIds) {
|
||||
builder.andWhere(`${builder.alias}.ownerId IN (:...userIds)`, { userIds: options.userIds });
|
||||
}
|
||||
|
||||
const path = _.pick(options, ['encodedVideoPath', 'originalFileName', 'originalPath', 'resizePath', 'webpPath']);
|
||||
builder.andWhere(_.omitBy(path, _.isUndefined));
|
||||
|
||||
@@ -177,11 +164,8 @@ export function searchAssetBuilder(
|
||||
),
|
||||
);
|
||||
|
||||
if (options.isNotInAlbum) {
|
||||
builder
|
||||
.leftJoin(`${builder.alias}.albums`, 'albums')
|
||||
.andWhere('albums.id IS NULL')
|
||||
.andWhere(`${builder.alias}.isVisible = true`);
|
||||
if (options.withExif) {
|
||||
builder.leftJoinAndSelect(`${builder.alias}.exifInfo`, 'exifInfo');
|
||||
}
|
||||
|
||||
if (options.withFaces || options.withPeople) {
|
||||
@@ -196,18 +180,6 @@ export function searchAssetBuilder(
|
||||
builder.leftJoinAndSelect(`${builder.alias}.smartInfo`, 'smartInfo');
|
||||
}
|
||||
|
||||
if (options.personIds && options.personIds.length > 0) {
|
||||
builder
|
||||
.leftJoin(`${builder.alias}.faces`, 'faces')
|
||||
.andWhere('faces.personId IN (:...personIds)', { personIds: options.personIds })
|
||||
.addGroupBy(`${builder.alias}.id`)
|
||||
.having('COUNT(faces.id) = :personCount', { personCount: options.personIds.length });
|
||||
|
||||
if (options.withExif) {
|
||||
builder.addGroupBy('exifInfo.assetId');
|
||||
}
|
||||
}
|
||||
|
||||
if (options.withStacked) {
|
||||
builder
|
||||
.leftJoinAndSelect(`${builder.alias}.stack`, 'stack')
|
||||
|
||||
@@ -176,7 +176,7 @@ export class AssetRepository implements IAssetRepository {
|
||||
}
|
||||
|
||||
getByUserId(pagination: PaginationOptions, userId: string, options: AssetSearchOptions = {}): Paginated<AssetEntity> {
|
||||
return this.getAll(pagination, { ...options, ownerId: userId });
|
||||
return this.getAll(pagination, { ...options, id: userId });
|
||||
}
|
||||
|
||||
@GenerateSql({ params: [[DummyValue.UUID]] })
|
||||
@@ -472,7 +472,7 @@ export class AssetRepository implements IAssetRepository {
|
||||
});
|
||||
}
|
||||
|
||||
async getMapMarkers(ownerIds: string[], options: MapMarkerSearchOptions = {}): Promise<MapMarker[]> {
|
||||
async getMapMarkers(ownerId: string, options: MapMarkerSearchOptions = {}): Promise<MapMarker[]> {
|
||||
const { isArchived, isFavorite, fileCreatedAfter, fileCreatedBefore } = options;
|
||||
|
||||
const assets = await this.repository.find({
|
||||
@@ -484,7 +484,7 @@ export class AssetRepository implements IAssetRepository {
|
||||
},
|
||||
},
|
||||
where: {
|
||||
ownerId: In([...ownerIds]),
|
||||
ownerId,
|
||||
isVisible: true,
|
||||
isArchived,
|
||||
exifInfo: {
|
||||
|
||||
@@ -60,7 +60,6 @@ export class MediaRepository implements IMediaRepository {
|
||||
frameCount: Number.parseInt(stream.nb_frames ?? '0'),
|
||||
rotation: Number.parseInt(`${stream.rotation ?? 0}`),
|
||||
isHDR: stream.color_transfer === 'smpte2084' || stream.color_transfer === 'arib-std-b67',
|
||||
bitrate: Number.parseInt(stream.bit_rate ?? '0'),
|
||||
})),
|
||||
audioStreams: results.streams
|
||||
.filter((stream) => stream.codec_type === 'audio')
|
||||
|
||||
@@ -58,7 +58,6 @@ export class SearchRepository implements ISearchRepository {
|
||||
ownerId: DummyValue.UUID,
|
||||
withStacked: true,
|
||||
isFavorite: true,
|
||||
ownerIds: [DummyValue.UUID],
|
||||
},
|
||||
],
|
||||
})
|
||||
@@ -67,6 +66,7 @@ export class SearchRepository implements ISearchRepository {
|
||||
builder = searchAssetBuilder(builder, options);
|
||||
|
||||
builder.orderBy('asset.fileCreatedAt', options.orderDirection ?? 'DESC');
|
||||
|
||||
return paginatedBuilder<AssetEntity>(builder, {
|
||||
mode: PaginationMode.SKIP_TAKE,
|
||||
skip: (pagination.page - 1) * pagination.size,
|
||||
|
||||
@@ -77,9 +77,9 @@ FROM
|
||||
(
|
||||
"asset"."fileCreatedAt" >= $1
|
||||
AND "exifInfo"."lensModel" = $2
|
||||
AND "asset"."ownerId" = $3
|
||||
AND 1 = 1
|
||||
AND 1 = 1
|
||||
AND "asset"."isFavorite" = $3
|
||||
AND "asset"."isFavorite" = $4
|
||||
AND (
|
||||
"stack"."primaryAssetId" = "asset"."id"
|
||||
OR "asset"."stackId" IS NULL
|
||||
|
||||
Vendored
+20
-23
@@ -13,14 +13,16 @@ const probeStubDefaultVideoStream: VideoStreamInfo[] = [
|
||||
height: 1080,
|
||||
width: 1920,
|
||||
codecName: 'hevc',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const probeStubDefaultAudioStream: AudioStreamInfo[] = [{ index: 1, codecName: 'mp3', frameCount: 100 }];
|
||||
const probeStubDefaultAudioStream: AudioStreamInfo[] = [
|
||||
{ index: 1, codecName: 'aac', codecType: 'audio', frameCount: 100 },
|
||||
];
|
||||
|
||||
const probeStubDefault: VideoInfo = {
|
||||
format: probeStubDefaultFormat,
|
||||
@@ -39,20 +41,20 @@ export const probeStub = {
|
||||
height: 1080,
|
||||
width: 400,
|
||||
codecName: 'hevc',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
{
|
||||
index: 1,
|
||||
height: 1080,
|
||||
width: 400,
|
||||
codecName: 'h7000',
|
||||
codecType: 'video',
|
||||
frameCount: 99,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -64,10 +66,10 @@ export const probeStub = {
|
||||
height: 0,
|
||||
width: 400,
|
||||
codecName: 'hevc',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -79,16 +81,21 @@ export const probeStub = {
|
||||
height: 2160,
|
||||
width: 3840,
|
||||
codecName: 'h264',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
videoStream40Mbps: Object.freeze<VideoInfo>({
|
||||
...probeStubDefault,
|
||||
videoStreams: [{ ...probeStubDefaultVideoStream[0], bitrate: 40_000_000 }],
|
||||
format: {
|
||||
formatName: 'mov,mp4,m4a,3gp,3g2,mj2',
|
||||
formatLongName: 'QuickTime / MOV',
|
||||
duration: 0,
|
||||
bitrate: 40_000_000,
|
||||
},
|
||||
}),
|
||||
videoStreamHDR: Object.freeze<VideoInfo>({
|
||||
...probeStubDefault,
|
||||
@@ -98,10 +105,10 @@ export const probeStub = {
|
||||
height: 480,
|
||||
width: 480,
|
||||
codecName: 'h264',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: true,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -113,10 +120,10 @@ export const probeStub = {
|
||||
height: 2160,
|
||||
width: 3840,
|
||||
codecName: 'h264',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 90,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -128,10 +135,10 @@ export const probeStub = {
|
||||
height: 355,
|
||||
width: 1586,
|
||||
codecName: 'h264',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -143,16 +150,16 @@ export const probeStub = {
|
||||
height: 1586,
|
||||
width: 355,
|
||||
codecName: 'h264',
|
||||
codecType: 'video',
|
||||
frameCount: 100,
|
||||
rotation: 0,
|
||||
isHDR: false,
|
||||
bitrate: 0,
|
||||
},
|
||||
],
|
||||
}),
|
||||
audioStreamAac: Object.freeze<VideoInfo>({
|
||||
audioStreamMp3: Object.freeze<VideoInfo>({
|
||||
...probeStubDefault,
|
||||
audioStreams: [{ index: 1, codecName: 'aac', frameCount: 100 }],
|
||||
audioStreams: [{ index: 1, codecType: 'audio', codecName: 'aac', frameCount: 100 }],
|
||||
}),
|
||||
matroskaContainer: Object.freeze<VideoInfo>({
|
||||
...probeStubDefault,
|
||||
@@ -163,14 +170,4 @@ export const probeStub = {
|
||||
bitrate: 0,
|
||||
},
|
||||
}),
|
||||
videoStreamVp9: Object.freeze<VideoInfo>({
|
||||
...probeStubDefault,
|
||||
videoStreams: [{ ...probeStubDefaultVideoStream[0], codecName: 'vp9' }],
|
||||
format: {
|
||||
formatName: 'matroska,webm',
|
||||
formatLongName: 'Matroska / WebM',
|
||||
duration: 0,
|
||||
bitrate: 0,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -38,7 +38,6 @@ module.exports = {
|
||||
'unicorn/prevent-abbreviations': 'off',
|
||||
'unicorn/no-nested-ternary': 'off',
|
||||
'unicorn/consistent-function-scoping': 'off',
|
||||
'unicorn/prefer-top-level-await': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
|
||||
+1
-2
@@ -3,7 +3,6 @@
|
||||
"trailingComma": "all",
|
||||
"printWidth": 120,
|
||||
"semi": true,
|
||||
"plugins": ["prettier-plugin-organize-imports", "prettier-plugin-svelte"],
|
||||
"organizeImportsSkipDestructiveCodeActions": true,
|
||||
"plugins": ["prettier-plugin-svelte"],
|
||||
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
FROM node:iron-alpine3.18
|
||||
|
||||
RUN apk add --no-cache tini
|
||||
USER node
|
||||
WORKDIR /usr/src/app
|
||||
COPY --chown=node:node package*.json ./
|
||||
@@ -9,4 +8,3 @@ COPY --chown=node:node . .
|
||||
ENV CHOKIDAR_USEPOLLING=true
|
||||
EXPOSE 24678
|
||||
EXPOSE 3000
|
||||
ENTRYPOINT ["/sbin/tini", "--", "/bin/sh"]
|
||||
|
||||
+7
-2
@@ -2,7 +2,12 @@
|
||||
|
||||
TYPESCRIPT_SDK=/usr/src/open-api/typescript-sdk
|
||||
|
||||
npm --prefix "$TYPESCRIPT_SDK" install
|
||||
npm --prefix "$TYPESCRIPT_SDK" run build
|
||||
if [ ! -d "$TYPESCRIPT_SDK/build" ]; then
|
||||
echo "$TYPESCRIPT_SDK/build does not exist, building"
|
||||
npm --prefix "$TYPESCRIPT_SDK" install
|
||||
npm --prefix "$TYPESCRIPT_SDK" run build
|
||||
else
|
||||
echo "$TYPESCRIPT_SDK/build exists, skipping"
|
||||
fi
|
||||
|
||||
node ./node_modules/.bin/vite dev --host 0.0.0.0 --port 3000
|
||||
|
||||
Generated
+35
-74
@@ -23,16 +23,15 @@
|
||||
"luxon": "^3.2.1",
|
||||
"socket.io-client": "^4.6.1",
|
||||
"svelte-local-storage-store": "^0.6.0",
|
||||
"svelte-maplibre": "^0.8.0",
|
||||
"svelte-maplibre": "^0.7.0",
|
||||
"thumbhash": "^0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.0",
|
||||
"@floating-ui/dom": "^1.5.1",
|
||||
"@socket.io/component-emitter": "^3.1.0",
|
||||
"@sveltejs/adapter-static": "^3.0.1",
|
||||
"@sveltejs/kit": "^2.5.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@sveltejs/kit": "^2.0.6",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/svelte": "^4.0.3",
|
||||
"@types/dom-to-image": "^2.6.4",
|
||||
@@ -51,11 +50,11 @@
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^3.1.0",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"svelte": "^4.2.11",
|
||||
"svelte-check": "^3.6.4",
|
||||
"svelte": "^4.0.5",
|
||||
"svelte-check": "^3.4.3",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"tslib": "^2.5.0",
|
||||
"typescript": "^5.3.3",
|
||||
@@ -1089,13 +1088,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@maplibre/maplibre-gl-style-spec": {
|
||||
"version": "20.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.1.1.tgz",
|
||||
"integrity": "sha512-z85ARNPCBI2Cs5cPOS3DSbraTN+ue8zrcYVoSWBuNrD/mA+2SKAJ+hIzI22uN7gac6jBMnCdpPKRxS/V0KSZVQ==",
|
||||
"version": "19.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-19.3.3.tgz",
|
||||
"integrity": "sha512-cOZZOVhDSulgK0meTsTkmNXb1ahVvmTmWmfx9gRBwc6hq98wS9JP35ESIoNq3xqEan+UN+gn8187Z6E4NKhLsw==",
|
||||
"dependencies": {
|
||||
"@mapbox/jsonlint-lines-primitives": "~2.0.2",
|
||||
"@mapbox/unitbezier": "^0.0.1",
|
||||
"json-stringify-pretty-compact": "^4.0.0",
|
||||
"json-stringify-pretty-compact": "^3.0.0",
|
||||
"minimist": "^1.2.8",
|
||||
"rw": "^1.3.3",
|
||||
"sort-object": "^3.0.3"
|
||||
@@ -1684,17 +1683,9 @@
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz",
|
||||
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg=="
|
||||
},
|
||||
"node_modules/@types/geojson-vt": {
|
||||
"version": "3.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz",
|
||||
"integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
"version": "7946.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz",
|
||||
"integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ=="
|
||||
},
|
||||
"node_modules/@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.6",
|
||||
@@ -1714,14 +1705,6 @@
|
||||
"integrity": "sha512-q2ybP0u0NVj87oMnGZOGxY2iUN8ddr48zPOBHBdbOLpsMTA/keGj+93ou+OMCnJk0xewzlNIaVEkxM6VBD3E2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/leaflet": {
|
||||
"version": "1.9.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.8.tgz",
|
||||
"integrity": "sha512-EXdsL4EhoUtGm2GC2ZYtXn+Fzc6pluVgagvo2VC1RHWToLGlTRwVYoDpqS/7QXa01rmDyBjJk3Catpf60VMkwg==",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
"version": "4.14.199",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz",
|
||||
@@ -4042,9 +4025,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.1.tgz",
|
||||
"integrity": "sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ=="
|
||||
},
|
||||
"node_modules/file-entry-cache": {
|
||||
"version": "6.0.1",
|
||||
@@ -5291,9 +5274,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/json-stringify-pretty-compact": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz",
|
||||
"integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q=="
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-3.0.0.tgz",
|
||||
"integrity": "sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA=="
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
@@ -5556,9 +5539,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/maplibre-gl": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-4.0.1.tgz",
|
||||
"integrity": "sha512-UF+wI2utIciFXNg6+gYaMe7IGa9fMLzAZM3vdlGilqyWYmuibjcN40yGVgkz2r28//aOLphvtli3TbDEjEqHww==",
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-3.6.2.tgz",
|
||||
"integrity": "sha512-krg2KFIdOpLPngONDhP6ixCoWl5kbdMINP0moMSJFVX7wX1Clm2M9hlNKXS8vBGlVWwR5R3ZfI6IPrYz7c+aCQ==",
|
||||
"dependencies": {
|
||||
"@mapbox/geojson-rewind": "^0.5.2",
|
||||
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
||||
@@ -5567,9 +5550,8 @@
|
||||
"@mapbox/unitbezier": "^0.0.1",
|
||||
"@mapbox/vector-tile": "^1.3.1",
|
||||
"@mapbox/whoots-js": "^3.1.0",
|
||||
"@maplibre/maplibre-gl-style-spec": "^20.1.1",
|
||||
"@types/geojson": "^7946.0.14",
|
||||
"@types/geojson-vt": "3.2.5",
|
||||
"@maplibre/maplibre-gl-style-spec": "^19.3.3",
|
||||
"@types/geojson": "^7946.0.13",
|
||||
"@types/mapbox__point-geometry": "^0.1.4",
|
||||
"@types/mapbox__vector-tile": "^1.3.4",
|
||||
"@types/pbf": "^3.0.5",
|
||||
@@ -6207,11 +6189,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pmtiles": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-3.0.3.tgz",
|
||||
"integrity": "sha512-tj4l3HHJd6/qf9VefzlPK2eYEQgbf+4uXPzNlrj3k7hHvLtibYSxfp51TF6ALt4YezM8MCdiOminnHvdAyqyGg==",
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/pmtiles/-/pmtiles-2.11.0.tgz",
|
||||
"integrity": "sha512-dU9SzzaqmCGpdEuTnIba6bDHT6j09ZJFIXxwGpvkiEnce3ZnBB1VKt6+EOmJGueriweaZLAMTUmKVElU2CBe0g==",
|
||||
"dependencies": {
|
||||
"@types/leaflet": "^1.9.8",
|
||||
"fflate": "^0.8.0"
|
||||
}
|
||||
},
|
||||
@@ -6417,26 +6398,6 @@
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-organize-imports": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz",
|
||||
"integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@volar/vue-language-plugin-pug": "^1.0.4",
|
||||
"@volar/vue-typescript": "^1.0.4",
|
||||
"prettier": ">=2.0",
|
||||
"typescript": ">=2.9"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@volar/vue-language-plugin-pug": {
|
||||
"optional": true
|
||||
},
|
||||
"@volar/vue-typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-plugin-svelte": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.1.2.tgz",
|
||||
@@ -7427,9 +7388,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/svelte": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.11.tgz",
|
||||
"integrity": "sha512-YIQk3J4X89wOLhjsqIW8tqY3JHPuBdtdOIkASP2PZeAMcSW9RsIjQzMesCrxOF3gdWYC0mKknlKF7OqmLM+Zqg==",
|
||||
"version": "4.2.10",
|
||||
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.10.tgz",
|
||||
"integrity": "sha512-Ep06yCaCdgG1Mafb/Rx8sJ1QS3RW2I2BxGp2Ui9LBHSZ2/tO/aGLc5WqPjgiAP6KAnLJGaIr/zzwQlOo1b8MxA==",
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.15",
|
||||
@@ -7523,15 +7484,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/svelte-maplibre": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/svelte-maplibre/-/svelte-maplibre-0.8.0.tgz",
|
||||
"integrity": "sha512-sRSj/zQa7LTfHNIzKcYe+sa9qHClt/OAXcdPQ0w3ksLbCMmVHGk4B2yIXHCVk0g4sc18M85N8KGsHVtZoNC+Mw==",
|
||||
"version": "0.7.7",
|
||||
"resolved": "https://registry.npmjs.org/svelte-maplibre/-/svelte-maplibre-0.7.7.tgz",
|
||||
"integrity": "sha512-fnv8L3tA4EMePp9BGKAc8AvXCsg34z56NBMGjYkz6qkl90qSTY4vUhIu1KXbwjGfQmHBmPkIl9VSdnnHCMnaRA==",
|
||||
"dependencies": {
|
||||
"d3-geo": "^3.1.0",
|
||||
"just-compare": "^2.3.0",
|
||||
"just-flush": "^2.3.0",
|
||||
"maplibre-gl": "^4.0.0",
|
||||
"pmtiles": "^3.0.3"
|
||||
"maplibre-gl": "^3.5.0",
|
||||
"pmtiles": "^2.10.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@deck.gl/core": "^8.8.0",
|
||||
|
||||
+6
-7
@@ -24,10 +24,9 @@
|
||||
"devDependencies": {
|
||||
"@faker-js/faker": "^8.0.0",
|
||||
"@floating-ui/dom": "^1.5.1",
|
||||
"@socket.io/component-emitter": "^3.1.0",
|
||||
"@sveltejs/adapter-static": "^3.0.1",
|
||||
"@sveltejs/kit": "^2.5.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.2",
|
||||
"@sveltejs/kit": "^2.0.6",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"@testing-library/jest-dom": "^6.1.5",
|
||||
"@testing-library/svelte": "^4.0.3",
|
||||
"@types/dom-to-image": "^2.6.4",
|
||||
@@ -46,11 +45,11 @@
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^3.1.0",
|
||||
"prettier-plugin-organize-imports": "^3.2.4",
|
||||
"prettier-plugin-svelte": "^3.1.2",
|
||||
"rollup-plugin-visualizer": "^5.12.0",
|
||||
"svelte": "^4.2.11",
|
||||
"svelte-check": "^3.6.4",
|
||||
"svelte": "^4.0.5",
|
||||
"svelte-check": "^3.4.3",
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"tslib": "^2.5.0",
|
||||
"typescript": "^5.3.3",
|
||||
@@ -73,7 +72,7 @@
|
||||
"luxon": "^3.2.1",
|
||||
"socket.io-client": "^4.6.1",
|
||||
"svelte-local-storage-store": "^0.6.0",
|
||||
"svelte-maplibre": "^0.8.0",
|
||||
"svelte-maplibre": "^0.7.0",
|
||||
"thumbhash": "^0.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
import {
|
||||
APIKeyApi,
|
||||
ActivityApi,
|
||||
AlbumApi,
|
||||
AssetApi,
|
||||
AssetApiFp,
|
||||
AssetJobName,
|
||||
AuditApi,
|
||||
AuthenticationApi,
|
||||
DownloadApi,
|
||||
FaceApi,
|
||||
JobApi,
|
||||
JobName,
|
||||
LibraryApi,
|
||||
OAuthApi,
|
||||
PartnerApi,
|
||||
PersonApi,
|
||||
SearchApi,
|
||||
ServerInfoApi,
|
||||
SharedLinkApi,
|
||||
SystemConfigApi,
|
||||
TrashApi,
|
||||
UserApi,
|
||||
UserApiFp,
|
||||
base,
|
||||
common,
|
||||
configuration,
|
||||
} from '@immich/sdk/axios';
|
||||
import type { ApiParams as ApiParameters } from './types';
|
||||
|
||||
class ImmichApi {
|
||||
public activityApi: ActivityApi;
|
||||
public albumApi: AlbumApi;
|
||||
public downloadApi: DownloadApi;
|
||||
public libraryApi: LibraryApi;
|
||||
public assetApi: AssetApi;
|
||||
public auditApi: AuditApi;
|
||||
public authenticationApi: AuthenticationApi;
|
||||
public faceApi: FaceApi;
|
||||
public jobApi: JobApi;
|
||||
public keyApi: APIKeyApi;
|
||||
public oauthApi: OAuthApi;
|
||||
public partnerApi: PartnerApi;
|
||||
public searchApi: SearchApi;
|
||||
public serverInfoApi: ServerInfoApi;
|
||||
public sharedLinkApi: SharedLinkApi;
|
||||
public personApi: PersonApi;
|
||||
public systemConfigApi: SystemConfigApi;
|
||||
public userApi: UserApi;
|
||||
public trashApi: TrashApi;
|
||||
|
||||
private config: configuration.Configuration;
|
||||
private key?: string;
|
||||
|
||||
get isSharedLink() {
|
||||
return !!this.key;
|
||||
}
|
||||
|
||||
constructor(parameters: configuration.ConfigurationParameters) {
|
||||
this.config = new configuration.Configuration(parameters);
|
||||
|
||||
this.activityApi = new ActivityApi(this.config);
|
||||
this.albumApi = new AlbumApi(this.config);
|
||||
this.auditApi = new AuditApi(this.config);
|
||||
this.downloadApi = new DownloadApi(this.config);
|
||||
this.libraryApi = new LibraryApi(this.config);
|
||||
this.assetApi = new AssetApi(this.config);
|
||||
this.authenticationApi = new AuthenticationApi(this.config);
|
||||
this.faceApi = new FaceApi(this.config);
|
||||
this.jobApi = new JobApi(this.config);
|
||||
this.keyApi = new APIKeyApi(this.config);
|
||||
this.oauthApi = new OAuthApi(this.config);
|
||||
this.partnerApi = new PartnerApi(this.config);
|
||||
this.searchApi = new SearchApi(this.config);
|
||||
this.serverInfoApi = new ServerInfoApi(this.config);
|
||||
this.sharedLinkApi = new SharedLinkApi(this.config);
|
||||
this.personApi = new PersonApi(this.config);
|
||||
this.systemConfigApi = new SystemConfigApi(this.config);
|
||||
this.userApi = new UserApi(this.config);
|
||||
this.trashApi = new TrashApi(this.config);
|
||||
}
|
||||
|
||||
private createUrl(path: string, parameters?: Record<string, unknown>) {
|
||||
const searchParameters = new URLSearchParams();
|
||||
for (const key in parameters) {
|
||||
const value = parameters[key];
|
||||
if (value !== undefined && value !== null) {
|
||||
searchParameters.set(key, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
const url = new URL(path, common.DUMMY_BASE_URL);
|
||||
url.search = searchParameters.toString();
|
||||
|
||||
return (this.config.basePath || base.BASE_PATH) + common.toPathString(url);
|
||||
}
|
||||
|
||||
public setKey(key: string) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public getKey(): string | undefined {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public setAccessToken(accessToken: string) {
|
||||
this.config.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public removeAccessToken() {
|
||||
this.config.accessToken = undefined;
|
||||
}
|
||||
|
||||
public setBaseUrl(baseUrl: string) {
|
||||
this.config.basePath = baseUrl;
|
||||
}
|
||||
|
||||
public getAssetFileUrl(...[assetId, isThumb, isWeb]: ApiParameters<typeof AssetApiFp, 'serveFile'>) {
|
||||
const path = `/asset/file/${assetId}`;
|
||||
return this.createUrl(path, { isThumb, isWeb, key: this.getKey() });
|
||||
}
|
||||
|
||||
public getAssetThumbnailUrl(...[assetId, format]: ApiParameters<typeof AssetApiFp, 'getAssetThumbnail'>) {
|
||||
const path = `/asset/thumbnail/${assetId}`;
|
||||
return this.createUrl(path, { format, key: this.getKey() });
|
||||
}
|
||||
|
||||
public getProfileImageUrl(...[userId]: ApiParameters<typeof UserApiFp, 'getProfileImage'>) {
|
||||
const path = `/user/profile-image/${userId}`;
|
||||
return this.createUrl(path);
|
||||
}
|
||||
|
||||
public getPeopleThumbnailUrl(personId: string) {
|
||||
const path = `/person/${personId}/thumbnail`;
|
||||
return this.createUrl(path);
|
||||
}
|
||||
|
||||
public getJobName(jobName: JobName) {
|
||||
const names: Record<JobName, string> = {
|
||||
[JobName.ThumbnailGeneration]: 'Generate Thumbnails',
|
||||
[JobName.MetadataExtraction]: 'Extract Metadata',
|
||||
[JobName.Sidecar]: 'Sidecar Metadata',
|
||||
[JobName.SmartSearch]: 'Smart Search',
|
||||
[JobName.FaceDetection]: 'Face Detection',
|
||||
[JobName.FacialRecognition]: 'Facial Recognition',
|
||||
[JobName.VideoConversion]: 'Transcode Videos',
|
||||
[JobName.StorageTemplateMigration]: 'Storage Template Migration',
|
||||
[JobName.Migration]: 'Migration',
|
||||
[JobName.BackgroundTask]: 'Background Tasks',
|
||||
[JobName.Search]: 'Search',
|
||||
[JobName.Library]: 'Library',
|
||||
};
|
||||
|
||||
return names[jobName];
|
||||
}
|
||||
|
||||
public getAssetJobName(job: AssetJobName) {
|
||||
const names: Record<AssetJobName, string> = {
|
||||
[AssetJobName.RefreshMetadata]: 'Refresh metadata',
|
||||
[AssetJobName.RegenerateThumbnail]: 'Refresh thumbnails',
|
||||
[AssetJobName.TranscodeVideo]: 'Refresh encoded videos',
|
||||
};
|
||||
|
||||
return names[job];
|
||||
}
|
||||
|
||||
public getAssetJobMessage(job: AssetJobName) {
|
||||
const messages: Record<AssetJobName, string> = {
|
||||
[AssetJobName.RefreshMetadata]: 'Refreshing metadata',
|
||||
[AssetJobName.RegenerateThumbnail]: `Regenerating thumbnails`,
|
||||
[AssetJobName.TranscodeVideo]: `Refreshing encoded video`,
|
||||
};
|
||||
|
||||
return messages[job];
|
||||
}
|
||||
}
|
||||
|
||||
export const api = new ImmichApi({ basePath: '/api' });
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './api';
|
||||
export * from '@immich/sdk/axios';
|
||||
export * from './utils';
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { Configuration } from '@immich/sdk/axios';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
export type ApiFp = (configuration: Configuration) => Record<any, (...arguments_: any) => any>;
|
||||
|
||||
export type OmitLast<T extends readonly unknown[]> = T extends readonly [...infer U, any?] ? U : [...T];
|
||||
|
||||
export type ApiParams<F extends ApiFp, K extends keyof ReturnType<F>> = OmitLast<Parameters<ReturnType<F>[K]>>;
|
||||
@@ -0,0 +1,63 @@
|
||||
import type { AxiosError, AxiosPromise } from 'axios';
|
||||
import {
|
||||
notificationController,
|
||||
NotificationType,
|
||||
} from '../lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '../lib/utils/handle-error';
|
||||
import { api } from './api';
|
||||
import type { UserResponseDto } from '@immich/sdk/axios';
|
||||
|
||||
export type ApiError = AxiosError<{ message: string }>;
|
||||
|
||||
export const copyToClipboard = async (secret: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(secret);
|
||||
notificationController.show({ message: 'Copied to clipboard!', type: NotificationType.Info });
|
||||
} catch (error) {
|
||||
handleError(error, 'Cannot copy to clipboard, make sure you are accessing the page through https');
|
||||
}
|
||||
};
|
||||
|
||||
export const makeSharedLinkUrl = (externalDomain: string, key: string) => {
|
||||
let url = externalDomain || window.location.origin;
|
||||
if (!url.endsWith('/')) {
|
||||
url += '/';
|
||||
}
|
||||
return `${url}share/${key}`;
|
||||
};
|
||||
|
||||
export const oauth = {
|
||||
isCallback: (location: Location) => {
|
||||
const search = location.search;
|
||||
return search.includes('code=') || search.includes('error=');
|
||||
},
|
||||
isAutoLaunchDisabled: (location: Location) => {
|
||||
const values = ['autoLaunch=0', 'password=1', 'password=true'];
|
||||
for (const value of values) {
|
||||
if (location.search.includes(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
authorize: async (location: Location) => {
|
||||
try {
|
||||
const redirectUri = location.href.split('?')[0];
|
||||
const { data } = await api.oauthApi.startOAuth({ oAuthConfigDto: { redirectUri } });
|
||||
window.location.href = data.url;
|
||||
return true;
|
||||
} catch (error) {
|
||||
handleError(error, 'Unable to login with OAuth');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
login: (location: Location) => {
|
||||
return api.oauthApi.finishOAuth({ oAuthCallbackDto: { url: location.href } });
|
||||
},
|
||||
link: (location: Location): AxiosPromise<UserResponseDto> => {
|
||||
return api.oauthApi.linkOAuthAccount({ oAuthCallbackDto: { url: location.href } });
|
||||
},
|
||||
unlink: () => {
|
||||
return api.oauthApi.unlinkOAuthAccount();
|
||||
},
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
import { AssetApi, DownloadApi, configuration } from '@immich/sdk/axios';
|
||||
|
||||
class ImmichApi {
|
||||
public downloadApi: DownloadApi;
|
||||
public assetApi: AssetApi;
|
||||
|
||||
constructor(parameters: configuration.ConfigurationParameters) {
|
||||
const config = new configuration.Configuration(parameters);
|
||||
this.downloadApi = new DownloadApi(config);
|
||||
this.assetApi = new AssetApi(config);
|
||||
}
|
||||
}
|
||||
|
||||
export const api = new ImmichApi({ basePath: '/api' });
|
||||
@@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { deleteUser, type UserResponseDto } from '@immich/sdk';
|
||||
import { api, type UserResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { handleError } from '../../utils/handle-error';
|
||||
|
||||
export let user: UserResponseDto;
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
fail: void;
|
||||
}>();
|
||||
|
||||
const handleDeleteUser = async () => {
|
||||
const deleteUser = async () => {
|
||||
try {
|
||||
const { deletedAt } = await deleteUser({ id: user.id });
|
||||
if (deletedAt == undefined) {
|
||||
const deletedUser = await api.userApi.deleteUser({ id: user.id });
|
||||
if (deletedUser.data.deletedAt == undefined) {
|
||||
dispatch('fail');
|
||||
} else {
|
||||
dispatch('success');
|
||||
@@ -26,7 +26,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<ConfirmDialogue title="Delete User" confirmText="Delete" on:confirm={handleDeleteUser} on:cancel>
|
||||
<ConfirmDialogue title="Delete User" confirmText="Delete" on:confirm={deleteUser} on:cancel>
|
||||
<svelte:fragment slot="prompt">
|
||||
<div class="flex flex-col gap-4">
|
||||
<p>
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@api';
|
||||
import Badge from '$lib/components/elements/badge.svelte';
|
||||
import JobTileButton from './job-tile-button.svelte';
|
||||
import JobTileStatus from './job-tile-status.svelte';
|
||||
import Button from '$lib/components/elements/buttons/button.svelte';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import { JobCommand, type JobCommandDto, type JobCountsDto, type QueueStatusDto } from '@immich/sdk';
|
||||
import {
|
||||
mdiAlertCircle,
|
||||
mdiAllInclusive,
|
||||
@@ -13,9 +16,6 @@
|
||||
mdiPlay,
|
||||
mdiSelectionSearch,
|
||||
} from '@mdi/js';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import JobTileButton from './job-tile-button.svelte';
|
||||
import JobTileStatus from './job-tile-status.svelte';
|
||||
|
||||
export let title: string;
|
||||
export let subtitle: string | undefined;
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { featureFlags } from '$lib/stores/server-config.store';
|
||||
import { getJobName } from '$lib/utils';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { JobCommand, JobName, sendJobCommand, type AllJobStatusResponseDto, type JobCommandDto } from '@immich/sdk';
|
||||
import { type AllJobStatusResponseDto, api, JobCommand, type JobCommandDto, JobName } from '@api';
|
||||
import type { ComponentType } from 'svelte';
|
||||
import {
|
||||
mdiFaceRecognition,
|
||||
mdiFileJpgBox,
|
||||
@@ -18,7 +18,6 @@
|
||||
mdiTagFaces,
|
||||
mdiVideo,
|
||||
} from '@mdi/js';
|
||||
import type { ComponentType } from 'svelte';
|
||||
import ConfirmDialogue from '../../shared-components/confirm-dialogue.svelte';
|
||||
import JobTile from './job-tile.svelte';
|
||||
import StorageMigrationDescription from './storage-migration-description.svelte';
|
||||
@@ -59,23 +58,23 @@
|
||||
$: jobDetails = <Partial<Record<JobName, JobDetails>>>{
|
||||
[JobName.ThumbnailGeneration]: {
|
||||
icon: mdiFileJpgBox,
|
||||
title: getJobName(JobName.ThumbnailGeneration),
|
||||
title: api.getJobName(JobName.ThumbnailGeneration),
|
||||
subtitle: 'Generate large, small and blurred thumbnails for each asset, as well as thumbnails for each person',
|
||||
},
|
||||
[JobName.MetadataExtraction]: {
|
||||
icon: mdiTable,
|
||||
title: getJobName(JobName.MetadataExtraction),
|
||||
title: api.getJobName(JobName.MetadataExtraction),
|
||||
subtitle: 'Extract metadata information from each asset, such as GPS and resolution',
|
||||
},
|
||||
[JobName.Library]: {
|
||||
icon: mdiLibraryShelves,
|
||||
title: getJobName(JobName.Library),
|
||||
title: api.getJobName(JobName.Library),
|
||||
subtitle: 'Perform library tasks',
|
||||
allText: 'ALL',
|
||||
missingText: 'REFRESH',
|
||||
},
|
||||
[JobName.Sidecar]: {
|
||||
title: getJobName(JobName.Sidecar),
|
||||
title: api.getJobName(JobName.Sidecar),
|
||||
icon: mdiFileXmlBox,
|
||||
subtitle: 'Discover or synchronize sidecar metadata from the filesystem',
|
||||
allText: 'SYNC',
|
||||
@@ -84,13 +83,13 @@
|
||||
},
|
||||
[JobName.SmartSearch]: {
|
||||
icon: mdiImageSearch,
|
||||
title: getJobName(JobName.SmartSearch),
|
||||
title: api.getJobName(JobName.SmartSearch),
|
||||
subtitle: 'Run machine learning on assets to support smart search',
|
||||
disabled: !$featureFlags.smartSearch,
|
||||
},
|
||||
[JobName.FaceDetection]: {
|
||||
icon: mdiFaceRecognition,
|
||||
title: getJobName(JobName.FaceDetection),
|
||||
title: api.getJobName(JobName.FaceDetection),
|
||||
subtitle:
|
||||
'Detect the faces in assets using machine learning. For videos, only the thumbnail is considered. "All" (re-)processes all assets. "Missing" queues assets that haven\'t been processed yet. Detected faces will be queued for Facial Recognition after Face Detection is complete, grouping them into existing or new people.',
|
||||
handleCommand: handleConfirmCommand,
|
||||
@@ -98,7 +97,7 @@
|
||||
},
|
||||
[JobName.FacialRecognition]: {
|
||||
icon: mdiTagFaces,
|
||||
title: getJobName(JobName.FacialRecognition),
|
||||
title: api.getJobName(JobName.FacialRecognition),
|
||||
subtitle:
|
||||
'Group detected faces into people. This step runs after Face Detection is complete. "All" (re-)clusters all faces. "Missing" queues faces that don\'t have a person assigned.',
|
||||
handleCommand: handleConfirmCommand,
|
||||
@@ -106,18 +105,18 @@
|
||||
},
|
||||
[JobName.VideoConversion]: {
|
||||
icon: mdiVideo,
|
||||
title: getJobName(JobName.VideoConversion),
|
||||
title: api.getJobName(JobName.VideoConversion),
|
||||
subtitle: 'Transcode videos for wider compatibility with browsers and devices',
|
||||
},
|
||||
[JobName.StorageTemplateMigration]: {
|
||||
icon: mdiFolderMove,
|
||||
title: getJobName(JobName.StorageTemplateMigration),
|
||||
title: api.getJobName(JobName.StorageTemplateMigration),
|
||||
allowForceCommand: false,
|
||||
component: StorageMigrationDescription,
|
||||
},
|
||||
[JobName.Migration]: {
|
||||
icon: mdiFolderMove,
|
||||
title: getJobName(JobName.Migration),
|
||||
title: api.getJobName(JobName.Migration),
|
||||
subtitle: 'Migrate thumbnails for assets and faces to the latest folder structure',
|
||||
allowForceCommand: false,
|
||||
},
|
||||
@@ -128,7 +127,8 @@
|
||||
const title = jobDetails[jobId]?.title;
|
||||
|
||||
try {
|
||||
jobs[jobId] = await sendJobCommand({ id: jobId, jobCommandDto: jobCommand });
|
||||
const { data } = await api.jobApi.sendJobCommand({ id: jobId, jobCommandDto: jobCommand });
|
||||
jobs[jobId] = data;
|
||||
|
||||
switch (jobCommand.command) {
|
||||
case JobCommand.Empty: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
import { restoreUser, type UserResponseDto } from '@immich/sdk';
|
||||
import { api, type UserResponseDto } from '@api';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import ConfirmDialogue from '$lib/components/shared-components/confirm-dialogue.svelte';
|
||||
|
||||
export let user: UserResponseDto;
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
fail: void;
|
||||
}>();
|
||||
|
||||
const handleRestoreUser = async () => {
|
||||
const { deletedAt } = await restoreUser({ id: user.id });
|
||||
if (deletedAt == undefined) {
|
||||
const restoreUser = async () => {
|
||||
const restoredUser = await api.userApi.restoreUser({ id: user.id });
|
||||
if (restoredUser.data.deletedAt == undefined) {
|
||||
dispatch('success');
|
||||
} else {
|
||||
dispatch('fail');
|
||||
@@ -20,13 +20,7 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<ConfirmDialogue
|
||||
title="Restore User"
|
||||
confirmText="Continue"
|
||||
confirmColor="green"
|
||||
on:confirm={handleRestoreUser}
|
||||
on:cancel
|
||||
>
|
||||
<ConfirmDialogue title="Restore User" confirmText="Continue" confirmColor="green" on:confirm={restoreUser} on:cancel>
|
||||
<svelte:fragment slot="prompt">
|
||||
<p><b>{user.name}</b>'s account will be restored.</p>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { locale } from '$lib/stores/preferences.store';
|
||||
import type { ServerStatsResponseDto } from '@api';
|
||||
import { asByteUnitString, getBytesWithUnit } from '$lib/utils/byte-units';
|
||||
import type { ServerStatsResponseDto } from '@immich/sdk';
|
||||
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
|
||||
import StatsCard from './stats-card.svelte';
|
||||
import { mdiCameraIris, mdiChartPie, mdiPlayCircle } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
|
||||
export let stats: ServerStatsResponseDto = {
|
||||
photos: 0,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<svelte:options accessors />
|
||||
|
||||
<script lang="ts">
|
||||
import { type SystemConfigDto, api } from '@api';
|
||||
import {
|
||||
NotificationType,
|
||||
notificationController,
|
||||
NotificationType,
|
||||
} from '$lib/components/shared-components/notification/notification';
|
||||
import { handleError } from '$lib/utils/handle-error';
|
||||
import { getConfig, getConfigDefaults, updateConfig, type SystemConfigDto } from '@immich/sdk';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import type { SettingsEventType } from './admin-settings';
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
export let config: SystemConfigDto;
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
const handleSave = async (update: Partial<SystemConfigDto>) => {
|
||||
try {
|
||||
const newConfig = await updateConfig({
|
||||
const { data: newConfig } = await api.systemConfigApi.updateConfig({
|
||||
systemConfigDto: {
|
||||
...savedConfig,
|
||||
...update,
|
||||
@@ -42,7 +42,7 @@
|
||||
};
|
||||
|
||||
const reset = async (configKeys: Array<keyof SystemConfigDto>) => {
|
||||
const resetConfig = await getConfig();
|
||||
const { data: resetConfig } = await api.systemConfigApi.getConfig();
|
||||
|
||||
for (const key of configKeys) {
|
||||
config = { ...config, [key]: resetConfig[key] };
|
||||
@@ -66,7 +66,10 @@
|
||||
};
|
||||
|
||||
onMount(async () => {
|
||||
[savedConfig, defaultConfig] = await Promise.all([getConfig(), getConfigDefaults()]);
|
||||
[savedConfig, defaultConfig] = await Promise.all([
|
||||
api.systemConfigApi.getConfig().then((res) => res.data),
|
||||
api.systemConfigApi.getConfigDefaults().then((res) => res.data),
|
||||
]);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { ResetOptions } from '$lib/utils/dipatch';
|
||||
import type { SystemConfigDto } from '@immich/sdk';
|
||||
import type { SystemConfigDto } from '@api';
|
||||
|
||||
export type SettingsEventType = {
|
||||
reset: ResetOptions & { configKeys: Array<keyof SystemConfigDto> };
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<script lang="ts">
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import {
|
||||
AudioCodec,
|
||||
CQMode,
|
||||
type SystemConfigDto,
|
||||
ToneMapping,
|
||||
TranscodeHWAccel,
|
||||
TranscodePolicy,
|
||||
VideoCodec,
|
||||
type SystemConfigDto,
|
||||
} from '@immich/sdk';
|
||||
import { mdiHelpCircleOutline } from '@mdi/js';
|
||||
import { isEqual, sortBy } from 'lodash-es';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
} from '@api';
|
||||
import SettingButtonsRow from '../setting-buttons-row.svelte';
|
||||
import SettingCheckboxes from '../setting-checkboxes.svelte';
|
||||
import SettingInputField, { SettingInputFieldType } from '../setting-input-field.svelte';
|
||||
import SettingSelect from '../setting-select.svelte';
|
||||
import SettingSwitch from '../setting-switch.svelte';
|
||||
import SettingCheckboxes from '../setting-checkboxes.svelte';
|
||||
import { isEqual, sortBy } from 'lodash-es';
|
||||
import { fade } from 'svelte/transition';
|
||||
import SettingAccordion from '../setting-accordion.svelte';
|
||||
import { mdiHelpCircleOutline } from '@mdi/js';
|
||||
import Icon from '$lib/components/elements/icon.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import type { SettingsEventType } from '../admin-settings';
|
||||
|
||||
export let savedConfig: SystemConfigDto;
|
||||
export let defaultConfig: SystemConfigDto;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { getJobName } from '$lib/utils';
|
||||
import { JobName, type SystemConfigDto, type SystemConfigJobDto } from '@immich/sdk';
|
||||
import { api, JobName, type SystemConfigDto, type SystemConfigJobDto } from '@api';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
@@ -28,8 +27,7 @@
|
||||
JobName.Migration,
|
||||
];
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function isSystemConfigJobDto(jobName: any): jobName is keyof SystemConfigJobDto {
|
||||
function isSystemConfigJobDto(jobName: JobName): jobName is keyof SystemConfigJobDto {
|
||||
return jobName in config.job;
|
||||
}
|
||||
</script>
|
||||
@@ -43,7 +41,7 @@
|
||||
<SettingInputField
|
||||
inputType={SettingInputFieldType.NUMBER}
|
||||
{disabled}
|
||||
label="{getJobName(jobName)} Concurrency"
|
||||
label="{api.getJobName(jobName)} Concurrency"
|
||||
desc=""
|
||||
bind:value={config.job[jobName].concurrency}
|
||||
required={true}
|
||||
@@ -52,7 +50,7 @@
|
||||
{:else}
|
||||
<SettingInputField
|
||||
inputType={SettingInputFieldType.NUMBER}
|
||||
label="{getJobName(jobName)} Concurrency"
|
||||
label="{api.getJobName(jobName)} Concurrency"
|
||||
desc=""
|
||||
value="1"
|
||||
disabled={true}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user