diff --git a/.editorconfig b/.editorconfig index 462a3da63679..e80002aa842b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -64,7 +64,7 @@ indent_style = space # Prisma # https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-schema/data-model#formatting [*.prisma] -indent_size = 4 +indent_size = 2 indent_style = space # YAML diff --git a/apps/mobile/src/components/modal/inspector/FileInfoModal.tsx b/apps/mobile/src/components/modal/inspector/FileInfoModal.tsx index 9df463d73550..e6de562e673c 100644 --- a/apps/mobile/src/components/modal/inspector/FileInfoModal.tsx +++ b/apps/mobile/src/components/modal/inspector/FileInfoModal.tsx @@ -85,10 +85,10 @@ const FileInfoModal = forwardRef((props, ref) => { value={`${byteSize(filePathData?.size_in_bytes_bytes)}`} /> {/* Duration */} - {/* {fullObjectData.data?.media_data?.duration && ( + {/* {fullObjectData.data?.exif_data?.duration && ( )} */} diff --git a/apps/server/src/main.rs b/apps/server/src/main.rs index 0c96b46d00de..268b8192c50f 100644 --- a/apps/server/src/main.rs +++ b/apps/server/src/main.rs @@ -4,7 +4,7 @@ use axum::{ extract::{FromRequestParts, State}, headers::{authorization::Basic, Authorization}, http::Request, - middleware::{self, Next}, + middleware::Next, response::{IntoResponse, Response}, routing::get, TypedHeader, @@ -29,7 +29,7 @@ async fn basic_auth( request: Request, next: Next, ) -> Response { - let request = if state.auth.len() != 0 { + let request = if !state.auth.is_empty() { let (mut parts, body) = request.into_parts(); let Ok(TypedHeader(Authorization(hdr))) = @@ -46,7 +46,7 @@ async fn basic_auth( if state .auth .get(hdr.username()) - .and_then(|pass| Some(*pass == SecStr::from(hdr.password()))) + .map(|pass| *pass == SecStr::from(hdr.password())) != Some(true) { return Response::builder() @@ -110,7 +110,7 @@ async fn main() { .into_iter() .enumerate() .filter_map(|(i, s)| { - if s.len() == 0 { + if s.is_empty() { return None; } @@ -133,7 +133,7 @@ async fn main() { }; // We require credentials in production builds (unless explicitly disabled) - if auth.len() == 0 && !disabled { + if auth.is_empty() && !disabled { #[cfg(not(debug_assertions))] { warn!("The 'SD_AUTH' environment variable is not set!"); @@ -143,7 +143,7 @@ async fn main() { } } - let state = AppState { auth }; + let _state = AppState { auth }; let (node, router) = match Node::new( data_dir, diff --git a/core/crates/prisma-helpers/src/lib.rs b/core/crates/prisma-helpers/src/lib.rs index 26d67a4bf409..3539fd60c6fc 100644 --- a/core/crates/prisma-helpers/src/lib.rs +++ b/core/crates/prisma-helpers/src/lib.rs @@ -138,7 +138,7 @@ file_path::select!(file_path_to_full_path { // File Path includes! file_path::include!(file_path_with_object { object: include { - media_data: select { + exif_data: select { resolution media_date media_location @@ -161,7 +161,7 @@ object::select!(object_for_file_identifier { object::include!(object_with_file_paths { file_paths: include { object: include { - media_data: select { + exif_data: select { resolution media_date media_location diff --git a/core/crates/sync/src/lib.rs b/core/crates/sync/src/lib.rs index f2afa081bea9..dfc5b9443dc0 100644 --- a/core/crates/sync/src/lib.rs +++ b/core/crates/sync/src/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] #![allow(clippy::unwrap_used, clippy::panic)] // TODO: Brendan remove this once you've got error handling here mod actor; diff --git a/core/prisma/schema.prisma b/core/prisma/schema.prisma index 3dfb05797504..c0ea61eea744 100644 --- a/core/prisma/schema.prisma +++ b/core/prisma/schema.prisma @@ -188,8 +188,8 @@ model FilePath { date_modified DateTime? date_indexed DateTime? - media_info MediaInfo? @relation(fields: [media_info_id], references: [id], onDelete: SetNull) - media_info_id Int? + media_info MediaInfo? @relation(fields: [media_info_id], references: [id], onDelete: SetNull) + media_info_id Int? // key Key? @relation(fields: [key_id], references: [id]) @@ -229,13 +229,13 @@ model Object { date_created DateTime? date_accessed DateTime? - tags TagOnObject[] - labels LabelOnObject[] - albums ObjectInAlbum[] - spaces ObjectInSpace[] - file_paths FilePath[] - // comments Comment[] - exif_data ExifData? + tags TagOnObject[] + labels LabelOnObject[] + albums ObjectInAlbum[] + spaces ObjectInSpace[] + file_paths FilePath[] + // comments Comment[] + exif_data ExifData? // key Key? @relation(fields: [key_id], references: [id]) @@ -267,212 +267,214 @@ model ExifData { // video_codec String? // eg: "h264, h265, av1" // audio_codec String? // eg: "opus" - object_id Int @unique - object Object @relation(fields: [object_id], references: [id], onDelete: Cascade) + object_id Int @unique + object Object @relation(fields: [object_id], references: [id], onDelete: Cascade) - @@map("exif_data") + @@map("exif_data") } model MediaInfo { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - // Internal FFmpeg properties - format String? - duration BigInt? - start_time BigInt? - bitrate BigInt? + // Internal FFmpeg properties + format String? + duration BigInt? + start_time BigInt? + bitrate BigInt? - chapters MediaChapter[] - programs MediaProgram[] + chapters MediaChapter[] + programs MediaProgram[] - metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) - metadata_id Int @unique + metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) + metadata_id Int @unique - files FilePath[] + files FilePath[] - @@map("media_info") + @@map("media_info") } model MediaChapter { - chapter_id Int + chapter_id Int - start BigInt? - end BigInt? + start BigInt? + end BigInt? - metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) - metadata_id Int @unique + metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) + metadata_id Int @unique - media_info MediaInfo @relation(fields: [media_info_id], references: [id], onDelete: Cascade) - media_info_id Int + media_info MediaInfo @relation(fields: [media_info_id], references: [id], onDelete: Cascade) + media_info_id Int - @@id(name: "likeId", [media_info_id, chapter_id]) - @@map("media_chapter") + @@id(name: "likeId", [media_info_id, chapter_id]) + @@map("media_chapter") } model MediaProgram { - program_id Int + program_id Int - name String? - streams MediaStream[] + name String? + streams MediaStream[] - metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) - metadata_id Int @unique + metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) + metadata_id Int @unique - media_info MediaInfo @relation(fields: [media_info_id], references: [id], onDelete: Cascade) - media_info_id Int + media_info MediaInfo @relation(fields: [media_info_id], references: [id], onDelete: Cascade) + media_info_id Int - @@id(name: "likeId", [media_info_id, program_id]) - @@map("media_program") + @@id(name: "likeId", [media_info_id, program_id]) + @@map("media_program") } model MediaStream { - stream_id Int + stream_id Int - name String? - codec MediaCodec? - aspect_ratio_num Int? - aspect_ratio_Den Int? - frames_per_second Decimal? - time_base_real Decimal? - dispositions String? + name String? + codec MediaCodec? + aspect_ratio_num Int? + aspect_ratio_den Int? + frames_per_second_num Int? + frames_per_second_den Int? + time_base_real_den Int? + time_base_real_num Int? + dispositions String? - metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) - metadata_id Int @unique + metadata MediaMetadata @relation(fields: [metadata_id], references: [id], onDelete: Cascade) + metadata_id Int @unique - program MediaProgram @relation(fields: [media_info_id, program_id], references: [media_info_id, program_id], onDelete: Cascade) - program_id Int - media_info_id Int + program MediaProgram @relation(fields: [media_info_id, program_id], references: [media_info_id, program_id], onDelete: Cascade) + program_id Int + media_info_id Int - @@id(name: "likeId", [media_info_id, program_id, stream_id]) - @@unique([media_info_id, program_id]) - @@map("media_stream") + @@id(name: "likeId", [media_info_id, program_id, stream_id]) + @@unique([media_info_id, program_id]) + @@map("media_stream") } model MediaCodec { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - type String? - tag String? - name String? - profile String? - bit_rate BigInt? + type String? + tag String? + name String? + profile String? + bit_rate BigInt? - video_props MediaVideoProps? - audio_props MediaAudioProps? - subtitle_props MediaSubtitleProps? + video_props MediaVideoProps? + audio_props MediaAudioProps? + subtitle_props MediaSubtitleProps? - codec MediaStream @relation(fields: [media_info_id, program_id, stream_id], references: [media_info_id, program_id, stream_id], onDelete: Cascade) - stream_id Int - program_id Int - media_info_id Int + codec MediaStream @relation(fields: [media_info_id, program_id, stream_id], references: [media_info_id, program_id, stream_id], onDelete: Cascade) + stream_id Int + program_id Int + media_info_id Int - @@unique([media_info_id, program_id, stream_id]) - @@map("media_codec") + @@unique([media_info_id, program_id, stream_id]) + @@map("media_codec") } model MediaVideoProps { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - pixel_format String? - color_range String? - bits_per_channel Int? - color_space String? - color_primaries String? - color_transfer String? - field_order String? - chroma_location String? - coded_width Int? - coded_height Int? - aspect_ratio_num Int? - aspect_ratio_Den Int? - properties String + pixel_format String? + color_range String? + bits_per_channel Int? + color_space String? + color_primaries String? + color_transfer String? + field_order String? + chroma_location String? + coded_width Int? + coded_height Int? + aspect_ratio_num Int? + aspect_ratio_Den Int? + properties String - codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) - codec_id Int @unique + codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) + codec_id Int @unique - @@map("media_video") + @@map("media_video_props") } model MediaAudioProps { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - delay Int? - padding Int? - sample_rate Int? - sample_format String? - bit_per_sample Int? - channel_layout String? + delay Int? + padding Int? + sample_rate Int? + sample_format String? + bit_per_sample Int? + channel_layout String? - codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) - codec_id Int @unique + codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) + codec_id Int @unique - @@map("media_audio") + @@map("media_audio_props") } model MediaSubtitleProps { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - width Int? - height Int? + width Int? + height Int? - codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) - codec_id Int @unique + codec MediaCodec @relation(fields: [codec_id], references: [id], onDelete: Cascade) + codec_id Int @unique - @@map("media_subtitle") + @@map("media_subtitle_props") } model MediaMetadata { - id Int @id @default(autoincrement()) - - // FFmpeg Metadata API - // https://ffmpeg.org/doxygen/trunk/group__metadata__api.html - album String? // -- name of the set this work belongs to - album_artist String? // -- main creator of the set/album, if different from artist. - // e.g. "Various Artists" for compilation albums. - artist String? // -- main creator of the work - comment String? // -- any additional description of the file. - composer String? // -- who composed the work, if different from artist. - copyright String? // -- name of copyright holder. - creation_time DateTime? // -- date when the file was created, preferably in ISO 8601. - date DateTime? // -- date when the work was created, preferably in ISO 8601. - disc Int? // -- number of a subset, e.g. disc in a multi-disc collection. - encoder String? // -- name/settings of the software/hardware that produced the file. - encoded_by String? // -- person/group who created the file. - filename String? // -- original name of the file. - genre String? - language String? // -- main language in which the work is performed, preferably - // in ISO 639-2 format. Multiple languages can be specified by - // separating them with commas. - performer String? // -- artist who performed the work, if different from artist. - // E.g for "Also sprach Zarathustra", artist would be "Richard - // Strauss" and performer "London Philharmonic Orchestra". - publisher String? // -- name of the label/publisher. - service_name String? // -- name of the service in broadcasting (channel name). - service_provider String? // -- name of the service provider in broadcasting. - title String? // -- name of the work. - track Int? // -- number of this work in the set, can be in form current/total. - variant_bitrate Int? // -- the total bitrate of the bitrate variant that the current stream is part of - - custom CustomMetadata[] - - media_info MediaInfo? - media_chapter MediaChapter? - media_program MediaProgram? - media_stream MediaStream? - - @@map("media_metadata") + id Int @id @default(autoincrement()) + + // FFmpeg Metadata API + // https://ffmpeg.org/doxygen/trunk/group__metadata__api.html + album String? // -- name of the set this work belongs to + album_artist String? // -- main creator of the set/album, if different from artist. + // e.g. "Various Artists" for compilation albums. + artist String? // -- main creator of the work + comment String? // -- any additional description of the file. + composer String? // -- who composed the work, if different from artist. + copyright String? // -- name of copyright holder. + creation_time DateTime? // -- date when the file was created, preferably in ISO 8601. + date DateTime? // -- date when the work was created, preferably in ISO 8601. + disc Int? // -- number of a subset, e.g. disc in a multi-disc collection. + encoder String? // -- name/settings of the software/hardware that produced the file. + encoded_by String? // -- person/group who created the file. + filename String? // -- original name of the file. + genre String? + language String? // -- main language in which the work is performed, preferably + // in ISO 639-2 format. Multiple languages can be specified by + // separating them with commas. + performer String? // -- artist who performed the work, if different from artist. + // E.g for "Also sprach Zarathustra", artist would be "Richard + // Strauss" and performer "London Philharmonic Orchestra". + publisher String? // -- name of the label/publisher. + service_name String? // -- name of the service in broadcasting (channel name). + service_provider String? // -- name of the service provider in broadcasting. + title String? // -- name of the work. + track Int? // -- number of this work in the set, can be in form current/total. + variant_bitrate Int? // -- the total bitrate of the bitrate variant that the current stream is part of + + custom CustomMetadata[] + + media_info MediaInfo? + media_chapter MediaChapter? + media_program MediaProgram? + media_stream MediaStream? + + @@map("media_metadata") } model CustomMetadata { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) - key String? - value String? + key String? + value String? - media_metadata MediaMetadata @relation(fields: [media_metadata_id], references: [id], onDelete: Cascade) - media_metadata_id Int @unique + media_metadata MediaMetadata @relation(fields: [media_metadata_id], references: [id], onDelete: Cascade) + media_metadata_id Int @unique - @@map("custom_metadata") + @@map("custom_metadata") } //// Tag //// diff --git a/core/src/api/files.rs b/core/src/api/files.rs index c834175da371..4f345f7cd29b 100644 --- a/core/src/api/files.rs +++ b/core/src/api/files.rs @@ -561,7 +561,7 @@ pub(crate) fn mount() -> AlphaRouter { ); #[cfg(not(any(target_os = "ios", target_os = "android")))] - trash::delete(&full_path).unwrap(); + trash::delete(full_path).unwrap(); Ok(()) } diff --git a/core/src/api/search/mod.rs b/core/src/api/search/mod.rs index a00ddfb1ca3a..1afd176fd5ca 100644 --- a/core/src/api/search/mod.rs +++ b/core/src/api/search/mod.rs @@ -36,7 +36,7 @@ pub mod object; pub mod saved; mod utils; -pub use self::{file_path::*, object::*, utils::*}; +pub use self::{file_path::*, object::*}; use super::{Ctx, R}; @@ -176,12 +176,9 @@ pub fn mount() -> AlphaRouter { }).collect::>() )]) .exec() - .await - .and_then(|l| { - Ok(l.into_iter() + .await.map(|l| l.into_iter() .filter_map(|item| item.path.clone().map(|l| (l, item))) .collect::>()) - }) .map_err(|err| error!("Looking up locations failed: {err:?}")) .unwrap_or_default(); @@ -261,7 +258,7 @@ pub fn mount() -> AlphaRouter { }; } - if to_generate.len() > 0 { + if !to_generate.is_empty() { node.thumbnailer .new_ephemeral_thumbnails_batch(BatchToProcess::new( to_generate, diff --git a/core/src/lib.rs b/core/src/lib.rs index 3a3306545f45..2781eccab65b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "256"] #![warn(clippy::unwrap_used, clippy::panic)] use crate::{ diff --git a/core/src/location/mod.rs b/core/src/location/mod.rs index f99418ce96c3..f5a79cf29eb6 100644 --- a/core/src/location/mod.rs +++ b/core/src/location/mod.rs @@ -23,7 +23,7 @@ use sd_sync::*; use sd_utils::{ db::{maybe_missing, MissingFieldError}, error::{FileIOError, NonUtf8PathError}, - msgpack, uuid_to_bytes, + msgpack, }; use std::{ diff --git a/crates/prisma/src/lib.rs b/crates/prisma/src/lib.rs index 5a5a5f3b9ab0..4f44660fa5f4 100644 --- a/crates/prisma/src/lib.rs +++ b/crates/prisma/src/lib.rs @@ -1,3 +1,5 @@ +#![recursion_limit = "256"] + #[allow(warnings, unused)] pub mod prisma; #[allow(warnings, unused)] diff --git a/crates/sync/src/compressed.rs b/crates/sync/src/compressed.rs index d4b1adf9e022..2b1afe3ec065 100644 --- a/crates/sync/src/compressed.rs +++ b/crates/sync/src/compressed.rs @@ -25,7 +25,7 @@ impl CompressedCRDTOperations { let mut instance_id = first.instance; let mut instance = vec![]; - let mut model_str = first.model.clone(); + let mut model_str = first.model; let mut model = vec![]; let mut record_id = first.record_id.clone(); @@ -38,7 +38,7 @@ impl CompressedCRDTOperations { std::mem::take(&mut record), )); instance.push(( - std::mem::replace(&mut model_str, op.model.clone()), + std::mem::replace(&mut model_str, op.model), std::mem::take(&mut model), )); compressed.push(( @@ -51,7 +51,7 @@ impl CompressedCRDTOperations { std::mem::take(&mut record), )); instance.push(( - std::mem::replace(&mut model_str, op.model.clone()), + std::mem::replace(&mut model_str, op.model), std::mem::take(&mut model), )); } else if record_id != op.record_id { @@ -80,7 +80,7 @@ impl CompressedCRDTOperations { for op in record { ops.push(CRDTOperation { instance: instance_id, - model: model_str.clone(), + model: model_str, record_id: record_id.clone(), timestamp: op.timestamp, data: op.data, diff --git a/docs/product/getting-started/setup.mdx b/docs/product/getting-started/setup.mdx index 0aba9699da81..8527feb44992 100644 --- a/docs/product/getting-started/setup.mdx +++ b/docs/product/getting-started/setup.mdx @@ -44,9 +44,10 @@ docker run -d --name spacedrive -p 8080:8080 -e SD_AUTH=admin,spacedrive -v /var When using the Spacedrive server you can use the `SD_AUTH` environment variable to configure authentication. Valid values: - - `SD_AUTH=disabled` - Disables authentication. - - `SD_AUTH=username:password` - Enables authentication for a single user. - - `SD_AUTH=username:password,username1:password1` - Enables authentication with multiple users (you can add as many users as you want). + +- `SD_AUTH=disabled` - Disables authentication. +- `SD_AUTH=username:password` - Enables authentication for a single user. +- `SD_AUTH=username:password,username1:password1` - Enables authentication with multiple users (you can add as many users as you want). ### Mobile (Preview) diff --git a/packages/client/src/core.ts b/packages/client/src/core.ts index bd140127af65..8a8c9702757e 100644 --- a/packages/client/src/core.ts +++ b/packages/client/src/core.ts @@ -2,146 +2,146 @@ // This file was generated by [rspc](https://github.com/oscartbeaumont/rspc). Do not edit this file manually. export type Procedures = { - queries: - { key: "auth.me", input: never, result: { id: string; email: string } } | - { key: "backups.getAll", input: never, result: GetAll } | - { key: "buildInfo", input: never, result: BuildInfo } | - { key: "cloud.getApiOrigin", input: never, result: string } | - { key: "cloud.library.get", input: LibraryArgs, result: { id: string; uuid: string; name: string; instances: CloudInstance[]; ownerId: string } | null } | - { key: "cloud.library.list", input: never, result: CloudLibrary[] } | - { key: "cloud.locations.list", input: never, result: CloudLocation[] } | - { key: "ephemeralFiles.getMediaData", input: string, result: ({ type: "Image" } & ImageMetadata) | ({ type: "Video" } & VideoMetadata) | ({ type: "Audio" } & AudioMetadata) | null } | - { key: "files.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | - { key: "files.getConvertibleImageExtensions", input: never, result: string[] } | - { key: "files.getMediaData", input: LibraryArgs, result: MediaMetadata } | - { key: "files.getPath", input: LibraryArgs, result: string | null } | - { key: "invalidation.test-invalidate", input: never, result: number } | - { key: "jobs.isActive", input: LibraryArgs, result: boolean } | - { key: "jobs.reports", input: LibraryArgs, result: JobGroup[] } | - { key: "labels.count", input: LibraryArgs, result: number } | - { key: "labels.get", input: LibraryArgs, result: { id: number; name: string; date_created: string | null; date_modified: string | null } | null } | - { key: "labels.getForObject", input: LibraryArgs, result: Label[] } | - { key: "labels.getWithObjects", input: LibraryArgs, result: { [key in number]: { date_created: string; object: { id: number } }[] } } | - { key: "labels.list", input: LibraryArgs, result: Label[] } | - { key: "labels.listWithThumbnails", input: LibraryArgs, result: ExplorerItem[] } | - { key: "library.kindStatistics", input: LibraryArgs, result: KindStatistics } | - { key: "library.list", input: never, result: NormalisedResults } | - { key: "library.statistics", input: LibraryArgs, result: StatisticsResponse } | - { key: "locations.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | - { key: "locations.getWithRules", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | - { key: "locations.indexer_rules.get", input: LibraryArgs, result: NormalisedResult } | - { key: "locations.indexer_rules.list", input: LibraryArgs, result: NormalisedResults } | - { key: "locations.indexer_rules.listForLocation", input: LibraryArgs, result: NormalisedResults } | - { key: "locations.list", input: LibraryArgs, result: NormalisedResults } | - { key: "locations.systemLocations", input: never, result: SystemLocations } | - { key: "models.image_detection.list", input: never, result: string[] } | - { key: "nodeState", input: never, result: NodeState } | - { key: "nodes.listLocations", input: LibraryArgs, result: ExplorerItem[] } | - { key: "notifications.dismiss", input: NotificationId, result: null } | - { key: "notifications.dismissAll", input: never, result: null } | - { key: "notifications.get", input: never, result: Notification[] } | - { key: "p2p.state", input: never, result: JsonValue } | - { key: "preferences.get", input: LibraryArgs, result: LibraryPreferences } | - { key: "search.objects", input: LibraryArgs, result: SearchData } | - { key: "search.objectsCount", input: LibraryArgs<{ filters?: SearchFilterArgs[] }>, result: number } | - { key: "search.paths", input: LibraryArgs, result: SearchData } | - { key: "search.pathsCount", input: LibraryArgs<{ filters?: SearchFilterArgs[] }>, result: number } | - { key: "search.saved.get", input: LibraryArgs, result: { id: number; pub_id: number[]; target: string | null; search: string | null; filters: string | null; name: string | null; icon: string | null; description: string | null; date_created: string | null; date_modified: string | null } | null } | - { key: "search.saved.list", input: LibraryArgs, result: SavedSearch[] } | - { key: "sync.enabled", input: LibraryArgs, result: boolean } | - { key: "sync.messages", input: LibraryArgs, result: CRDTOperation[] } | - { key: "tags.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | - { key: "tags.getForObject", input: LibraryArgs, result: NormalisedResults } | - { key: "tags.getWithObjects", input: LibraryArgs, result: { [key in number]: ({ date_created: string | null; object: { id: number } })[] } } | - { key: "tags.list", input: LibraryArgs, result: NormalisedResults } | + queries: + { key: "auth.me", input: never, result: { id: string; email: string } } | + { key: "backups.getAll", input: never, result: GetAll } | + { key: "buildInfo", input: never, result: BuildInfo } | + { key: "cloud.getApiOrigin", input: never, result: string } | + { key: "cloud.library.get", input: LibraryArgs, result: { id: string; uuid: string; name: string; instances: CloudInstance[]; ownerId: string } | null } | + { key: "cloud.library.list", input: never, result: CloudLibrary[] } | + { key: "cloud.locations.list", input: never, result: CloudLocation[] } | + { key: "ephemeralFiles.getMediaData", input: string, result: ({ type: "Image" } & ImageMetadata) | ({ type: "Video" } & VideoMetadata) | ({ type: "Audio" } & AudioMetadata) | null } | + { key: "files.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | + { key: "files.getConvertibleImageExtensions", input: never, result: string[] } | + { key: "files.getMediaData", input: LibraryArgs, result: MediaMetadata } | + { key: "files.getPath", input: LibraryArgs, result: string | null } | + { key: "invalidation.test-invalidate", input: never, result: number } | + { key: "jobs.isActive", input: LibraryArgs, result: boolean } | + { key: "jobs.reports", input: LibraryArgs, result: JobGroup[] } | + { key: "labels.count", input: LibraryArgs, result: number } | + { key: "labels.get", input: LibraryArgs, result: { id: number; name: string; date_created: string | null; date_modified: string | null } | null } | + { key: "labels.getForObject", input: LibraryArgs, result: Label[] } | + { key: "labels.getWithObjects", input: LibraryArgs, result: { [key in number]: { date_created: string; object: { id: number } }[] } } | + { key: "labels.list", input: LibraryArgs, result: Label[] } | + { key: "labels.listWithThumbnails", input: LibraryArgs, result: ExplorerItem[] } | + { key: "library.kindStatistics", input: LibraryArgs, result: KindStatistics } | + { key: "library.list", input: never, result: NormalisedResults } | + { key: "library.statistics", input: LibraryArgs, result: StatisticsResponse } | + { key: "locations.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | + { key: "locations.getWithRules", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | + { key: "locations.indexer_rules.get", input: LibraryArgs, result: NormalisedResult } | + { key: "locations.indexer_rules.list", input: LibraryArgs, result: NormalisedResults } | + { key: "locations.indexer_rules.listForLocation", input: LibraryArgs, result: NormalisedResults } | + { key: "locations.list", input: LibraryArgs, result: NormalisedResults } | + { key: "locations.systemLocations", input: never, result: SystemLocations } | + { key: "models.image_detection.list", input: never, result: string[] } | + { key: "nodeState", input: never, result: NodeState } | + { key: "nodes.listLocations", input: LibraryArgs, result: ExplorerItem[] } | + { key: "notifications.dismiss", input: NotificationId, result: null } | + { key: "notifications.dismissAll", input: never, result: null } | + { key: "notifications.get", input: never, result: Notification[] } | + { key: "p2p.state", input: never, result: JsonValue } | + { key: "preferences.get", input: LibraryArgs, result: LibraryPreferences } | + { key: "search.objects", input: LibraryArgs, result: SearchData } | + { key: "search.objectsCount", input: LibraryArgs<{ filters?: SearchFilterArgs[] }>, result: number } | + { key: "search.paths", input: LibraryArgs, result: SearchData } | + { key: "search.pathsCount", input: LibraryArgs<{ filters?: SearchFilterArgs[] }>, result: number } | + { key: "search.saved.get", input: LibraryArgs, result: { id: number; pub_id: number[]; target: string | null; search: string | null; filters: string | null; name: string | null; icon: string | null; description: string | null; date_created: string | null; date_modified: string | null } | null } | + { key: "search.saved.list", input: LibraryArgs, result: SavedSearch[] } | + { key: "sync.enabled", input: LibraryArgs, result: boolean } | + { key: "sync.messages", input: LibraryArgs, result: CRDTOperation[] } | + { key: "tags.get", input: LibraryArgs, result: { item: Reference; nodes: CacheNode[] } | null } | + { key: "tags.getForObject", input: LibraryArgs, result: NormalisedResults } | + { key: "tags.getWithObjects", input: LibraryArgs, result: { [key in number]: ({ date_created: string | null; object: { id: number } })[] } } | + { key: "tags.list", input: LibraryArgs, result: NormalisedResults } | { key: "volumes.list", input: never, result: NormalisedResults }, - mutations: - { key: "api.sendFeedback", input: Feedback, result: null } | - { key: "auth.logout", input: never, result: null } | - { key: "backups.backup", input: LibraryArgs, result: string } | - { key: "backups.delete", input: string, result: null } | - { key: "backups.restore", input: string, result: null } | - { key: "cloud.library.create", input: LibraryArgs, result: null } | - { key: "cloud.library.join", input: string, result: LibraryConfigWrapped } | - { key: "cloud.library.sync", input: LibraryArgs, result: null } | - { key: "cloud.locations.create", input: string, result: CloudLocation } | - { key: "cloud.locations.remove", input: string, result: CloudLocation } | - { key: "cloud.locations.testing", input: TestingParams, result: null } | - { key: "cloud.setApiOrigin", input: string, result: null } | - { key: "ephemeralFiles.copyFiles", input: LibraryArgs, result: null } | - { key: "ephemeralFiles.createFile", input: LibraryArgs, result: string } | - { key: "ephemeralFiles.createFolder", input: LibraryArgs, result: string } | - { key: "ephemeralFiles.cutFiles", input: LibraryArgs, result: null } | - { key: "ephemeralFiles.deleteFiles", input: LibraryArgs, result: null } | - { key: "ephemeralFiles.moveToTrash", input: LibraryArgs, result: null } | - { key: "ephemeralFiles.renameFile", input: LibraryArgs, result: null } | - { key: "files.convertImage", input: LibraryArgs, result: null } | - { key: "files.copyFiles", input: LibraryArgs, result: null } | - { key: "files.createFile", input: LibraryArgs, result: string } | - { key: "files.createFolder", input: LibraryArgs, result: string } | - { key: "files.cutFiles", input: LibraryArgs, result: null } | - { key: "files.deleteFiles", input: LibraryArgs, result: null } | - { key: "files.eraseFiles", input: LibraryArgs, result: null } | - { key: "files.moveToTrash", input: LibraryArgs, result: null } | - { key: "files.removeAccessTime", input: LibraryArgs, result: null } | - { key: "files.renameFile", input: LibraryArgs, result: null } | - { key: "files.setFavorite", input: LibraryArgs, result: null } | - { key: "files.setNote", input: LibraryArgs, result: null } | - { key: "files.updateAccessTime", input: LibraryArgs, result: null } | - { key: "invalidation.test-invalidate-mutation", input: LibraryArgs, result: null } | - { key: "jobs.cancel", input: LibraryArgs, result: null } | - { key: "jobs.clear", input: LibraryArgs, result: null } | - { key: "jobs.clearAll", input: LibraryArgs, result: null } | - { key: "jobs.generateLabelsForLocation", input: LibraryArgs, result: null } | - { key: "jobs.generateThumbsForLocation", input: LibraryArgs, result: null } | - { key: "jobs.identifyUniqueFiles", input: LibraryArgs, result: null } | - { key: "jobs.objectValidator", input: LibraryArgs, result: null } | - { key: "jobs.pause", input: LibraryArgs, result: null } | - { key: "jobs.resume", input: LibraryArgs, result: null } | - { key: "labels.delete", input: LibraryArgs, result: null } | - { key: "library.create", input: CreateLibraryArgs, result: NormalisedResult } | - { key: "library.delete", input: string, result: null } | - { key: "library.edit", input: EditLibraryArgs, result: null } | - { key: "library.startActor", input: LibraryArgs, result: null } | - { key: "library.stopActor", input: LibraryArgs, result: null } | - { key: "library.vaccumDb", input: LibraryArgs, result: null } | - { key: "locations.addLibrary", input: LibraryArgs, result: number | null } | - { key: "locations.create", input: LibraryArgs, result: number | null } | - { key: "locations.delete", input: LibraryArgs, result: null } | - { key: "locations.fullRescan", input: LibraryArgs, result: null } | - { key: "locations.indexer_rules.create", input: LibraryArgs, result: null } | - { key: "locations.indexer_rules.delete", input: LibraryArgs, result: null } | - { key: "locations.relink", input: LibraryArgs, result: number } | - { key: "locations.subPathRescan", input: LibraryArgs, result: null } | - { key: "locations.update", input: LibraryArgs, result: null } | - { key: "nodes.edit", input: ChangeNodeNameArgs, result: null } | - { key: "nodes.updateThumbnailerPreferences", input: UpdateThumbnailerPreferences, result: null } | - { key: "p2p.acceptSpacedrop", input: [string, string | null], result: null } | - { key: "p2p.cancelSpacedrop", input: string, result: null } | - { key: "p2p.debugConnect", input: RemoteIdentity, result: string } | - { key: "p2p.spacedrop", input: SpacedropArgs, result: string } | - { key: "preferences.update", input: LibraryArgs, result: null } | - { key: "search.saved.create", input: LibraryArgs<{ name: string; target?: SearchTarget; search?: string | null; filters?: string | null; description?: string | null; icon?: string | null }>, result: null } | - { key: "search.saved.delete", input: LibraryArgs, result: null } | - { key: "search.saved.update", input: LibraryArgs<[number, Args]>, result: null } | - { key: "sync.enable", input: LibraryArgs, result: null } | - { key: "tags.assign", input: LibraryArgs<{ targets: Target[]; tag_id: number; unassign: boolean }>, result: null } | - { key: "tags.create", input: LibraryArgs, result: Tag } | - { key: "tags.delete", input: LibraryArgs, result: null } | - { key: "tags.update", input: LibraryArgs, result: null } | + mutations: + { key: "api.sendFeedback", input: Feedback, result: null } | + { key: "auth.logout", input: never, result: null } | + { key: "backups.backup", input: LibraryArgs, result: string } | + { key: "backups.delete", input: string, result: null } | + { key: "backups.restore", input: string, result: null } | + { key: "cloud.library.create", input: LibraryArgs, result: null } | + { key: "cloud.library.join", input: string, result: LibraryConfigWrapped } | + { key: "cloud.library.sync", input: LibraryArgs, result: null } | + { key: "cloud.locations.create", input: string, result: CloudLocation } | + { key: "cloud.locations.remove", input: string, result: CloudLocation } | + { key: "cloud.locations.testing", input: TestingParams, result: null } | + { key: "cloud.setApiOrigin", input: string, result: null } | + { key: "ephemeralFiles.copyFiles", input: LibraryArgs, result: null } | + { key: "ephemeralFiles.createFile", input: LibraryArgs, result: string } | + { key: "ephemeralFiles.createFolder", input: LibraryArgs, result: string } | + { key: "ephemeralFiles.cutFiles", input: LibraryArgs, result: null } | + { key: "ephemeralFiles.deleteFiles", input: LibraryArgs, result: null } | + { key: "ephemeralFiles.moveToTrash", input: LibraryArgs, result: null } | + { key: "ephemeralFiles.renameFile", input: LibraryArgs, result: null } | + { key: "files.convertImage", input: LibraryArgs, result: null } | + { key: "files.copyFiles", input: LibraryArgs, result: null } | + { key: "files.createFile", input: LibraryArgs, result: string } | + { key: "files.createFolder", input: LibraryArgs, result: string } | + { key: "files.cutFiles", input: LibraryArgs, result: null } | + { key: "files.deleteFiles", input: LibraryArgs, result: null } | + { key: "files.eraseFiles", input: LibraryArgs, result: null } | + { key: "files.moveToTrash", input: LibraryArgs, result: null } | + { key: "files.removeAccessTime", input: LibraryArgs, result: null } | + { key: "files.renameFile", input: LibraryArgs, result: null } | + { key: "files.setFavorite", input: LibraryArgs, result: null } | + { key: "files.setNote", input: LibraryArgs, result: null } | + { key: "files.updateAccessTime", input: LibraryArgs, result: null } | + { key: "invalidation.test-invalidate-mutation", input: LibraryArgs, result: null } | + { key: "jobs.cancel", input: LibraryArgs, result: null } | + { key: "jobs.clear", input: LibraryArgs, result: null } | + { key: "jobs.clearAll", input: LibraryArgs, result: null } | + { key: "jobs.generateLabelsForLocation", input: LibraryArgs, result: null } | + { key: "jobs.generateThumbsForLocation", input: LibraryArgs, result: null } | + { key: "jobs.identifyUniqueFiles", input: LibraryArgs, result: null } | + { key: "jobs.objectValidator", input: LibraryArgs, result: null } | + { key: "jobs.pause", input: LibraryArgs, result: null } | + { key: "jobs.resume", input: LibraryArgs, result: null } | + { key: "labels.delete", input: LibraryArgs, result: null } | + { key: "library.create", input: CreateLibraryArgs, result: NormalisedResult } | + { key: "library.delete", input: string, result: null } | + { key: "library.edit", input: EditLibraryArgs, result: null } | + { key: "library.startActor", input: LibraryArgs, result: null } | + { key: "library.stopActor", input: LibraryArgs, result: null } | + { key: "library.vaccumDb", input: LibraryArgs, result: null } | + { key: "locations.addLibrary", input: LibraryArgs, result: number | null } | + { key: "locations.create", input: LibraryArgs, result: number | null } | + { key: "locations.delete", input: LibraryArgs, result: null } | + { key: "locations.fullRescan", input: LibraryArgs, result: null } | + { key: "locations.indexer_rules.create", input: LibraryArgs, result: null } | + { key: "locations.indexer_rules.delete", input: LibraryArgs, result: null } | + { key: "locations.relink", input: LibraryArgs, result: number } | + { key: "locations.subPathRescan", input: LibraryArgs, result: null } | + { key: "locations.update", input: LibraryArgs, result: null } | + { key: "nodes.edit", input: ChangeNodeNameArgs, result: null } | + { key: "nodes.updateThumbnailerPreferences", input: UpdateThumbnailerPreferences, result: null } | + { key: "p2p.acceptSpacedrop", input: [string, string | null], result: null } | + { key: "p2p.cancelSpacedrop", input: string, result: null } | + { key: "p2p.debugConnect", input: RemoteIdentity, result: string } | + { key: "p2p.spacedrop", input: SpacedropArgs, result: string } | + { key: "preferences.update", input: LibraryArgs, result: null } | + { key: "search.saved.create", input: LibraryArgs<{ name: string; target?: SearchTarget; search?: string | null; filters?: string | null; description?: string | null; icon?: string | null }>, result: null } | + { key: "search.saved.delete", input: LibraryArgs, result: null } | + { key: "search.saved.update", input: LibraryArgs<[number, Args]>, result: null } | + { key: "sync.enable", input: LibraryArgs, result: null } | + { key: "tags.assign", input: LibraryArgs<{ targets: Target[]; tag_id: number; unassign: boolean }>, result: null } | + { key: "tags.create", input: LibraryArgs, result: Tag } | + { key: "tags.delete", input: LibraryArgs, result: null } | + { key: "tags.update", input: LibraryArgs, result: null } | { key: "toggleFeatureFlag", input: BackendFeature, result: null }, - subscriptions: - { key: "auth.loginSession", input: never, result: Response } | - { key: "invalidation.listen", input: never, result: InvalidateOperationEvent[] } | - { key: "jobs.newThumbnail", input: LibraryArgs, result: string[] } | - { key: "jobs.progress", input: LibraryArgs, result: JobProgressEvent } | - { key: "library.actors", input: LibraryArgs, result: { [key in string]: boolean } } | - { key: "locations.online", input: never, result: number[][] } | - { key: "locations.quickRescan", input: LibraryArgs, result: null } | - { key: "notifications.listen", input: never, result: Notification } | - { key: "p2p.events", input: never, result: P2PEvent } | - { key: "search.ephemeralPaths", input: LibraryArgs, result: EphemeralPathsResultItem } | - { key: "sync.active", input: LibraryArgs, result: SyncStatus } | + subscriptions: + { key: "auth.loginSession", input: never, result: Response } | + { key: "invalidation.listen", input: never, result: InvalidateOperationEvent[] } | + { key: "jobs.newThumbnail", input: LibraryArgs, result: string[] } | + { key: "jobs.progress", input: LibraryArgs, result: JobProgressEvent } | + { key: "library.actors", input: LibraryArgs, result: { [key in string]: boolean } } | + { key: "locations.online", input: never, result: number[][] } | + { key: "locations.quickRescan", input: LibraryArgs, result: null } | + { key: "notifications.listen", input: never, result: Notification } | + { key: "p2p.events", input: never, result: P2PEvent } | + { key: "search.ephemeralPaths", input: LibraryArgs, result: EphemeralPathsResultItem } | + { key: "sync.active", input: LibraryArgs, result: SyncStatus } | { key: "sync.newMessage", input: LibraryArgs, result: null } }; @@ -151,7 +151,7 @@ export type AudioMetadata = { duration: number | null; audio_codec: string | nul /** * All of the feature flags provided by the core itself. The frontend has it's own set of feature flags! - * + * * If you want a variant of this to show up on the frontend it must be added to `backendFeatures` in `useFeatureFlag.tsx` */ export type BackendFeature = "filesOverP2P" | "cloudSync" @@ -178,19 +178,19 @@ export type CloudLocation = { id: string; name: string } export type ColorProfile = "Normal" | "Custom" | "HDRNoOriginal" | "HDRWithOriginal" | "OriginalForHDR" | "Panorama" | "PortraitHDR" | "Portrait" -export type Composite = +export type Composite = /** * The data is present, but we're unable to determine what they mean */ -"Unknown" | +"Unknown" | /** * Not a composite image */ -"False" | +"False" | /** * A general composite image */ -"General" | +"General" | /** * The composite image was captured while shooting */ @@ -248,6 +248,8 @@ export type EphemeralRenameMany = { from_pattern: FromPattern; to_pattern: strin export type EphemeralRenameOne = { from_path: string; to: string } +export type ExifDataOrder = { field: "epochTime"; value: SortOrder } + export type ExplorerItem = { type: "Path"; thumbnail: string[] | null; item: FilePathWithObject } | { type: "Object"; thumbnail: string[] | null; item: ObjectWithFilePaths } | { type: "Location"; item: Location } | { type: "NonIndexedPath"; thumbnail: string[] | null; item: NonIndexedPathItem } | { type: "SpacedropPeer"; item: PeerMetadata } | { type: "Label"; thumbnails: string[][]; item: LabelWithObjects } export type ExplorerLayout = "grid" | "list" | "media" @@ -258,7 +260,7 @@ export type Feedback = { message: string; emoji: number } export type FileCreateContextTypes = "empty" | "text" -export type FilePath = { id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null } +export type FilePath = { id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null; media_info_id: number | null } export type FilePathCursor = { isDir: boolean; variant: FilePathCursorVariant } @@ -272,48 +274,48 @@ export type FilePathOrder = { field: "name"; value: SortOrder } | { field: "size export type FilePathSearchArgs = { take?: number | null; orderAndPagination?: OrderAndPagination | null; filters?: SearchFilterArgs[]; groupDirectories?: boolean } -export type FilePathWithObject = { id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null; object: { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; media_data: { resolution: number[] | null; media_date: number[] | null; media_location: number[] | null; camera_data: number[] | null; artist: string | null; description: string | null; copyright: string | null; exif_version: string | null } | null } | null } +export type FilePathWithObject = { id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null; media_info_id: number | null; object: { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; exif_data: { resolution: number[] | null; media_date: number[] | null; media_location: number[] | null; camera_data: number[] | null; artist: string | null; description: string | null; copyright: string | null; exif_version: string | null } | null } | null } -export type Flash = { +export type Flash = { /** * Specifies how flash was used (on, auto, off, forced, onvalid) - * + * * [`FlashMode::Unknown`] isn't a valid EXIF state, but it's included as the default, * just in case we're unable to correctly match it to a known (valid) state. - * + * * This type should only ever be evaluated if flash EXIF data is present, so having this as a non-option shouldn't be an issue. */ -mode: FlashMode; +mode: FlashMode; /** * Did the flash actually fire? */ -fired: boolean | null; +fired: boolean | null; /** * Did flash return to the camera? (Unsure of the meaning) */ -returned: boolean | null; +returned: boolean | null; /** * Was red eye reduction used? */ red_eye_reduction: boolean | null } -export type FlashMode = +export type FlashMode = /** * The data is present, but we're unable to determine what they mean */ -"Unknown" | +"Unknown" | /** * FLash was on */ -"On" | +"On" | /** * Flash was off */ -"Off" | +"Off" | /** * Flash was set to automatically fire in certain conditions */ -"Auto" | +"Auto" | /** * Flash was forcefully fired */ @@ -342,10 +344,10 @@ export type IndexerRule = { id: number; pub_id: number[]; name: string | null; d /** * `IndexerRuleCreateArgs` is the argument received from the client using rspc to create a new indexer rule. * Note that `rules` field is a vector of tuples of `RuleKind` and `parameters`. - * + * * In case of `RuleKind::AcceptFilesByGlob` or `RuleKind::RejectFilesByGlob`, it will be a * vector of strings containing a glob patterns. - * + * * In case of `RuleKind::AcceptIfChildrenDirectoriesArePresent` or `RuleKind::RejectIfChildrenDirectoriesArePresent` the * `parameters` field must be a vector of strings containing the names of the directories. */ @@ -379,19 +381,19 @@ export type LibraryArgs = { library_id: string; arg: T } /** * LibraryConfig holds the configuration for a specific library. This is stored as a '{uuid}.sdlibrary' file. */ -export type LibraryConfig = { +export type LibraryConfig = { /** * name is the display name of the library. This is used in the UI and is set by the user. */ -name: LibraryName; +name: LibraryName; /** * description is a user set description of the library. This is used in the UI and is set by the user. */ -description: string | null; +description: string | null; /** * id of the current instance so we know who this `.db` is. This can be looked up within the `Instance` table. */ -instance_id: number; +instance_id: number; /** * cloud_id is the ID of the cloud library this library is linked to. * If this is set we can assume the library is synced with the Cloud. @@ -425,7 +427,7 @@ export type LocationSettings = { explorer: ExplorerSettings } * `LocationUpdateArgs` is the argument received from the client using `rspc` to update a location. * It contains the id of the location to be updated, possible a name to change the current location's name * and a vector of indexer rules ids to add or remove from the location. - * + * * It is important to note that only the indexer rule ids in this vector will be used from now on. * Old rules that aren't in this vector will be purged. */ @@ -447,11 +449,11 @@ export type MediaMetadata = ({ type: "Image" } & ImageMetadata) | ({ type: "Vide export type NodePreferences = { thumbnailer: ThumbnailerPreferences } -export type NodeState = ({ +export type NodeState = ({ /** * id is a unique identifier for the current node. Each node has a public identifier (this one) and is given a local id for each library (done within the library code). */ -id: string; +id: string; /** * name is the display name of the current node. This is set by the user and is shown in the UI. // TODO: Length validation so it can fit in DNS record */ @@ -461,14 +463,14 @@ export type NonIndexedPathItem = { path: string; name: string; extension: string /** * A type that can be used to return a group of `Reference` and `CacheNode`'s - * + * * You don't need to use this, it's just a shortcut to avoid having to write out the full type every time. */ export type NormalisedResult = { item: Reference; nodes: CacheNode[] } /** * A type that can be used to return a group of `Reference` and `CacheNode`'s - * + * * You don't need to use this, it's just a shortcut to avoid having to write out the full type every time. */ export type NormalisedResults = { items: Reference[]; nodes: CacheNode[] } @@ -502,7 +504,7 @@ export type ObjectSearchArgs = { take: number; orderAndPagination?: OrderAndPagi export type ObjectValidatorArgs = { id: number; path: string } -export type ObjectWithFilePaths = { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; file_paths: ({ id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null; object: { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; media_data: { resolution: number[] | null; media_date: number[] | null; media_location: number[] | null; camera_data: number[] | null; artist: string | null; description: string | null; copyright: string | null; exif_version: string | null } | null } | null })[] } +export type ObjectWithFilePaths = { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; file_paths: ({ id: number; pub_id: number[]; is_dir: boolean | null; cas_id: string | null; integrity_checksum: string | null; location_id: number | null; materialized_path: string | null; name: string | null; extension: string | null; hidden: boolean | null; size_in_bytes: string | null; size_in_bytes_bytes: number[] | null; inode: number[] | null; object_id: number | null; key_id: number | null; date_created: string | null; date_modified: string | null; date_indexed: string | null; media_info_id: number | null; object: { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; exif_data: { resolution: number[] | null; media_date: number[] | null; media_location: number[] | null; camera_data: number[] | null; artist: string | null; description: string | null; copyright: string | null; exif_version: string | null } | null } | null })[] } export type ObjectWithFilePaths2 = { id: number; pub_id: number[]; kind: number | null; key_id: number | null; hidden: boolean | null; favorite: boolean | null; important: boolean | null; note: string | null; date_created: string | null; date_accessed: string | null; file_paths: Reference[] } @@ -540,10 +542,10 @@ export type Range = { from: T } | { to: T } /** * A reference to a `CacheNode`. - * + * * This does not contain the actual data, but instead a reference to it. * This allows the CacheNode's to be switched out and the query recomputed without any backend communication. - * + * * If you use a `Reference` in a query, you *must* ensure the corresponding `CacheNode` is also in the query. */ export type Reference = { __type: string; __id: string; "#type": T } @@ -578,7 +580,7 @@ export type SetFavoriteArgs = { id: number; favorite: boolean } export type SetNoteArgs = { id: number; note: string | null } -export type SingleInvalidateOperationEvent = { +export type SingleInvalidateOperationEvent = { /** * This fields are intentionally private. */ diff --git a/packages/client/src/lib/explorerItem.ts b/packages/client/src/lib/explorerItem.ts index ad93fea2abb5..09ba303bd8a0 100644 --- a/packages/client/src/lib/explorerItem.ts +++ b/packages/client/src/lib/explorerItem.ts @@ -40,8 +40,8 @@ export function getExplorerItemData(data?: ExplorerItem | null): ItemData { if (object) { if (object.kind) itemData.kind = ObjectKind[object.kind] ?? 'Unknown'; - if ('media_data' in object && object.media_data?.media_date) { - const byteArray = object.media_data.media_date; + if ('exif_data' in object && object.exif_data?.media_date) { + const byteArray = object.exif_data.media_date; const dateString = String.fromCharCode.apply(null, byteArray); const [date, time] = dateString.replace(/"/g, '').split(' '); if (date && time) itemData.dateTaken = `${date}T${time}Z`; diff --git a/packages/client/src/utils/jobs/useJobInfo.tsx b/packages/client/src/utils/jobs/useJobInfo.tsx index 18160596e903..bc530c7c69dc 100644 --- a/packages/client/src/utils/jobs/useJobInfo.tsx +++ b/packages/client/src/utils/jobs/useJobInfo.tsx @@ -63,13 +63,13 @@ export function useJobInfo(job: JobReport, realtimeUpdate: JobProgressEvent | nu case 'media_processor': { const generateTexts = () => { switch (phase) { - case 'media_data': { + case 'exif_data': { return [ { text: `${ completedTaskCount ? formatNumber(completedTaskCount || 0) - : formatNumber(output?.media_data?.extracted) + : formatNumber(output?.exif_data?.extracted) } of ${formatNumber(taskCount)} ${plural( taskCount, 'media file' @@ -110,7 +110,7 @@ export function useJobInfo(job: JobReport, realtimeUpdate: JobProgressEvent | nu const totalThumbs = output?.thumbs_processed || 0; const totalMediaFiles = - output?.media_data?.extracted || 0 + output?.media_data?.skipped || 0; + output?.exif_data?.extracted || 0 + output?.exif_data?.skipped || 0; return totalThumbs === 0 && totalMediaFiles === 0 ? [{ text: 'None processed' }]