Compare commits

..

1 Commits

Author SHA1 Message Date
Alex 8b6b495bf5 fix: keep owned asset in iOS shared album in Free Up Space 2026-01-28 15:43:39 -06:00
444 changed files with 1260 additions and 6229 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@immich/cli", "name": "@immich/cli",
"version": "2.5.2", "version": "2.5.1",
"description": "Command Line Interface (CLI) for Immich", "description": "Command Line Interface (CLI) for Immich",
"type": "module", "type": "module",
"exports": "./dist/index.js", "exports": "./dist/index.js",
+2 -2
View File
@@ -1,6 +1,6 @@
[tools] [tools]
terragrunt = "0.98.0" terragrunt = "0.93.10"
opentofu = "1.11.4" opentofu = "1.10.7"
[tasks."tg:fmt"] [tasks."tg:fmt"]
run = "terragrunt hclfmt" run = "terragrunt hclfmt"
+2 -2
View File
@@ -1,7 +1,7 @@
[ [
{ {
"label": "v2.5.2", "label": "v2.5.1",
"url": "https://docs.v2.5.2.archive.immich.app" "url": "https://docs.v2.5.1.archive.immich.app"
}, },
{ {
"label": "v2.4.1", "label": "v2.4.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "immich-e2e", "name": "immich-e2e",
"version": "2.5.2", "version": "2.5.1",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "immich-i18n", "name": "immich-i18n",
"version": "2.5.2", "version": "2.5.1",
"private": true, "private": true,
"scripts": { "scripts": {
"format": "prettier --check .", "format": "prettier --check .",
+1 -1
View File
@@ -1,6 +1,6 @@
[project] [project]
name = "immich-ml" name = "immich-ml"
version = "2.5.2" version = "2.5.1"
description = "" description = ""
authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }] authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }]
requires-python = ">=3.11,<4.0" requires-python = ">=3.11,<4.0"
+1 -1
View File
@@ -919,7 +919,7 @@ wheels = [
[[package]] [[package]]
name = "immich-ml" name = "immich-ml"
version = "2.5.2" version = "2.4.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "aiocache" }, { name = "aiocache" },
+3 -3
View File
@@ -17,9 +17,9 @@ config_roots = [
node = "24.13.0" node = "24.13.0"
flutter = "3.35.7" flutter = "3.35.7"
pnpm = "10.28.0" pnpm = "10.28.0"
terragrunt = "0.98.0" terragrunt = "0.93.10"
opentofu = "1.11.4" opentofu = "1.10.7"
java = "21.0.2" java = "25.0.1"
[tools."github:CQLabs/homebrew-dcm"] [tools."github:CQLabs/homebrew-dcm"]
version = "1.30.0" version = "1.30.0"
+3
View File
@@ -0,0 +1,3 @@
{
"flutter": "3.35.7"
}
+3
View File
@@ -55,5 +55,8 @@ default.isar
default.isar.lock default.isar.lock
libisar.so libisar.so
# FVM Version
.fvm/
# Translation file # Translation file
lib/generated/ lib/generated/
+1 -3
View File
@@ -2,9 +2,7 @@
"dart.flutterSdkPath": ".fvm/versions/3.35.7", "dart.flutterSdkPath": ".fvm/versions/3.35.7",
"dart.lineLength": 120, "dart.lineLength": 120,
"[dart]": { "[dart]": {
"editor.rulers": [ "editor.rulers": [120]
120
]
}, },
"search.exclude": { "search.exclude": {
"**/.fvm": true "**/.fvm": true
+4 -6
View File
@@ -4,12 +4,10 @@ The Immich mobile app is a Flutter-based solution leveraging the Isar Database f
## Setup ## Setup
1. [Install mise](https://mise.jdx.dev/installing-mise.html). 1. Setup Flutter toolchain using FVM.
2. Change to the immich directory and trust the mise config with `mise trust`. 2. Run `flutter pub get` to install the dependencies.
3. Install tools with mise: `mise install`. 3. Run `make translation` to generate the translation file.
4. Run `flutter pub get` to install the dependencies. 4. Run `fvm flutter run` to start the app.
5. Run `make translation` to generate the translation file.
6. Run `flutter run` to start the app.
## Translation ## Translation
+2 -2
View File
@@ -35,8 +35,8 @@ platform :android do
task: 'bundle', task: 'bundle',
build_type: 'Release', build_type: 'Release',
properties: { properties: {
"android.injected.version.code" => 3033, "android.injected.version.code" => 3032,
"android.injected.version.name" => "2.5.2", "android.injected.version.name" => "2.5.1",
} }
) )
upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab') upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab')
+1 -1
View File
@@ -80,7 +80,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.5.2</string> <string>2.5.1</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
+2 -2
View File
@@ -16,9 +16,9 @@ class ScrollToDateEvent extends Event {
} }
// Asset Viewer Events // Asset Viewer Events
class ViewerShowDetailsEvent extends Event { class ViewerOpenBottomSheetEvent extends Event {
final bool activitiesMode; final bool activitiesMode;
const ViewerShowDetailsEvent({this.activitiesMode = false}); const ViewerOpenBottomSheetEvent({this.activitiesMode = false});
} }
class ViewerReloadAssetEvent extends Event { class ViewerReloadAssetEvent extends Event {
@@ -144,16 +144,13 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
bool keepFavorites = true, bool keepFavorites = true,
Set<String> keepAlbumIds = const {}, Set<String> keepAlbumIds = const {},
}) async { }) async {
final iosSharedAlbumIds = _db.localAlbumEntity.selectOnly()
..addColumns([_db.localAlbumEntity.id])
..where(_db.localAlbumEntity.isIosSharedAlbum.equals(true));
final iosSharedAlbumAssets = _db.localAlbumAssetEntity.selectOnly() final iosSharedAlbumAssets = _db.localAlbumAssetEntity.selectOnly()
..addColumns([_db.localAlbumAssetEntity.assetId]) ..addColumns([_db.localAlbumAssetEntity.assetId])
..join([ ..where(_db.localAlbumAssetEntity.albumId.isInQuery(iosSharedAlbumIds));
innerJoin(
_db.localAlbumEntity,
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
useColumns: false,
),
])
..where(_db.localAlbumEntity.isIosSharedAlbum.equals(true));
final query = _db.localAssetEntity.select().join([ final query = _db.localAssetEntity.select().join([
innerJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)), innerJoin(_db.remoteAssetEntity, _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum)),
@@ -20,7 +20,7 @@ enum VersionStatus {
class ServerInfo { class ServerInfo {
final ServerVersion serverVersion; final ServerVersion serverVersion;
final ServerVersion? latestVersion; final ServerVersion latestVersion;
final ServerFeatures serverFeatures; final ServerFeatures serverFeatures;
final ServerConfig serverConfig; final ServerConfig serverConfig;
final ServerDiskInfo serverDiskInfo; final ServerDiskInfo serverDiskInfo;
@@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:math' as math;
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@@ -15,11 +14,12 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/platform_extensions.dart';
import 'package:immich_mobile/extensions/scroll_extensions.dart'; import 'package:immich_mobile/extensions/scroll_extensions.dart';
import 'package:immich_mobile/presentation/widgets/action_buttons/download_status_floating_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/download_status_floating_button.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_details.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/activities_bottom_sheet.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.provider.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.provider.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_stack.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_bar.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_bar.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/top_app_bar.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/top_app_bar.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/video_viewer.widget.dart';
import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/image_provider.dart';
@@ -30,6 +30,7 @@ import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider
import 'package:immich_mobile/providers/cast.provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/current_album.provider.dart';
import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart';
import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart'; import 'package:immich_mobile/providers/infrastructure/timeline.provider.dart';
import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart'; import 'package:immich_mobile/widgets/common/immich_loading_indicator.dart';
import 'package:immich_mobile/widgets/photo_view/photo_view.dart'; import 'package:immich_mobile/widgets/photo_view/photo_view.dart';
@@ -99,24 +100,27 @@ class AssetViewer extends ConsumerStatefulWidget {
} }
} }
enum _DragMode { undecided, dismiss, scroll } const double _kBottomSheetMinimumExtent = 0.4;
const double _kBottomSheetSnapExtent = 0.67;
class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderStateMixin { class _AssetViewerState extends ConsumerState<AssetViewer> {
static final _dummyListener = ImageStreamListener((image, _) => image.dispose()); static final _dummyListener = ImageStreamListener((image, _) => image.dispose());
late PageController pageController; late PageController pageController;
late DraggableScrollableController bottomSheetController;
PersistentBottomSheetController? sheetCloseController;
// PhotoViewGallery takes care of disposing it's controllers // PhotoViewGallery takes care of disposing it's controllers
PhotoViewControllerBase? viewController; PhotoViewControllerBase? viewController;
StreamSubscription? reloadSubscription; StreamSubscription? reloadSubscription;
StreamSubscription? _scaleBoundarySub;
late final int heroOffset; late final int heroOffset;
late PhotoViewControllerValue initialPhotoViewState; late PhotoViewControllerValue initialPhotoViewState;
bool? hasDraggedDown;
bool isSnapping = false;
bool blockGestures = false; bool blockGestures = false;
bool dragInProgress = false; bool dragInProgress = false;
bool shouldPopOnDrag = false; bool shouldPopOnDrag = false;
_DragMode _dragMode = _DragMode.undecided;
Offset _dragStartGlobalPosition = Offset.zero;
bool assetReloadRequested = false; bool assetReloadRequested = false;
double previousExtent = _kBottomSheetMinimumExtent;
Offset dragDownPosition = Offset.zero; Offset dragDownPosition = Offset.zero;
int totalAssets = 0; int totalAssets = 0;
int stackIndex = 0; int stackIndex = 0;
@@ -131,19 +135,13 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
KeepAliveLink? _stackChildrenKeepAlive; KeepAliveLink? _stackChildrenKeepAlive;
final ScrollController _scrollController = ScrollController();
late final AnimationController _ballisticAnimController;
double _assetDetailsOpacity = 0.0;
double _currentSnapOffset = 0.0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
assert(ref.read(currentAssetNotifier) != null, "Current asset should not be null when opening the AssetViewer"); assert(ref.read(currentAssetNotifier) != null, "Current asset should not be null when opening the AssetViewer");
pageController = PageController(initialPage: widget.initialIndex); pageController = PageController(initialPage: widget.initialIndex);
_scrollController.addListener(_onScroll);
_ballisticAnimController = AnimationController.unbounded(vsync: this)..addListener(_onBallisticTick);
totalAssets = ref.read(timelineServiceProvider).totalAssets; totalAssets = ref.read(timelineServiceProvider).totalAssets;
bottomSheetController = DraggableScrollableController();
WidgetsBinding.instance.addPostFrameCallback(_onAssetInit); WidgetsBinding.instance.addPostFrameCallback(_onAssetInit);
reloadSubscription = EventStream.shared.listen(_onEvent); reloadSubscription = EventStream.shared.listen(_onEvent);
heroOffset = widget.heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0; heroOffset = widget.heroOffset ?? TabsRouterScope.of(context)?.controller.activeIndex ?? 0;
@@ -158,129 +156,12 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
} }
void _onScroll() {
final newOpacity = _scrollController.offset > 5 ? 1.0 : 0.0;
if (newOpacity != _assetDetailsOpacity) {
setState(() {
_assetDetailsOpacity = newOpacity;
});
if (_assetDetailsOpacity == 0) {
ref.read(assetViewerProvider.notifier).setControls(true);
} else {
ref.read(assetViewerProvider.notifier).setControls(false);
}
}
}
// Match Flutter's ScrollPhysics defaults
static final _snapSpring = SpringDescription.withDampingRatio(mass: 0.5, stiffness: 100.0, ratio: 1.1);
static const _minFlingVelocity = 50.0; // px/s, matches ScrollPhysics.minFlingVelocity
Tolerance get _scrollTolerance {
final dpr = MediaQuery.devicePixelRatioOf(context);
return Tolerance(velocity: 1.0 / (0.050 * dpr), distance: 1.0 / dpr);
}
/// Drive the scroll controller by [dy] pixels (positive = scroll down).
void _scrollBy(double dy) {
if (!_scrollController.hasClients) return;
final newOffset = (_scrollController.offset - dy).clamp(0.0, _scrollController.position.maxScrollExtent);
_scrollController.jumpTo(newOffset);
}
/// Animate the scroll position to [target] using a spring simulation.
void _animateScrollTo(double target, double velocity) {
final offset = _scrollController.offset;
final tolerance = _scrollTolerance;
if ((offset - target).abs() < tolerance.distance) {
_scrollController.jumpTo(target);
return;
}
_ballisticAnimController.value = offset;
_ballisticAnimController.animateWith(
ScrollSpringSimulation(_snapSpring, offset, target, velocity, tolerance: tolerance),
);
}
/// Create a platform-appropriate fling simulation (clamping on Android, bouncing on iOS).
Simulation _createFlingSimulation(double offset, double velocity) {
final tolerance = _scrollTolerance;
if (CurrentPlatform.isIOS) {
return BouncingScrollSimulation(
position: offset,
velocity: velocity,
leadingExtent: _currentSnapOffset,
trailingExtent: _scrollController.position.maxScrollExtent,
spring: _snapSpring,
tolerance: tolerance,
);
}
return ClampingScrollSimulation(position: offset, velocity: velocity, tolerance: tolerance);
}
void _onBallisticTick() {
if (!_scrollController.hasClients) return;
final raw = _ballisticAnimController.value;
final max = _scrollController.position.maxScrollExtent;
final offset = raw.clamp(0.0, max);
final prevOffset = _scrollController.offset;
// Stop at bounds
if (raw != offset) {
_ballisticAnimController.stop();
_scrollController.jumpTo(offset);
return;
}
// During free-scroll deceleration, don't cross into the snap zone.
// Stop at snapOffset so the user can release there cleanly.
final snap = _currentSnapOffset;
if (prevOffset >= snap && offset < snap) {
_ballisticAnimController.stop();
_scrollController.jumpTo(snap);
return;
}
_scrollController.jumpTo(offset);
}
void _snapScroll(double velocity) {
if (!_scrollController.hasClients) return;
final offset = _scrollController.offset;
final snap = _currentSnapOffset;
if (snap <= 0) return;
// Above snap offset: free scroll or spring back to snap
if (offset >= snap) {
if (velocity.abs() < _minFlingVelocity) return;
if (velocity < -_minFlingVelocity) {
_animateScrollTo(snap, velocity);
return;
}
// Scrolling up: decelerate with platform-native physics
_ballisticAnimController.value = offset;
_ballisticAnimController.animateWith(_createFlingSimulation(offset, velocity));
return;
}
// In snap zone (0 → snapOffset): snap to nearest target
final double target;
if (velocity.abs() > _minFlingVelocity) {
target = velocity > 0 ? snap : 0;
} else {
target = (offset < snap / 2) ? 0 : snap;
}
_animateScrollTo(target, velocity);
}
@override @override
void dispose() { void dispose() {
_ballisticAnimController.dispose();
_scrollController.dispose();
pageController.dispose(); pageController.dispose();
bottomSheetController.dispose();
_cancelTimers(); _cancelTimers();
reloadSubscription?.cancel(); reloadSubscription?.cancel();
_scaleBoundarySub?.cancel();
_prevPreCacheStream?.removeListener(_dummyListener); _prevPreCacheStream?.removeListener(_dummyListener);
_nextPreCacheStream?.removeListener(_dummyListener); _nextPreCacheStream?.removeListener(_dummyListener);
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge); SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
@@ -288,7 +169,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
super.dispose(); super.dispose();
} }
bool get showingDetails => _scrollController.offset > 0; bool get showingBottomSheet => ref.read(assetViewerProvider.select((s) => s.showingBottomSheet));
Color get backgroundColor { Color get backgroundColor {
final opacity = ref.read(assetViewerProvider.select((s) => s.backgroundOpacity)); final opacity = ref.read(assetViewerProvider.select((s) => s.backgroundOpacity));
@@ -302,6 +183,9 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
_delayedOperations.clear(); _delayedOperations.clear();
} }
double _getVerticalOffsetForBottomSheet(double extent) =>
(context.height * extent) - (context.height * _kBottomSheetMinimumExtent);
ImageStream _precacheImage(BaseAsset asset) { ImageStream _precacheImage(BaseAsset asset) {
final provider = getFullImageProvider(asset, size: context.sizeData); final provider = getFullImageProvider(asset, size: context.sizeData);
return provider.resolve(ImageConfiguration.empty)..addListener(_dummyListener); return provider.resolve(ImageConfiguration.empty)..addListener(_dummyListener);
@@ -336,8 +220,6 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
void _onAssetChanged(int index) async { void _onAssetChanged(int index) async {
_ballisticAnimController.stop();
if (_scrollController.hasClients) _scrollController.jumpTo(0);
final timelineService = ref.read(timelineServiceProvider); final timelineService = ref.read(timelineServiceProvider);
final asset = await timelineService.getAssetAsync(index); final asset = await timelineService.getAssetAsync(index);
if (asset == null) { if (asset == null) {
@@ -381,23 +263,20 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
} }
void _onPageBuild(PhotoViewControllerBase controller) {
viewController ??= controller;
if (showingBottomSheet && bottomSheetController.isAttached) {
final verticalOffset =
(context.height * bottomSheetController.size) - (context.height * _kBottomSheetMinimumExtent);
controller.position = Offset(0, -verticalOffset);
// Apply the zoom effect when the bottom sheet is showing
controller.scale = (controller.scale ?? 1.0) + 0.01;
}
}
void _onPageChanged(int index, PhotoViewControllerBase? controller) { void _onPageChanged(int index, PhotoViewControllerBase? controller) {
_onAssetChanged(index); _onAssetChanged(index);
viewController = controller; viewController = controller;
_listenForScaleBoundaries(controller);
}
void _listenForScaleBoundaries(PhotoViewControllerBase? controller) {
_scaleBoundarySub?.cancel();
_scaleBoundarySub = null;
if (controller == null || controller.scaleBoundaries != null) return;
_scaleBoundarySub = controller.outputStateStream.listen((_) {
if (controller.scaleBoundaries != null) {
_scaleBoundarySub?.cancel();
_scaleBoundarySub = null;
if (mounted) setState(() {});
}
});
} }
void _onDragStart( void _onDragStart(
@@ -406,43 +285,40 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
PhotoViewControllerBase controller, PhotoViewControllerBase controller,
PhotoViewScaleStateController scaleStateController, PhotoViewScaleStateController scaleStateController,
) { ) {
_ballisticAnimController.stop();
viewController = controller; viewController = controller;
dragDownPosition = details.localPosition; dragDownPosition = details.localPosition;
_dragStartGlobalPosition = details.globalPosition;
initialPhotoViewState = controller.value; initialPhotoViewState = controller.value;
_dragMode = showingDetails ? _DragMode.scroll : _DragMode.undecided;
final isZoomed = final isZoomed =
scaleStateController.scaleState == PhotoViewScaleState.zoomedIn || scaleStateController.scaleState == PhotoViewScaleState.zoomedIn ||
scaleStateController.scaleState == PhotoViewScaleState.covering; scaleStateController.scaleState == PhotoViewScaleState.covering;
if (!showingDetails && isZoomed) { if (!showingBottomSheet && isZoomed) {
blockGestures = true; blockGestures = true;
} }
} }
void _onDragEnd(BuildContext ctx, DragEndDetails details, _) { void _onDragEnd(BuildContext ctx, _, __) {
dragInProgress = false; dragInProgress = false;
final mode = _dragMode;
_dragMode = _DragMode.undecided;
if (mode == _DragMode.scroll) {
// Convert finger velocity to scroll velocity (inverted)
final scrollVelocity = -details.velocity.pixelsPerSecond.dy;
_snapScroll(scrollVelocity);
return;
}
if (shouldPopOnDrag) { if (shouldPopOnDrag) {
// Dismiss immediately without state updates to avoid rebuilds
ctx.maybePop(); ctx.maybePop();
return; return;
} }
// Do not reset the state if the bottom sheet is showing
if (showingBottomSheet) {
_snapBottomSheet();
return;
}
// If the gestures are blocked, do not reset the state
if (blockGestures) { if (blockGestures) {
blockGestures = false; blockGestures = false;
return; return;
} }
shouldPopOnDrag = false; shouldPopOnDrag = false;
hasDraggedDown = null;
viewController?.animateMultiple( viewController?.animateMultiple(
position: initialPhotoViewState.position, position: initialPhotoViewState.position,
scale: viewController?.initialScale ?? initialPhotoViewState.scale, scale: viewController?.initialScale ?? initialPhotoViewState.scale,
@@ -452,28 +328,37 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
void _onDragUpdate(BuildContext ctx, DragUpdateDetails details, _) { void _onDragUpdate(BuildContext ctx, DragUpdateDetails details, _) {
if (blockGestures) return; if (blockGestures) {
dragInProgress = true;
if (_dragMode == _DragMode.undecided) {
final globalDelta = details.globalPosition - _dragStartGlobalPosition;
if (globalDelta.dy > 1) {
_dragMode = _DragMode.dismiss;
} else if (globalDelta.dy < -1) {
_dragMode = _DragMode.scroll;
} else {
return;
}
// Fall through to process this update immediately
}
if (_dragMode == _DragMode.dismiss) {
final delta = details.localPosition - dragDownPosition;
_handleDragDown(ctx, delta);
return; return;
} }
_scrollBy(details.delta.dy); dragInProgress = true;
final delta = details.localPosition - dragDownPosition;
hasDraggedDown ??= delta.dy > 0;
if (!hasDraggedDown! || showingBottomSheet) {
_handleDragUp(ctx, delta);
return;
}
_handleDragDown(ctx, delta);
}
void _handleDragUp(BuildContext ctx, Offset delta) {
const double openThreshold = 50;
final position = initialPhotoViewState.position + Offset(0, delta.dy);
final distanceToOrigin = position.distance;
viewController?.updateMultiple(position: position);
// Moves the bottom sheet when the asset is being dragged up
if (showingBottomSheet && bottomSheetController.isAttached) {
final centre = (ctx.height * _kBottomSheetMinimumExtent);
bottomSheetController.jumpTo((centre + distanceToOrigin) / ctx.height);
}
if (distanceToOrigin > openThreshold && !showingBottomSheet && !ref.read(readonlyModeProvider)) {
_openBottomSheet(ctx);
}
} }
void _handleDragDown(BuildContext ctx, Offset delta) { void _handleDragDown(BuildContext ctx, Offset delta) {
@@ -497,12 +382,54 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
ref.read(assetViewerProvider.notifier).setOpacity(backgroundOpacity); ref.read(assetViewerProvider.notifier).setOpacity(backgroundOpacity);
} }
void _onTapUp(_, __, ___) { void _onTapDown(_, __, ___) {
if (!showingDetails) { if (!showingBottomSheet) {
ref.read(assetViewerProvider.notifier).toggleControls(); ref.read(assetViewerProvider.notifier).toggleControls();
} }
} }
bool _onNotification(Notification delta) {
if (delta is DraggableScrollableNotification) {
_handleDraggableNotification(delta);
}
// Handle sheet snap manually so that the it snaps only at _kBottomSheetSnapExtent but not after
// the isSnapping guard is to prevent the notification from recursively handling the
// notification, eventually resulting in a heap overflow
if (!isSnapping && delta is ScrollEndNotification) {
_snapBottomSheet();
}
return false;
}
void _handleDraggableNotification(DraggableScrollableNotification delta) {
final currentExtent = delta.extent;
final isDraggingDown = currentExtent < previousExtent;
previousExtent = currentExtent;
// Closes the bottom sheet if the user is dragging down
if (isDraggingDown && delta.extent < 0.67) {
if (dragInProgress) {
blockGestures = true;
}
// Jump to a lower position before starting close animation to prevent glitch
if (bottomSheetController.isAttached) {
bottomSheetController.jumpTo(0.67);
}
sheetCloseController?.close();
}
// If the asset is being dragged down, we do not want to update the asset position again
if (dragInProgress) {
return;
}
final verticalOffset = _getVerticalOffsetForBottomSheet(delta.extent);
// Moves the asset when the bottom sheet is being dragged
if (verticalOffset > 0) {
viewController?.position = Offset(0, -verticalOffset);
}
}
void _onEvent(Event event) { void _onEvent(Event event) {
if (event is TimelineReloadEvent) { if (event is TimelineReloadEvent) {
_onTimelineReloadEvent(); _onTimelineReloadEvent();
@@ -514,18 +441,15 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
return; return;
} }
if (event is ViewerShowDetailsEvent) { if (event is ViewerOpenBottomSheetEvent) {
_showDetails(); final extent = _kBottomSheetMinimumExtent + 0.3;
_openBottomSheet(scaffoldContext!, extent: extent, activitiesMode: event.activitiesMode);
final offset = _getVerticalOffsetForBottomSheet(extent);
viewController?.position = Offset(0, -offset);
return; return;
} }
} }
void _showDetails() {
if (!_scrollController.hasClients || _currentSnapOffset <= 0) return;
_ballisticAnimController.stop();
_animateScrollTo(_currentSnapOffset, 0);
}
void _onTimelineReloadEvent() { void _onTimelineReloadEvent() {
totalAssets = ref.read(timelineServiceProvider).totalAssets; totalAssets = ref.read(timelineServiceProvider).totalAssets;
if (totalAssets == 0) { if (totalAssets == 0) {
@@ -550,16 +474,57 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
final currentAsset = ref.read(currentAssetNotifier); final currentAsset = ref.read(currentAssetNotifier);
// Do not reload if the asset has not changed // Do not reload / close the bottom sheet if the asset has not changed
if (newAsset.heroTag == currentAsset?.heroTag) { if (newAsset.heroTag == currentAsset?.heroTag) {
return; return;
} }
setState(() { setState(() {
_onAssetChanged(pageController.page!.round()); _onAssetChanged(pageController.page!.round());
sheetCloseController?.close();
}); });
} }
void _openBottomSheet(BuildContext ctx, {double extent = _kBottomSheetMinimumExtent, bool activitiesMode = false}) {
ref.read(assetViewerProvider.notifier).setBottomSheet(true);
previousExtent = _kBottomSheetMinimumExtent;
sheetCloseController = showBottomSheet(
context: ctx,
sheetAnimationStyle: const AnimationStyle(duration: Durations.medium2, reverseDuration: Durations.medium2),
constraints: const BoxConstraints(maxWidth: double.infinity),
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.vertical(top: Radius.circular(20.0))),
backgroundColor: ctx.colorScheme.surfaceContainerLowest,
builder: (_) {
return NotificationListener<Notification>(
onNotification: _onNotification,
child: activitiesMode
? ActivitiesBottomSheet(controller: bottomSheetController, initialChildSize: extent)
: AssetDetailBottomSheet(controller: bottomSheetController, initialChildSize: extent),
);
},
);
sheetCloseController?.closed.then((_) => _handleSheetClose());
}
void _handleSheetClose() {
viewController?.animateMultiple(position: Offset.zero);
viewController?.updateMultiple(scale: viewController?.initialScale);
ref.read(assetViewerProvider.notifier).setBottomSheet(false);
sheetCloseController = null;
shouldPopOnDrag = false;
hasDraggedDown = null;
}
void _snapBottomSheet() {
if (!bottomSheetController.isAttached ||
bottomSheetController.size > _kBottomSheetSnapExtent ||
bottomSheetController.size < 0.4) {
return;
}
isSnapping = true;
bottomSheetController.animateTo(_kBottomSheetSnapExtent, duration: Durations.short3, curve: Curves.easeOut);
}
Widget _placeholderBuilder(BuildContext ctx, ImageChunkEvent? progress, int index) { Widget _placeholderBuilder(BuildContext ctx, ImageChunkEvent? progress, int index) {
return const Center(child: ImmichLoadingIndicator()); return const Center(child: ImmichLoadingIndicator());
} }
@@ -573,7 +538,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
return; return;
} }
if (!showingDetails) { if (!showingBottomSheet) {
ref.read(assetViewerProvider.notifier).setControls(true); ref.read(assetViewerProvider.notifier).setControls(true);
} }
} }
@@ -622,11 +587,11 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
heroAttributes: PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'), heroAttributes: PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'),
filterQuality: FilterQuality.high, filterQuality: FilterQuality.high,
tightMode: true, tightMode: true,
disableScaleGestures: showingDetails, disableScaleGestures: showingBottomSheet,
onDragStart: _onDragStart, onDragStart: _onDragStart,
onDragUpdate: _onDragUpdate, onDragUpdate: _onDragUpdate,
onDragEnd: _onDragEnd, onDragEnd: _onDragEnd,
onTapUp: _onTapUp, onTapDown: _onTapDown,
onLongPressStart: asset.isMotionPhoto ? _onLongPress : null, onLongPressStart: asset.isMotionPhoto ? _onLongPress : null,
errorBuilder: (_, __, ___) => Container( errorBuilder: (_, __, ___) => Container(
width: size.width, width: size.width,
@@ -647,7 +612,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
onDragStart: _onDragStart, onDragStart: _onDragStart,
onDragUpdate: _onDragUpdate, onDragUpdate: _onDragUpdate,
onDragEnd: _onDragEnd, onDragEnd: _onDragEnd,
onTapUp: _onTapUp, onTapDown: _onTapDown,
heroAttributes: PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'), heroAttributes: PhotoViewHeroAttributes(tag: '${asset.heroTag}_$heroOffset'),
filterQuality: FilterQuality.high, filterQuality: FilterQuality.high,
maxScale: 1.0, maxScale: 1.0,
@@ -680,6 +645,7 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
Widget build(BuildContext context) { Widget build(BuildContext context) {
// Rebuild the widget when the asset viewer state changes // Rebuild the widget when the asset viewer state changes
// Using multiple selectors to avoid unnecessary rebuilds for other state changes // Using multiple selectors to avoid unnecessary rebuilds for other state changes
ref.watch(assetViewerProvider.select((s) => s.showingBottomSheet));
ref.watch(assetViewerProvider.select((s) => s.backgroundOpacity)); ref.watch(assetViewerProvider.select((s) => s.backgroundOpacity));
ref.watch(assetViewerProvider.select((s) => s.stackIndex)); ref.watch(assetViewerProvider.select((s) => s.stackIndex));
ref.watch(isPlayingMotionVideoProvider); ref.watch(isPlayingMotionVideoProvider);
@@ -706,6 +672,9 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
} }
}); });
// Currently it is not possible to scroll the asset when the bottom sheet is open all the way.
// Issue: https://github.com/flutter/flutter/issues/109037
// TODO: Add a custom scrum builder once the fix lands on stable
return PopScope( return PopScope(
onPopInvokedWithResult: _onPop, onPopInvokedWithResult: _onPop,
child: Scaffold( child: Scaffold(
@@ -721,92 +690,36 @@ class _AssetViewerState extends ConsumerState<AssetViewer> with TickerProviderSt
child: const DownloadStatusFloatingButton(), child: const DownloadStatusFloatingButton(),
), ),
), ),
body: LayoutBuilder( body: Stack(
builder: (context, constraints) { children: [
final viewportWidth = constraints.maxWidth; PhotoViewGallery.builder(
final viewportHeight = constraints.maxHeight; gaplessPlayback: true,
loadingBuilder: _placeholderBuilder,
// Use the actual rendered image size from PhotoView when available, pageController: pageController,
// falling back to a calculation from asset metadata. scrollPhysics: CurrentPlatform.isIOS
final sb = viewController?.scaleBoundaries; ? const FastScrollPhysics() // Use bouncing physics for iOS
double imageHeight; : const FastClampingScrollPhysics(), // Use heavy physics for Android
if (sb != null) { itemCount: totalAssets,
imageHeight = sb.childSize.height * sb.initialScale; onPageChanged: _onPageChanged,
} else { onPageBuild: _onPageBuild,
final asset = ref.read(currentAssetNotifier); scaleStateChangedCallback: _onScaleStateChanged,
final assetWidth = asset?.width; builder: _assetBuilder,
final assetHeight = asset?.height; backgroundDecoration: BoxDecoration(color: backgroundColor),
imageHeight = viewportHeight; enablePanAlways: true,
if (assetWidth != null && assetHeight != null && assetWidth > 0 && assetHeight > 0) { ),
final aspectRatio = assetWidth / assetHeight; if (!showingBottomSheet)
imageHeight = math.min(viewportWidth / aspectRatio, viewportHeight); const Positioned(
} bottom: 0,
} left: 0,
right: 0,
// Calculate padding to center the image in the viewport child: Column(
final topPadding = math.max((viewportHeight - imageHeight) / 2, 0.0); mainAxisSize: MainAxisSize.min,
final snapOffset = math.max(topPadding + (imageHeight / 2), viewportHeight / 4 * 3); mainAxisAlignment: MainAxisAlignment.end,
_currentSnapOffset = snapOffset; crossAxisAlignment: CrossAxisAlignment.stretch,
children: [AssetStackRow(), ViewerBottomBar()],
return Stack(
clipBehavior: Clip.none,
children: [
SingleChildScrollView(
controller: _scrollController,
physics: const NeverScrollableScrollPhysics(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedOverflowBox(
size: Size(double.infinity, topPadding + imageHeight - (kMinInteractiveDimension / 2)),
alignment: Alignment.topCenter,
child: SizedBox(
height: viewportHeight,
child: PhotoViewGallery.builder(
gaplessPlayback: true,
loadingBuilder: _placeholderBuilder,
pageController: pageController,
scrollPhysics: CurrentPlatform.isIOS
? const FastScrollPhysics() // Use bouncing physics for iOS
: const FastClampingScrollPhysics(), // Use heavy physics for Android
itemCount: totalAssets,
onPageChanged: _onPageChanged,
scaleStateChangedCallback: _onScaleStateChanged,
builder: _assetBuilder,
backgroundDecoration: BoxDecoration(color: backgroundColor),
enablePanAlways: true,
),
),
),
GestureDetector(
onVerticalDragStart: (_) => _ballisticAnimController.stop(),
onVerticalDragUpdate: (details) => _scrollBy(details.delta.dy),
onVerticalDragEnd: (details) => _snapScroll(-details.velocity.pixelsPerSecond.dy),
child: AnimatedOpacity(
opacity: _assetDetailsOpacity,
duration: kThemeAnimationDuration,
child: AssetDetails(minHeight: viewportHeight / 4 * 3),
),
),
],
),
), ),
Positioned( ),
height: viewportHeight, ],
bottom: 0,
left: 0,
right: 0,
child: const Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [AssetStackRow(), ViewerBottomBar()],
),
),
],
);
},
), ),
), ),
); );
@@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart'; import 'package:easy_localization/easy_localization.dart';
@@ -17,6 +18,7 @@ import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet/she
import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet/sheet_people_details.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/bottom_sheet/sheet_people_details.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/rating_bar.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/rating_bar.widget.dart';
import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart'; import 'package:immich_mobile/presentation/widgets/asset_viewer/sheet_tile.widget.dart';
import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart';
import 'package:immich_mobile/providers/infrastructure/action.provider.dart'; import 'package:immich_mobile/providers/infrastructure/action.provider.dart';
import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
@@ -30,10 +32,36 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart';
const _kSeparator = ''; const _kSeparator = '';
class AssetDetails extends ConsumerWidget { class AssetDetailBottomSheet extends ConsumerWidget {
final double minHeight; final DraggableScrollableController? controller;
final double initialChildSize;
const AssetDetails({required this.minHeight, super.key}); const AssetDetailBottomSheet({this.controller, this.initialChildSize = 0.35, super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final asset = ref.watch(currentAssetNotifier);
if (asset == null) {
return const SizedBox.shrink();
}
return BaseBottomSheet(
actions: [],
slivers: const [_AssetDetailBottomSheet()],
controller: controller,
initialChildSize: initialChildSize,
minChildSize: 0.1,
maxChildSize: 0.88,
expand: false,
shouldCloseOnMinExtent: false,
resizeOnScroll: false,
backgroundColor: context.isDarkTheme ? context.colorScheme.surface : Colors.white,
);
}
}
class _AssetDetailBottomSheet extends ConsumerWidget {
const _AssetDetailBottomSheet();
String _getDateTime(BuildContext ctx, BaseAsset asset, ExifInfo? exifInfo) { String _getDateTime(BuildContext ctx, BaseAsset asset, ExifInfo? exifInfo) {
DateTime dateTime = asset.createdAt.toLocal(); DateTime dateTime = asset.createdAt.toLocal();
@@ -171,7 +199,7 @@ class AssetDetails extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final asset = ref.watch(currentAssetNotifier); final asset = ref.watch(currentAssetNotifier);
if (asset == null) { if (asset == null) {
return const SizedBox.shrink(); return const SliverToBoxAdapter(child: SizedBox.shrink());
} }
final exifInfo = ref.watch(currentAssetExifProvider).valueOrNull; final exifInfo = ref.watch(currentAssetExifProvider).valueOrNull;
@@ -219,100 +247,81 @@ class AssetDetails extends ConsumerWidget {
} }
} }
return Container( return SliverList.list(
constraints: BoxConstraints(minHeight: minHeight), children: [
decoration: BoxDecoration( // Asset Date and Time
color: context.isDarkTheme ? context.colorScheme.surface : Colors.white, SheetTile(
borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), title: _getDateTime(context, asset, exifInfo),
), titleStyle: context.textTheme.labelLarge,
child: Column( trailing: asset.hasRemote && isOwner ? const Icon(Icons.edit, size: 18) : null,
children: [ onTap: asset.hasRemote && isOwner ? () async => await _editDateTime(context, ref) : null,
),
if (exifInfo != null) _SheetAssetDescription(exif: exifInfo, isEditable: isOwner),
const SheetPeopleDetails(),
const SheetLocationDetails(),
// Details header
SheetTile(
title: 'details'.t(context: context),
titleStyle: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
// File info
buildFileInfoTile(),
// Camera info
if (cameraTitle != null) ...[
const SizedBox(height: 16), const SizedBox(height: 16),
Center(
child: Container(
width: 32,
height: 4,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(2),
color: context.colorScheme.onSurfaceVariant,
),
),
),
const SizedBox(height: 16),
// Asset Date and Time
SheetTile( SheetTile(
title: _getDateTime(context, asset, exifInfo), title: cameraTitle,
titleStyle: context.textTheme.labelLarge, titleStyle: context.textTheme.labelLarge,
trailing: asset.hasRemote && isOwner ? const Icon(Icons.edit, size: 18) : null, leading: Icon(Icons.camera_alt_outlined, size: 24, color: context.textTheme.labelLarge?.color),
onTap: asset.hasRemote && isOwner ? () async => await _editDateTime(context, ref) : null, subtitle: _getCameraInfoSubtitle(exifInfo),
subtitleStyle: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
), ),
if (exifInfo != null) _SheetAssetDescription(exif: exifInfo, isEditable: isOwner),
const SheetPeopleDetails(),
const SheetLocationDetails(),
// Details header
SheetTile(
title: 'details'.t(context: context),
titleStyle: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
// File info
buildFileInfoTile(),
// Camera info
if (cameraTitle != null) ...[
const SizedBox(height: 16),
SheetTile(
title: cameraTitle,
titleStyle: context.textTheme.labelLarge,
leading: Icon(Icons.camera_alt_outlined, size: 24, color: context.textTheme.labelLarge?.color),
subtitle: _getCameraInfoSubtitle(exifInfo),
subtitleStyle: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
],
// Lens info
if (lensTitle != null) ...[
const SizedBox(height: 16),
SheetTile(
title: lensTitle,
titleStyle: context.textTheme.labelLarge,
leading: Icon(Icons.camera_outlined, size: 24, color: context.textTheme.labelLarge?.color),
subtitle: _getLensInfoSubtitle(exifInfo),
subtitleStyle: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
],
// Rating bar
if (isRatingEnabled) ...[
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
Text(
'rating'.t(context: context),
style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
RatingBar(
initialRating: exifInfo?.rating?.toDouble() ?? 0,
filledColor: context.themeData.colorScheme.primary,
unfilledColor: context.themeData.colorScheme.onSurface.withAlpha(100),
itemSize: 40,
onRatingUpdate: (rating) async {
await ref.read(actionProvider.notifier).updateRating(ActionSource.viewer, rating.round());
},
onClearRating: () async {
await ref.read(actionProvider.notifier).updateRating(ActionSource.viewer, 0);
},
),
],
),
),
],
// Appears in (Albums)
Padding(padding: const EdgeInsets.only(top: 16.0), child: _buildAppearsInList(ref, context)),
// padding at the bottom to avoid cut-off
const SizedBox(height: 60),
], ],
), // Lens info
if (lensTitle != null) ...[
const SizedBox(height: 16),
SheetTile(
title: lensTitle,
titleStyle: context.textTheme.labelLarge,
leading: Icon(Icons.camera_outlined, size: 24, color: context.textTheme.labelLarge?.color),
subtitle: _getLensInfoSubtitle(exifInfo),
subtitleStyle: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
],
// Rating bar
if (isRatingEnabled) ...[
Padding(
padding: const EdgeInsets.only(left: 16.0, top: 16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
Text(
'rating'.t(context: context),
style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurfaceSecondary),
),
RatingBar(
initialRating: exifInfo?.rating?.toDouble() ?? 0,
filledColor: context.themeData.colorScheme.primary,
unfilledColor: context.themeData.colorScheme.onSurface.withAlpha(100),
itemSize: 40,
onRatingUpdate: (rating) async {
await ref.read(actionProvider.notifier).updateRating(ActionSource.viewer, rating.round());
},
onClearRating: () async {
await ref.read(actionProvider.notifier).updateRating(ActionSource.viewer, 0);
},
),
],
),
),
],
// Appears in (Albums)
Padding(padding: const EdgeInsets.only(top: 16.0), child: _buildAppearsInList(ref, context)),
// padding at the bottom to avoid cut-off
const SizedBox(height: 60),
],
); );
} }
} }
@@ -398,4 +407,3 @@ class _SheetAssetDescriptionState extends ConsumerState<_SheetAssetDescription>
); );
} }
} }
@@ -55,7 +55,7 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget {
IconButton( IconButton(
icon: const Icon(Icons.chat_outlined), icon: const Icon(Icons.chat_outlined),
onPressed: () { onPressed: () {
EventStream.shared.emit(const ViewerShowDetailsEvent(activitiesMode: true)); EventStream.shared.emit(const ViewerOpenBottomSheetEvent(activitiesMode: true));
}, },
), ),
@@ -15,7 +15,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
: super( : super(
const ServerInfo( const ServerInfo(
serverVersion: ServerVersion(major: 0, minor: 0, patch: 0), serverVersion: ServerVersion(major: 0, minor: 0, patch: 0),
latestVersion: null, latestVersion: ServerVersion(major: 0, minor: 0, patch: 0),
serverFeatures: ServerFeatures(map: true, trash: true, oauthEnabled: false, passwordLogin: true), serverFeatures: ServerFeatures(map: true, trash: true, oauthEnabled: false, passwordLogin: true),
serverConfig: ServerConfig( serverConfig: ServerConfig(
trashDays: 30, trashDays: 30,
@@ -43,7 +43,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
try { try {
final serverVersion = await _serverInfoService.getServerVersion(); final serverVersion = await _serverInfoService.getServerVersion();
// using isClientOutOfDate since that will show to users regardless of if they are an admin // using isClientOutOfDate since that will show to users reguardless of if they are an admin
if (serverVersion == null) { if (serverVersion == null) {
state = state.copyWith(versionStatus: VersionStatus.error); state = state.copyWith(versionStatus: VersionStatus.error);
return; return;
@@ -76,7 +76,7 @@ class ServerInfoNotifier extends StateNotifier<ServerInfo> {
state = state.copyWith(versionStatus: VersionStatus.upToDate); state = state.copyWith(versionStatus: VersionStatus.upToDate);
} }
handleReleaseInfo(ServerVersion serverVersion, ServerVersion? latestVersion) { handleReleaseInfo(ServerVersion serverVersion, ServerVersion latestVersion) {
// Update local server version // Update local server version
_checkServerVersionMismatch(serverVersion, latestVersion: latestVersion); _checkServerVersionMismatch(serverVersion, latestVersion: latestVersion);
} }
+1 -1
View File
@@ -225,7 +225,7 @@ enum ActionButtonType {
iconData: Icons.info_outline, iconData: Icons.info_outline,
iconColor: context.originalTheme?.iconTheme.color, iconColor: context.originalTheme?.iconTheme.color,
menuItem: true, menuItem: true,
onPressed: () => EventStream.shared.emit(const ViewerShowDetailsEvent()), onPressed: () => EventStream.shared.emit(const ViewerOpenBottomSheetEvent()),
), ),
ActionButtonType.viewInTimeline => BaseActionButton( ActionButtonType.viewInTimeline => BaseActionButton(
label: 'view_in_timeline'.tr(), label: 'view_in_timeline'.tr(),
@@ -170,52 +170,50 @@ class AppBarServerInfo extends HookConsumerWidget {
), ),
], ],
), ),
if (serverInfoState.latestVersion != null) ...[ const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)),
const Padding(padding: EdgeInsets.symmetric(horizontal: 10), child: Divider(thickness: 1)), Row(
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
children: [ Expanded(
Expanded( child: Padding(
child: Padding( padding: const EdgeInsets.only(left: 10.0),
padding: const EdgeInsets.only(left: 10.0), child: Row(
child: Row( children: [
children: [ if (serverInfoState.versionStatus == VersionStatus.serverOutOfDate)
if (serverInfoState.versionStatus == VersionStatus.serverOutOfDate) const Padding(
const Padding( padding: EdgeInsets.only(right: 5.0),
padding: EdgeInsets.only(right: 5.0), child: Icon(Icons.info, color: Color.fromARGB(255, 243, 188, 106), size: 12),
child: Icon(Icons.info, color: Color.fromARGB(255, 243, 188, 106), size: 12), ),
), Text(
Text( "latest_version".tr(),
"latest_version".tr(), style: TextStyle(
style: TextStyle( fontSize: titleFontSize,
fontSize: titleFontSize, color: context.textTheme.labelSmall?.color,
color: context.textTheme.labelSmall?.color, fontWeight: FontWeight.w500,
fontWeight: FontWeight.w500,
),
), ),
],
),
),
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Text(
serverInfoState.latestVersion!.major > 0
? "${serverInfoState.latestVersion!.major}.${serverInfoState.latestVersion!.minor}.${serverInfoState.latestVersion!.patch}"
: "--",
style: TextStyle(
fontSize: contentFontSize,
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
), ),
],
),
),
),
Expanded(
flex: 0,
child: Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Text(
serverInfoState.latestVersion.major > 0
? "${serverInfoState.latestVersion.major}.${serverInfoState.latestVersion.minor}.${serverInfoState.latestVersion.patch}"
: "--",
style: TextStyle(
fontSize: contentFontSize,
color: context.colorScheme.onSurfaceSecondary,
fontWeight: FontWeight.bold,
), ),
), ),
), ),
], ),
), ],
], ),
], ],
), ),
), ),
@@ -414,7 +414,6 @@ class LoginForm extends HookConsumerWidget {
keyboardAction: TextInputAction.next, keyboardAction: TextInputAction.next,
keyboardType: TextInputType.url, keyboardType: TextInputType.url,
autofillHints: const [AutofillHints.url], autofillHints: const [AutofillHints.url],
autoCorrect: false,
onSubmit: (ctx, _) => ImmichForm.of(ctx).submit(), onSubmit: (ctx, _) => ImmichForm.of(ctx).submit(),
), ),
), ),
@@ -203,13 +203,9 @@ class PhotoViewGestureRecognizer extends ScaleGestureRecognizer {
void _decideIfWeAcceptEvent(PointerEvent event) { void _decideIfWeAcceptEvent(PointerEvent event) {
final move = _initialFocalPoint! - _currentFocalPoint!; final move = _initialFocalPoint! - _currentFocalPoint!;
final bool shouldMove = validateAxis == Axis.vertical
// Accept gesture if movement is possible in the direction the user is swiping ? hitDetector!.shouldMove(move, Axis.vertical)
final bool isHorizontalGesture = move.dx.abs() > move.dy.abs(); : hitDetector!.shouldMove(move, Axis.horizontal);
final bool shouldMove = isHorizontalGesture
? hitDetector!.shouldMove(move, Axis.horizontal)
: hitDetector!.shouldMove(move, Axis.vertical);
if (shouldMove || _pointerLocations.keys.length > 1) { if (shouldMove || _pointerLocations.keys.length > 1) {
final double spanDelta = (_currentSpan! - _initialSpan!).abs(); final double spanDelta = (_currentSpan! - _initialSpan!).abs();
final double focalPointDelta = (_currentFocalPoint! - _initialFocalPoint!).distance; final double focalPointDelta = (_currentFocalPoint! - _initialFocalPoint!).distance;
+1 -1
View File
@@ -3,7 +3,7 @@ Immich API
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: 2.5.2 - API version: 2.5.1
- Generator version: 7.8.0 - Generator version: 7.8.0
- Build package: org.openapitools.codegen.languages.DartClientCodegen - Build package: org.openapitools.codegen.languages.DartClientCodegen
-14
View File
@@ -130,19 +130,14 @@ class ActivitiesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId (required): /// * [String] albumId (required):
/// Album ID
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Asset ID (if activity is for an asset)
/// ///
/// * [ReactionLevel] level: /// * [ReactionLevel] level:
/// Filter by activity level
/// ///
/// * [ReactionType] type: /// * [ReactionType] type:
/// Filter by activity type
/// ///
/// * [String] userId: /// * [String] userId:
/// Filter by user ID
Future<Response> getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { Future<Response> getActivitiesWithHttpInfo(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/activities'; final apiPath = r'/activities';
@@ -189,19 +184,14 @@ class ActivitiesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId (required): /// * [String] albumId (required):
/// Album ID
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Asset ID (if activity is for an asset)
/// ///
/// * [ReactionLevel] level: /// * [ReactionLevel] level:
/// Filter by activity level
/// ///
/// * [ReactionType] type: /// * [ReactionType] type:
/// Filter by activity type
/// ///
/// * [String] userId: /// * [String] userId:
/// Filter by user ID
Future<List<ActivityResponseDto>?> getActivities(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async { Future<List<ActivityResponseDto>?> getActivities(String albumId, { String? assetId, ReactionLevel? level, ReactionType? type, String? userId, }) async {
final response = await getActivitiesWithHttpInfo(albumId, assetId: assetId, level: level, type: type, userId: userId, ); final response = await getActivitiesWithHttpInfo(albumId, assetId: assetId, level: level, type: type, userId: userId, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -229,10 +219,8 @@ class ActivitiesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId (required): /// * [String] albumId (required):
/// Album ID
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Asset ID (if activity is for an asset)
Future<Response> getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, }) async { Future<Response> getActivityStatisticsWithHttpInfo(String albumId, { String? assetId, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/activities/statistics'; final apiPath = r'/activities/statistics';
@@ -270,10 +258,8 @@ class ActivitiesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId (required): /// * [String] albumId (required):
/// Album ID
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Asset ID (if activity is for an asset)
Future<ActivityStatisticsResponseDto?> getActivityStatistics(String albumId, { String? assetId, }) async { Future<ActivityStatisticsResponseDto?> getActivityStatistics(String albumId, { String? assetId, }) async {
final response = await getActivityStatisticsWithHttpInfo(albumId, assetId: assetId, ); final response = await getActivityStatisticsWithHttpInfo(albumId, assetId: assetId, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
+2 -6
View File
@@ -347,7 +347,6 @@ class AlbumsApi {
/// * [String] slug: /// * [String] slug:
/// ///
/// * [bool] withoutAssets: /// * [bool] withoutAssets:
/// Exclude assets from response
Future<Response> getAlbumInfoWithHttpInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async { Future<Response> getAlbumInfoWithHttpInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/albums/{id}' final apiPath = r'/albums/{id}'
@@ -397,7 +396,6 @@ class AlbumsApi {
/// * [String] slug: /// * [String] slug:
/// ///
/// * [bool] withoutAssets: /// * [bool] withoutAssets:
/// Exclude assets from response
Future<AlbumResponseDto?> getAlbumInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async { Future<AlbumResponseDto?> getAlbumInfo(String id, { String? key, String? slug, bool? withoutAssets, }) async {
final response = await getAlbumInfoWithHttpInfo(id, key: key, slug: slug, withoutAssets: withoutAssets, ); final response = await getAlbumInfoWithHttpInfo(id, key: key, slug: slug, withoutAssets: withoutAssets, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -470,10 +468,9 @@ class AlbumsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Filter albums containing this asset ID (ignores shared parameter) /// Only returns albums that contain the asset Ignores the shared parameter undefined: get all albums
/// ///
/// * [bool] shared: /// * [bool] shared:
/// Filter by shared status: true = only shared, false = only own, undefined = all
Future<Response> getAllAlbumsWithHttpInfo({ String? assetId, bool? shared, }) async { Future<Response> getAllAlbumsWithHttpInfo({ String? assetId, bool? shared, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/albums'; final apiPath = r'/albums';
@@ -513,10 +510,9 @@ class AlbumsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] assetId: /// * [String] assetId:
/// Filter albums containing this asset ID (ignores shared parameter) /// Only returns albums that contain the asset Ignores the shared parameter undefined: get all albums
/// ///
/// * [bool] shared: /// * [bool] shared:
/// Filter by shared status: true = only shared, false = only own, undefined = all
Future<List<AlbumResponseDto>?> getAllAlbums({ String? assetId, bool? shared, }) async { Future<List<AlbumResponseDto>?> getAllAlbums({ String? assetId, bool? shared, }) async {
final response = await getAllAlbumsWithHttpInfo( assetId: assetId, shared: shared, ); final response = await getAllAlbumsWithHttpInfo( assetId: assetId, shared: shared, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-62
View File
@@ -185,10 +185,8 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Asset ID
/// ///
/// * [String] key (required): /// * [String] key (required):
/// Metadata key
Future<Response> deleteAssetMetadataWithHttpInfo(String id, String key,) async { Future<Response> deleteAssetMetadataWithHttpInfo(String id, String key,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/{id}/metadata/{key}' final apiPath = r'/assets/{id}/metadata/{key}'
@@ -223,10 +221,8 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Asset ID
/// ///
/// * [String] key (required): /// * [String] key (required):
/// Metadata key
Future<void> deleteAssetMetadata(String id, String key,) async { Future<void> deleteAssetMetadata(String id, String key,) async {
final response = await deleteAssetMetadataWithHttpInfo(id, key,); final response = await deleteAssetMetadataWithHttpInfo(id, key,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -341,7 +337,6 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] edited: /// * [bool] edited:
/// Return edited asset if available
/// ///
/// * [String] key: /// * [String] key:
/// ///
@@ -391,7 +386,6 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] edited: /// * [bool] edited:
/// Return edited asset if available
/// ///
/// * [String] key: /// * [String] key:
/// ///
@@ -481,7 +475,6 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
Future<Response> getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { Future<Response> getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/device/{deviceId}' final apiPath = r'/assets/device/{deviceId}'
@@ -515,7 +508,6 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
Future<List<String>?> getAllUserAssetsByDeviceId(String deviceId,) async { Future<List<String>?> getAllUserAssetsByDeviceId(String deviceId,) async {
final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -732,10 +724,8 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Asset ID
/// ///
/// * [String] key (required): /// * [String] key (required):
/// Metadata key
Future<Response> getAssetMetadataByKeyWithHttpInfo(String id, String key,) async { Future<Response> getAssetMetadataByKeyWithHttpInfo(String id, String key,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/{id}/metadata/{key}' final apiPath = r'/assets/{id}/metadata/{key}'
@@ -770,10 +760,8 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Asset ID
/// ///
/// * [String] key (required): /// * [String] key (required):
/// Metadata key
Future<AssetMetadataResponseDto?> getAssetMetadataByKey(String id, String key,) async { Future<AssetMetadataResponseDto?> getAssetMetadataByKey(String id, String key,) async {
final response = await getAssetMetadataByKeyWithHttpInfo(id, key,); final response = await getAssetMetadataByKeyWithHttpInfo(id, key,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -858,13 +846,10 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Filter by trash status
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
Future<Response> getAssetStatisticsWithHttpInfo({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { Future<Response> getAssetStatisticsWithHttpInfo({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/statistics'; final apiPath = r'/assets/statistics';
@@ -907,13 +892,10 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Filter by trash status
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
Future<AssetStatsResponseDto?> getAssetStatistics({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { Future<AssetStatsResponseDto?> getAssetStatistics({ bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
final response = await getAssetStatisticsWithHttpInfo( isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); final response = await getAssetStatisticsWithHttpInfo( isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -938,7 +920,6 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [num] count: /// * [num] count:
/// Number of random assets to return
Future<Response> getRandomWithHttpInfo({ num? count, }) async { Future<Response> getRandomWithHttpInfo({ num? count, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/random'; final apiPath = r'/assets/random';
@@ -975,7 +956,6 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [num] count: /// * [num] count:
/// Number of random assets to return
Future<List<AssetResponseDto>?> getRandom({ num? count, }) async { Future<List<AssetResponseDto>?> getRandom({ num? count, }) async {
final response = await getRandomWithHttpInfo( count: count, ); final response = await getRandomWithHttpInfo( count: count, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -1126,29 +1106,22 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
Future<Response> replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { Future<Response> replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/{id}/original' final apiPath = r'/assets/{id}/original'
@@ -1225,29 +1198,22 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
Future<AssetMediaResponseDto?> replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { Future<AssetMediaResponseDto?> replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async {
final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, ); final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -1552,19 +1518,14 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
@@ -1574,25 +1535,18 @@ class AssetsApi {
/// sha1 checksum that can be used for duplicate detection before the file is uploaded /// sha1 checksum that can be used for duplicate detection before the file is uploaded
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Mark as favorite
/// ///
/// * [String] livePhotoVideoId: /// * [String] livePhotoVideoId:
/// Live photo video ID
/// ///
/// * [List<AssetMetadataUpsertItemDto>] metadata: /// * [List<AssetMetadataUpsertItemDto>] metadata:
/// Asset metadata items
/// ///
/// * [MultipartFile] sidecarData: /// * [MultipartFile] sidecarData:
/// Sidecar file data
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Asset visibility
Future<Response> uploadAssetWithHttpInfo(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List<AssetMetadataUpsertItemDto>? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { Future<Response> uploadAssetWithHttpInfo(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List<AssetMetadataUpsertItemDto>? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets'; final apiPath = r'/assets';
@@ -1691,19 +1645,14 @@ class AssetsApi {
/// Parameters: /// Parameters:
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
@@ -1713,25 +1662,18 @@ class AssetsApi {
/// sha1 checksum that can be used for duplicate detection before the file is uploaded /// sha1 checksum that can be used for duplicate detection before the file is uploaded
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Mark as favorite
/// ///
/// * [String] livePhotoVideoId: /// * [String] livePhotoVideoId:
/// Live photo video ID
/// ///
/// * [List<AssetMetadataUpsertItemDto>] metadata: /// * [List<AssetMetadataUpsertItemDto>] metadata:
/// Asset metadata items
/// ///
/// * [MultipartFile] sidecarData: /// * [MultipartFile] sidecarData:
/// Sidecar file data
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Asset visibility
Future<AssetMediaResponseDto?> uploadAsset(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List<AssetMetadataUpsertItemDto>? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async { Future<AssetMediaResponseDto?> uploadAsset(MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? xImmichChecksum, String? duration, String? filename, bool? isFavorite, String? livePhotoVideoId, List<AssetMetadataUpsertItemDto>? metadata, MultipartFile? sidecarData, AssetVisibility? visibility, }) async {
final response = await uploadAssetWithHttpInfo(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, ); final response = await uploadAssetWithHttpInfo(assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, xImmichChecksum: xImmichChecksum, duration: duration, filename: filename, isFavorite: isFavorite, livePhotoVideoId: livePhotoVideoId, metadata: metadata, sidecarData: sidecarData, visibility: visibility, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -1758,12 +1700,10 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] edited: /// * [bool] edited:
/// Return edited asset if available
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [AssetMediaSize] size: /// * [AssetMediaSize] size:
/// Asset media size
/// ///
/// * [String] slug: /// * [String] slug:
Future<Response> viewAssetWithHttpInfo(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { Future<Response> viewAssetWithHttpInfo(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async {
@@ -1814,12 +1754,10 @@ class AssetsApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] edited: /// * [bool] edited:
/// Return edited asset if available
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [AssetMediaSize] size: /// * [AssetMediaSize] size:
/// Asset media size
/// ///
/// * [String] slug: /// * [String] slug:
Future<MultipartFile?> viewAsset(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async { Future<MultipartFile?> viewAsset(String id, { bool? edited, String? key, AssetMediaSize? size, String? slug, }) async {
-20
View File
@@ -82,7 +82,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
Future<Response> getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async { Future<Response> getAllUserAssetsByDeviceIdWithHttpInfo(String deviceId,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/device/{deviceId}' final apiPath = r'/assets/device/{deviceId}'
@@ -116,7 +115,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
Future<List<String>?> getAllUserAssetsByDeviceId(String deviceId,) async { Future<List<String>?> getAllUserAssetsByDeviceId(String deviceId,) async {
final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,); final response = await getAllUserAssetsByDeviceIdWithHttpInfo(deviceId,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -307,7 +305,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [num] count: /// * [num] count:
/// Number of random assets to return
Future<Response> getRandomWithHttpInfo({ num? count, }) async { Future<Response> getRandomWithHttpInfo({ num? count, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/random'; final apiPath = r'/assets/random';
@@ -344,7 +341,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [num] count: /// * [num] count:
/// Number of random assets to return
Future<List<AssetResponseDto>?> getRandom({ num? count, }) async { Future<List<AssetResponseDto>?> getRandom({ num? count, }) async {
final response = await getRandomWithHttpInfo( count: count, ); final response = await getRandomWithHttpInfo( count: count, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -374,29 +370,22 @@ class DeprecatedApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
Future<Response> replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { Future<Response> replaceAssetWithHttpInfo(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/assets/{id}/original' final apiPath = r'/assets/{id}/original'
@@ -473,29 +462,22 @@ class DeprecatedApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [MultipartFile] assetData (required): /// * [MultipartFile] assetData (required):
/// Asset file data
/// ///
/// * [String] deviceAssetId (required): /// * [String] deviceAssetId (required):
/// Device asset ID
/// ///
/// * [String] deviceId (required): /// * [String] deviceId (required):
/// Device ID
/// ///
/// * [DateTime] fileCreatedAt (required): /// * [DateTime] fileCreatedAt (required):
/// File creation date
/// ///
/// * [DateTime] fileModifiedAt (required): /// * [DateTime] fileModifiedAt (required):
/// File modification date
/// ///
/// * [String] key: /// * [String] key:
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] duration: /// * [String] duration:
/// Duration (for videos)
/// ///
/// * [String] filename: /// * [String] filename:
/// Filename
Future<AssetMediaResponseDto?> replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async { Future<AssetMediaResponseDto?> replaceAsset(String id, MultipartFile assetData, String deviceAssetId, String deviceId, DateTime fileCreatedAt, DateTime fileModifiedAt, { String? key, String? slug, String? duration, String? filename, }) async {
final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, ); final response = await replaceAssetWithHttpInfo(id, assetData, deviceAssetId, deviceId, fileCreatedAt, fileModifiedAt, key: key, slug: slug, duration: duration, filename: filename, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -520,7 +502,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueCommandDto] queueCommandDto (required): /// * [QueueCommandDto] queueCommandDto (required):
Future<Response> runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { Future<Response> runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async {
@@ -556,7 +537,6 @@ class DeprecatedApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueCommandDto] queueCommandDto (required): /// * [QueueCommandDto] queueCommandDto (required):
Future<QueueResponseLegacyDto?> runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { Future<QueueResponseLegacyDto?> runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async {
-2
View File
@@ -126,7 +126,6 @@ class FacesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Face ID
Future<Response> getFacesWithHttpInfo(String id,) async { Future<Response> getFacesWithHttpInfo(String id,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/faces'; final apiPath = r'/faces';
@@ -161,7 +160,6 @@ class FacesApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id (required): /// * [String] id (required):
/// Face ID
Future<List<AssetFaceResponseDto>?> getFaces(String id,) async { Future<List<AssetFaceResponseDto>?> getFaces(String id,) async {
final response = await getFacesWithHttpInfo(id,); final response = await getFacesWithHttpInfo(id,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-2
View File
@@ -121,7 +121,6 @@ class JobsApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueCommandDto] queueCommandDto (required): /// * [QueueCommandDto] queueCommandDto (required):
Future<Response> runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async { Future<Response> runQueueCommandLegacyWithHttpInfo(QueueName name, QueueCommandDto queueCommandDto,) async {
@@ -157,7 +156,6 @@ class JobsApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueCommandDto] queueCommandDto (required): /// * [QueueCommandDto] queueCommandDto (required):
Future<QueueResponseLegacyDto?> runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async { Future<QueueResponseLegacyDto?> runQueueCommandLegacy(QueueName name, QueueCommandDto queueCommandDto,) async {
-16
View File
@@ -25,22 +25,16 @@ class MapApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] fileCreatedAfter: /// * [DateTime] fileCreatedAfter:
/// Filter assets created after this date
/// ///
/// * [DateTime] fileCreatedBefore: /// * [DateTime] fileCreatedBefore:
/// Filter assets created before this date
/// ///
/// * [bool] isArchived: /// * [bool] isArchived:
/// Filter by archived status
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] withPartners: /// * [bool] withPartners:
/// Include partner assets
/// ///
/// * [bool] withSharedAlbums: /// * [bool] withSharedAlbums:
/// Include shared album assets
Future<Response> getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { Future<Response> getMapMarkersWithHttpInfo({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/map/markers'; final apiPath = r'/map/markers';
@@ -92,22 +86,16 @@ class MapApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] fileCreatedAfter: /// * [DateTime] fileCreatedAfter:
/// Filter assets created after this date
/// ///
/// * [DateTime] fileCreatedBefore: /// * [DateTime] fileCreatedBefore:
/// Filter assets created before this date
/// ///
/// * [bool] isArchived: /// * [bool] isArchived:
/// Filter by archived status
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] withPartners: /// * [bool] withPartners:
/// Include partner assets
/// ///
/// * [bool] withSharedAlbums: /// * [bool] withSharedAlbums:
/// Include shared album assets
Future<List<MapMarkerResponseDto>?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async { Future<List<MapMarkerResponseDto>?> getMapMarkers({ DateTime? fileCreatedAfter, DateTime? fileCreatedBefore, bool? isArchived, bool? isFavorite, bool? withPartners, bool? withSharedAlbums, }) async {
final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, withSharedAlbums: withSharedAlbums, ); final response = await getMapMarkersWithHttpInfo( fileCreatedAfter: fileCreatedAfter, fileCreatedBefore: fileCreatedBefore, isArchived: isArchived, isFavorite: isFavorite, withPartners: withPartners, withSharedAlbums: withSharedAlbums, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -135,10 +123,8 @@ class MapApi {
/// Parameters: /// Parameters:
/// ///
/// * [double] lat (required): /// * [double] lat (required):
/// Latitude (-90 to 90)
/// ///
/// * [double] lon (required): /// * [double] lon (required):
/// Longitude (-180 to 180)
Future<Response> reverseGeocodeWithHttpInfo(double lat, double lon,) async { Future<Response> reverseGeocodeWithHttpInfo(double lat, double lon,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/map/reverse-geocode'; final apiPath = r'/map/reverse-geocode';
@@ -174,10 +160,8 @@ class MapApi {
/// Parameters: /// Parameters:
/// ///
/// * [double] lat (required): /// * [double] lat (required):
/// Latitude (-90 to 90)
/// ///
/// * [double] lon (required): /// * [double] lon (required):
/// Longitude (-180 to 180)
Future<List<MapReverseGeocodeResponseDto>?> reverseGeocode(double lat, double lon,) async { Future<List<MapReverseGeocodeResponseDto>?> reverseGeocode(double lat, double lon,) async {
final response = await reverseGeocodeWithHttpInfo(lat, lon,); final response = await reverseGeocodeWithHttpInfo(lat, lon,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-20
View File
@@ -251,22 +251,17 @@ class MemoriesApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] for_: /// * [DateTime] for_:
/// Filter by date
/// ///
/// * [bool] isSaved: /// * [bool] isSaved:
/// Filter by saved status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Include trashed memories
/// ///
/// * [MemorySearchOrder] order: /// * [MemorySearchOrder] order:
/// Sort order
/// ///
/// * [int] size: /// * [int] size:
/// Number of memories to return /// Number of memories to return
/// ///
/// * [MemoryType] type: /// * [MemoryType] type:
/// Memory type
Future<Response> memoriesStatisticsWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { Future<Response> memoriesStatisticsWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/memories/statistics'; final apiPath = r'/memories/statistics';
@@ -318,22 +313,17 @@ class MemoriesApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] for_: /// * [DateTime] for_:
/// Filter by date
/// ///
/// * [bool] isSaved: /// * [bool] isSaved:
/// Filter by saved status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Include trashed memories
/// ///
/// * [MemorySearchOrder] order: /// * [MemorySearchOrder] order:
/// Sort order
/// ///
/// * [int] size: /// * [int] size:
/// Number of memories to return /// Number of memories to return
/// ///
/// * [MemoryType] type: /// * [MemoryType] type:
/// Memory type
Future<MemoryStatisticsResponseDto?> memoriesStatistics({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { Future<MemoryStatisticsResponseDto?> memoriesStatistics({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async {
final response = await memoriesStatisticsWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); final response = await memoriesStatisticsWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -422,22 +412,17 @@ class MemoriesApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] for_: /// * [DateTime] for_:
/// Filter by date
/// ///
/// * [bool] isSaved: /// * [bool] isSaved:
/// Filter by saved status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Include trashed memories
/// ///
/// * [MemorySearchOrder] order: /// * [MemorySearchOrder] order:
/// Sort order
/// ///
/// * [int] size: /// * [int] size:
/// Number of memories to return /// Number of memories to return
/// ///
/// * [MemoryType] type: /// * [MemoryType] type:
/// Memory type
Future<Response> searchMemoriesWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { Future<Response> searchMemoriesWithHttpInfo({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/memories'; final apiPath = r'/memories';
@@ -489,22 +474,17 @@ class MemoriesApi {
/// Parameters: /// Parameters:
/// ///
/// * [DateTime] for_: /// * [DateTime] for_:
/// Filter by date
/// ///
/// * [bool] isSaved: /// * [bool] isSaved:
/// Filter by saved status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Include trashed memories
/// ///
/// * [MemorySearchOrder] order: /// * [MemorySearchOrder] order:
/// Sort order
/// ///
/// * [int] size: /// * [int] size:
/// Number of memories to return /// Number of memories to return
/// ///
/// * [MemoryType] type: /// * [MemoryType] type:
/// Memory type
Future<List<MemoryResponseDto>?> searchMemories({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async { Future<List<MemoryResponseDto>?> searchMemories({ DateTime? for_, bool? isSaved, bool? isTrashed, MemorySearchOrder? order, int? size, MemoryType? type, }) async {
final response = await searchMemoriesWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, ); final response = await searchMemoriesWithHttpInfo( for_: for_, isSaved: isSaved, isTrashed: isTrashed, order: order, size: size, type: type, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-8
View File
@@ -179,16 +179,12 @@ class NotificationsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id: /// * [String] id:
/// Filter by notification ID
/// ///
/// * [NotificationLevel] level: /// * [NotificationLevel] level:
/// Filter by notification level
/// ///
/// * [NotificationType] type: /// * [NotificationType] type:
/// Filter by notification type
/// ///
/// * [bool] unread: /// * [bool] unread:
/// Filter by unread status
Future<Response> getNotificationsWithHttpInfo({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { Future<Response> getNotificationsWithHttpInfo({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/notifications'; final apiPath = r'/notifications';
@@ -234,16 +230,12 @@ class NotificationsApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id: /// * [String] id:
/// Filter by notification ID
/// ///
/// * [NotificationLevel] level: /// * [NotificationLevel] level:
/// Filter by notification level
/// ///
/// * [NotificationType] type: /// * [NotificationType] type:
/// Filter by notification type
/// ///
/// * [bool] unread: /// * [bool] unread:
/// Filter by unread status
Future<List<NotificationDto>?> getNotifications({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async { Future<List<NotificationDto>?> getNotifications({ String? id, NotificationLevel? level, NotificationType? type, bool? unread, }) async {
final response = await getNotificationsWithHttpInfo( id: id, level: level, type: type, unread: unread, ); final response = await getNotificationsWithHttpInfo( id: id, level: level, type: type, unread: unread, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-2
View File
@@ -138,7 +138,6 @@ class PartnersApi {
/// Parameters: /// Parameters:
/// ///
/// * [PartnerDirection] direction (required): /// * [PartnerDirection] direction (required):
/// Partner direction
Future<Response> getPartnersWithHttpInfo(PartnerDirection direction,) async { Future<Response> getPartnersWithHttpInfo(PartnerDirection direction,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/partners'; final apiPath = r'/partners';
@@ -173,7 +172,6 @@ class PartnersApi {
/// Parameters: /// Parameters:
/// ///
/// * [PartnerDirection] direction (required): /// * [PartnerDirection] direction (required):
/// Partner direction
Future<List<PartnerResponseDto>?> getPartners(PartnerDirection direction,) async { Future<List<PartnerResponseDto>?> getPartners(PartnerDirection direction,) async {
final response = await getPartnersWithHttpInfo(direction,); final response = await getPartnersWithHttpInfo(direction,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-6
View File
@@ -178,10 +178,8 @@ class PeopleApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] closestAssetId: /// * [String] closestAssetId:
/// Closest asset ID for similarity search
/// ///
/// * [String] closestPersonId: /// * [String] closestPersonId:
/// Closest person ID for similarity search
/// ///
/// * [num] page: /// * [num] page:
/// Page number for pagination /// Page number for pagination
@@ -190,7 +188,6 @@ class PeopleApi {
/// Number of items per page /// Number of items per page
/// ///
/// * [bool] withHidden: /// * [bool] withHidden:
/// Include hidden people
Future<Response> getAllPeopleWithHttpInfo({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async { Future<Response> getAllPeopleWithHttpInfo({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/people'; final apiPath = r'/people';
@@ -239,10 +236,8 @@ class PeopleApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] closestAssetId: /// * [String] closestAssetId:
/// Closest asset ID for similarity search
/// ///
/// * [String] closestPersonId: /// * [String] closestPersonId:
/// Closest person ID for similarity search
/// ///
/// * [num] page: /// * [num] page:
/// Page number for pagination /// Page number for pagination
@@ -251,7 +246,6 @@ class PeopleApi {
/// Number of items per page /// Number of items per page
/// ///
/// * [bool] withHidden: /// * [bool] withHidden:
/// Include hidden people
Future<PeopleResponseDto?> getAllPeople({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async { Future<PeopleResponseDto?> getAllPeople({ String? closestAssetId, String? closestPersonId, num? page, num? size, bool? withHidden, }) async {
final response = await getAllPeopleWithHttpInfo( closestAssetId: closestAssetId, closestPersonId: closestPersonId, page: page, size: size, withHidden: withHidden, ); final response = await getAllPeopleWithHttpInfo( closestAssetId: closestAssetId, closestPersonId: closestPersonId, page: page, size: size, withHidden: withHidden, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-10
View File
@@ -25,7 +25,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueDeleteDto] queueDeleteDto (required): /// * [QueueDeleteDto] queueDeleteDto (required):
Future<Response> emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto,) async { Future<Response> emptyQueueWithHttpInfo(QueueName name, QueueDeleteDto queueDeleteDto,) async {
@@ -61,7 +60,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueDeleteDto] queueDeleteDto (required): /// * [QueueDeleteDto] queueDeleteDto (required):
Future<void> emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto,) async { Future<void> emptyQueue(QueueName name, QueueDeleteDto queueDeleteDto,) async {
@@ -80,7 +78,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
Future<Response> getQueueWithHttpInfo(QueueName name,) async { Future<Response> getQueueWithHttpInfo(QueueName name,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/queues/{name}' final apiPath = r'/queues/{name}'
@@ -114,7 +111,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
Future<QueueResponseDto?> getQueue(QueueName name,) async { Future<QueueResponseDto?> getQueue(QueueName name,) async {
final response = await getQueueWithHttpInfo(name,); final response = await getQueueWithHttpInfo(name,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -139,10 +135,8 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [List<QueueJobStatus>] status: /// * [List<QueueJobStatus>] status:
/// Filter jobs by status
Future<Response> getQueueJobsWithHttpInfo(QueueName name, { List<QueueJobStatus>? status, }) async { Future<Response> getQueueJobsWithHttpInfo(QueueName name, { List<QueueJobStatus>? status, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/queues/{name}/jobs' final apiPath = r'/queues/{name}/jobs'
@@ -180,10 +174,8 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [List<QueueJobStatus>] status: /// * [List<QueueJobStatus>] status:
/// Filter jobs by status
Future<List<QueueJobResponseDto>?> getQueueJobs(QueueName name, { List<QueueJobStatus>? status, }) async { Future<List<QueueJobResponseDto>?> getQueueJobs(QueueName name, { List<QueueJobStatus>? status, }) async {
final response = await getQueueJobsWithHttpInfo(name, status: status, ); final response = await getQueueJobsWithHttpInfo(name, status: status, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -262,7 +254,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueUpdateDto] queueUpdateDto (required): /// * [QueueUpdateDto] queueUpdateDto (required):
Future<Response> updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto,) async { Future<Response> updateQueueWithHttpInfo(QueueName name, QueueUpdateDto queueUpdateDto,) async {
@@ -298,7 +289,6 @@ class QueuesApi {
/// Parameters: /// Parameters:
/// ///
/// * [QueueName] name (required): /// * [QueueName] name (required):
/// Queue name
/// ///
/// * [QueueUpdateDto] queueUpdateDto (required): /// * [QueueUpdateDto] queueUpdateDto (required):
Future<QueueResponseDto?> updateQueue(QueueName name, QueueUpdateDto queueUpdateDto,) async { Future<QueueResponseDto?> updateQueue(QueueName name, QueueUpdateDto queueUpdateDto,) async {
-84
View File
@@ -127,25 +127,18 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [SearchSuggestionType] type (required): /// * [SearchSuggestionType] type (required):
/// Suggestion type
/// ///
/// * [String] country: /// * [String] country:
/// Filter by country
/// ///
/// * [bool] includeNull: /// * [bool] includeNull:
/// Include null values in suggestions
/// ///
/// * [String] lensModel: /// * [String] lensModel:
/// Filter by lens model
/// ///
/// * [String] make: /// * [String] make:
/// Filter by camera make
/// ///
/// * [String] model: /// * [String] model:
/// Filter by camera model
/// ///
/// * [String] state: /// * [String] state:
/// Filter by state/province
Future<Response> getSearchSuggestionsWithHttpInfo(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { Future<Response> getSearchSuggestionsWithHttpInfo(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/search/suggestions'; final apiPath = r'/search/suggestions';
@@ -198,25 +191,18 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [SearchSuggestionType] type (required): /// * [SearchSuggestionType] type (required):
/// Suggestion type
/// ///
/// * [String] country: /// * [String] country:
/// Filter by country
/// ///
/// * [bool] includeNull: /// * [bool] includeNull:
/// Include null values in suggestions
/// ///
/// * [String] lensModel: /// * [String] lensModel:
/// Filter by lens model
/// ///
/// * [String] make: /// * [String] make:
/// Filter by camera make
/// ///
/// * [String] model: /// * [String] model:
/// Filter by camera model
/// ///
/// * [String] state: /// * [String] state:
/// Filter by state/province
Future<List<String>?> getSearchSuggestions(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async { Future<List<String>?> getSearchSuggestions(SearchSuggestionType type, { String? country, bool? includeNull, String? lensModel, String? make, String? model, String? state, }) async {
final response = await getSearchSuggestionsWithHttpInfo(type, country: country, includeNull: includeNull, lensModel: lensModel, make: make, model: model, state: state, ); final response = await getSearchSuggestionsWithHttpInfo(type, country: country, includeNull: includeNull, lensModel: lensModel, make: make, model: model, state: state, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -356,100 +342,68 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [List<String>] albumIds: /// * [List<String>] albumIds:
/// Filter by album IDs
/// ///
/// * [String] city: /// * [String] city:
/// Filter by city name
/// ///
/// * [String] country: /// * [String] country:
/// Filter by country name
/// ///
/// * [DateTime] createdAfter: /// * [DateTime] createdAfter:
/// Filter by creation date (after)
/// ///
/// * [DateTime] createdBefore: /// * [DateTime] createdBefore:
/// Filter by creation date (before)
/// ///
/// * [String] deviceId: /// * [String] deviceId:
/// Device ID to filter by
/// ///
/// * [bool] isEncoded: /// * [bool] isEncoded:
/// Filter by encoded status
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isMotion: /// * [bool] isMotion:
/// Filter by motion photo status
/// ///
/// * [bool] isNotInAlbum: /// * [bool] isNotInAlbum:
/// Filter assets not in any album
/// ///
/// * [bool] isOffline: /// * [bool] isOffline:
/// Filter by offline status
/// ///
/// * [String] lensModel: /// * [String] lensModel:
/// Filter by lens model
/// ///
/// * [String] libraryId: /// * [String] libraryId:
/// Library ID to filter by
/// ///
/// * [String] make: /// * [String] make:
/// Filter by camera make
/// ///
/// * [int] minFileSize: /// * [int] minFileSize:
/// Minimum file size in bytes
/// ///
/// * [String] model: /// * [String] model:
/// Filter by camera model
/// ///
/// * [String] ocr: /// * [String] ocr:
/// Filter by OCR text content
/// ///
/// * [List<String>] personIds: /// * [List<String>] personIds:
/// Filter by person IDs
/// ///
/// * [num] rating: /// * [num] rating:
/// Filter by rating
/// ///
/// * [num] size: /// * [num] size:
/// Number of results to return
/// ///
/// * [String] state: /// * [String] state:
/// Filter by state/province name
/// ///
/// * [List<String>] tagIds: /// * [List<String>] tagIds:
/// Filter by tag IDs
/// ///
/// * [DateTime] takenAfter: /// * [DateTime] takenAfter:
/// Filter by taken date (after)
/// ///
/// * [DateTime] takenBefore: /// * [DateTime] takenBefore:
/// Filter by taken date (before)
/// ///
/// * [DateTime] trashedAfter: /// * [DateTime] trashedAfter:
/// Filter by trash date (after)
/// ///
/// * [DateTime] trashedBefore: /// * [DateTime] trashedBefore:
/// Filter by trash date (before)
/// ///
/// * [AssetTypeEnum] type: /// * [AssetTypeEnum] type:
/// Asset type filter
/// ///
/// * [DateTime] updatedAfter: /// * [DateTime] updatedAfter:
/// Filter by update date (after)
/// ///
/// * [DateTime] updatedBefore: /// * [DateTime] updatedBefore:
/// Filter by update date (before)
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
/// ///
/// * [bool] withDeleted: /// * [bool] withDeleted:
/// Include deleted assets
/// ///
/// * [bool] withExif: /// * [bool] withExif:
/// Include EXIF data in response
Future<Response> searchLargeAssetsWithHttpInfo({ List<String>? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List<String>? personIds, num? rating, num? size, String? state, List<String>? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { Future<Response> searchLargeAssetsWithHttpInfo({ List<String>? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List<String>? personIds, num? rating, num? size, String? state, List<String>? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/search/large-assets'; final apiPath = r'/search/large-assets';
@@ -579,100 +533,68 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [List<String>] albumIds: /// * [List<String>] albumIds:
/// Filter by album IDs
/// ///
/// * [String] city: /// * [String] city:
/// Filter by city name
/// ///
/// * [String] country: /// * [String] country:
/// Filter by country name
/// ///
/// * [DateTime] createdAfter: /// * [DateTime] createdAfter:
/// Filter by creation date (after)
/// ///
/// * [DateTime] createdBefore: /// * [DateTime] createdBefore:
/// Filter by creation date (before)
/// ///
/// * [String] deviceId: /// * [String] deviceId:
/// Device ID to filter by
/// ///
/// * [bool] isEncoded: /// * [bool] isEncoded:
/// Filter by encoded status
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isMotion: /// * [bool] isMotion:
/// Filter by motion photo status
/// ///
/// * [bool] isNotInAlbum: /// * [bool] isNotInAlbum:
/// Filter assets not in any album
/// ///
/// * [bool] isOffline: /// * [bool] isOffline:
/// Filter by offline status
/// ///
/// * [String] lensModel: /// * [String] lensModel:
/// Filter by lens model
/// ///
/// * [String] libraryId: /// * [String] libraryId:
/// Library ID to filter by
/// ///
/// * [String] make: /// * [String] make:
/// Filter by camera make
/// ///
/// * [int] minFileSize: /// * [int] minFileSize:
/// Minimum file size in bytes
/// ///
/// * [String] model: /// * [String] model:
/// Filter by camera model
/// ///
/// * [String] ocr: /// * [String] ocr:
/// Filter by OCR text content
/// ///
/// * [List<String>] personIds: /// * [List<String>] personIds:
/// Filter by person IDs
/// ///
/// * [num] rating: /// * [num] rating:
/// Filter by rating
/// ///
/// * [num] size: /// * [num] size:
/// Number of results to return
/// ///
/// * [String] state: /// * [String] state:
/// Filter by state/province name
/// ///
/// * [List<String>] tagIds: /// * [List<String>] tagIds:
/// Filter by tag IDs
/// ///
/// * [DateTime] takenAfter: /// * [DateTime] takenAfter:
/// Filter by taken date (after)
/// ///
/// * [DateTime] takenBefore: /// * [DateTime] takenBefore:
/// Filter by taken date (before)
/// ///
/// * [DateTime] trashedAfter: /// * [DateTime] trashedAfter:
/// Filter by trash date (after)
/// ///
/// * [DateTime] trashedBefore: /// * [DateTime] trashedBefore:
/// Filter by trash date (before)
/// ///
/// * [AssetTypeEnum] type: /// * [AssetTypeEnum] type:
/// Asset type filter
/// ///
/// * [DateTime] updatedAfter: /// * [DateTime] updatedAfter:
/// Filter by update date (after)
/// ///
/// * [DateTime] updatedBefore: /// * [DateTime] updatedBefore:
/// Filter by update date (before)
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
/// ///
/// * [bool] withDeleted: /// * [bool] withDeleted:
/// Include deleted assets
/// ///
/// * [bool] withExif: /// * [bool] withExif:
/// Include EXIF data in response
Future<List<AssetResponseDto>?> searchLargeAssets({ List<String>? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List<String>? personIds, num? rating, num? size, String? state, List<String>? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async { Future<List<AssetResponseDto>?> searchLargeAssets({ List<String>? albumIds, String? city, String? country, DateTime? createdAfter, DateTime? createdBefore, String? deviceId, bool? isEncoded, bool? isFavorite, bool? isMotion, bool? isNotInAlbum, bool? isOffline, String? lensModel, String? libraryId, String? make, int? minFileSize, String? model, String? ocr, List<String>? personIds, num? rating, num? size, String? state, List<String>? tagIds, DateTime? takenAfter, DateTime? takenBefore, DateTime? trashedAfter, DateTime? trashedBefore, AssetTypeEnum? type, DateTime? updatedAfter, DateTime? updatedBefore, AssetVisibility? visibility, bool? withDeleted, bool? withExif, }) async {
final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceId: deviceId, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, ); final response = await searchLargeAssetsWithHttpInfo( albumIds: albumIds, city: city, country: country, createdAfter: createdAfter, createdBefore: createdBefore, deviceId: deviceId, isEncoded: isEncoded, isFavorite: isFavorite, isMotion: isMotion, isNotInAlbum: isNotInAlbum, isOffline: isOffline, lensModel: lensModel, libraryId: libraryId, make: make, minFileSize: minFileSize, model: model, ocr: ocr, personIds: personIds, rating: rating, size: size, state: state, tagIds: tagIds, takenAfter: takenAfter, takenBefore: takenBefore, trashedAfter: trashedAfter, trashedBefore: trashedBefore, type: type, updatedAfter: updatedAfter, updatedBefore: updatedBefore, visibility: visibility, withDeleted: withDeleted, withExif: withExif, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -700,10 +622,8 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] name (required): /// * [String] name (required):
/// Person name to search for
/// ///
/// * [bool] withHidden: /// * [bool] withHidden:
/// Include hidden people
Future<Response> searchPersonWithHttpInfo(String name, { bool? withHidden, }) async { Future<Response> searchPersonWithHttpInfo(String name, { bool? withHidden, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/search/person'; final apiPath = r'/search/person';
@@ -741,10 +661,8 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] name (required): /// * [String] name (required):
/// Person name to search for
/// ///
/// * [bool] withHidden: /// * [bool] withHidden:
/// Include hidden people
Future<List<PersonResponseDto>?> searchPerson(String name, { bool? withHidden, }) async { Future<List<PersonResponseDto>?> searchPerson(String name, { bool? withHidden, }) async {
final response = await searchPersonWithHttpInfo(name, withHidden: withHidden, ); final response = await searchPersonWithHttpInfo(name, withHidden: withHidden, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -772,7 +690,6 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] name (required): /// * [String] name (required):
/// Place name to search for
Future<Response> searchPlacesWithHttpInfo(String name,) async { Future<Response> searchPlacesWithHttpInfo(String name,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/search/places'; final apiPath = r'/search/places';
@@ -807,7 +724,6 @@ class SearchApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] name (required): /// * [String] name (required):
/// Place name to search for
Future<List<PlacesResponseDto>?> searchPlaces(String name,) async { Future<List<PlacesResponseDto>?> searchPlaces(String name,) async {
final response = await searchPlacesWithHttpInfo(name,); final response = await searchPlacesWithHttpInfo(name,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-8
View File
@@ -160,10 +160,8 @@ class SharedLinksApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId: /// * [String] albumId:
/// Filter by album ID
/// ///
/// * [String] id: /// * [String] id:
/// Filter by shared link ID
Future<Response> getAllSharedLinksWithHttpInfo({ String? albumId, String? id, }) async { Future<Response> getAllSharedLinksWithHttpInfo({ String? albumId, String? id, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/shared-links'; final apiPath = r'/shared-links';
@@ -203,10 +201,8 @@ class SharedLinksApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] albumId: /// * [String] albumId:
/// Filter by album ID
/// ///
/// * [String] id: /// * [String] id:
/// Filter by shared link ID
Future<List<SharedLinkResponseDto>?> getAllSharedLinks({ String? albumId, String? id, }) async { Future<List<SharedLinkResponseDto>?> getAllSharedLinks({ String? albumId, String? id, }) async {
final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, id: id, ); final response = await getAllSharedLinksWithHttpInfo( albumId: albumId, id: id, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -236,12 +232,10 @@ class SharedLinksApi {
/// * [String] key: /// * [String] key:
/// ///
/// * [String] password: /// * [String] password:
/// Link password
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] token: /// * [String] token:
/// Access token
Future<Response> getMySharedLinkWithHttpInfo({ String? key, String? password, String? slug, String? token, }) async { Future<Response> getMySharedLinkWithHttpInfo({ String? key, String? password, String? slug, String? token, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/shared-links/me'; final apiPath = r'/shared-links/me';
@@ -289,12 +283,10 @@ class SharedLinksApi {
/// * [String] key: /// * [String] key:
/// ///
/// * [String] password: /// * [String] password:
/// Link password
/// ///
/// * [String] slug: /// * [String] slug:
/// ///
/// * [String] token: /// * [String] token:
/// Access token
Future<SharedLinkResponseDto?> getMySharedLink({ String? key, String? password, String? slug, String? token, }) async { Future<SharedLinkResponseDto?> getMySharedLink({ String? key, String? password, String? slug, String? token, }) async {
final response = await getMySharedLinkWithHttpInfo( key: key, password: password, slug: slug, token: token, ); final response = await getMySharedLinkWithHttpInfo( key: key, password: password, slug: slug, token: token, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-2
View File
@@ -289,7 +289,6 @@ class StacksApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] primaryAssetId: /// * [String] primaryAssetId:
/// Filter by primary asset ID
Future<Response> searchStacksWithHttpInfo({ String? primaryAssetId, }) async { Future<Response> searchStacksWithHttpInfo({ String? primaryAssetId, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/stacks'; final apiPath = r'/stacks';
@@ -326,7 +325,6 @@ class StacksApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] primaryAssetId: /// * [String] primaryAssetId:
/// Filter by primary asset ID
Future<List<StackResponseDto>?> searchStacks({ String? primaryAssetId, }) async { Future<List<StackResponseDto>?> searchStacks({ String? primaryAssetId, }) async {
final response = await searchStacksWithHttpInfo( primaryAssetId: primaryAssetId, ); final response = await searchStacksWithHttpInfo( primaryAssetId: primaryAssetId, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-10
View File
@@ -318,13 +318,10 @@ class UsersAdminApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Filter by trash status
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
Future<Response> getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { Future<Response> getUserStatisticsAdminWithHttpInfo(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/admin/users/{id}/statistics' final apiPath = r'/admin/users/{id}/statistics'
@@ -370,13 +367,10 @@ class UsersAdminApi {
/// * [String] id (required): /// * [String] id (required):
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// Filter by favorite status
/// ///
/// * [bool] isTrashed: /// * [bool] isTrashed:
/// Filter by trash status
/// ///
/// * [AssetVisibility] visibility: /// * [AssetVisibility] visibility:
/// Filter by visibility
Future<AssetStatsResponseDto?> getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async { Future<AssetStatsResponseDto?> getUserStatisticsAdmin(String id, { bool? isFavorite, bool? isTrashed, AssetVisibility? visibility, }) async {
final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, ); final response = await getUserStatisticsAdminWithHttpInfo(id, isFavorite: isFavorite, isTrashed: isTrashed, visibility: visibility, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
@@ -458,10 +452,8 @@ class UsersAdminApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id: /// * [String] id:
/// User ID filter
/// ///
/// * [bool] withDeleted: /// * [bool] withDeleted:
/// Include deleted users
Future<Response> searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, }) async { Future<Response> searchUsersAdminWithHttpInfo({ String? id, bool? withDeleted, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/admin/users'; final apiPath = r'/admin/users';
@@ -501,10 +493,8 @@ class UsersAdminApi {
/// Parameters: /// Parameters:
/// ///
/// * [String] id: /// * [String] id:
/// User ID filter
/// ///
/// * [bool] withDeleted: /// * [bool] withDeleted:
/// Include deleted users
Future<List<UserAdminResponseDto>?> searchUsersAdmin({ String? id, bool? withDeleted, }) async { Future<List<UserAdminResponseDto>?> searchUsersAdmin({ String? id, bool? withDeleted, }) async {
final response = await searchUsersAdminWithHttpInfo( id: id, withDeleted: withDeleted, ); final response = await searchUsersAdminWithHttpInfo( id: id, withDeleted: withDeleted, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-2
View File
@@ -25,7 +25,6 @@ class UsersApi {
/// Parameters: /// Parameters:
/// ///
/// * [MultipartFile] file (required): /// * [MultipartFile] file (required):
/// Profile image file
Future<Response> createProfileImageWithHttpInfo(MultipartFile file,) async { Future<Response> createProfileImageWithHttpInfo(MultipartFile file,) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final apiPath = r'/users/profile-image'; final apiPath = r'/users/profile-image';
@@ -68,7 +67,6 @@ class UsersApi {
/// Parameters: /// Parameters:
/// ///
/// * [MultipartFile] file (required): /// * [MultipartFile] file (required):
/// Profile image file
Future<CreateProfileImageResponseDto?> createProfileImage(MultipartFile file,) async { Future<CreateProfileImageResponseDto?> createProfileImage(MultipartFile file,) async {
final response = await createProfileImageWithHttpInfo(file,); final response = await createProfileImageWithHttpInfo(file,);
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
-4
View File
@@ -19,10 +19,8 @@ class ActivityCreateDto {
required this.type, required this.type,
}); });
/// Album ID
String albumId; String albumId;
/// Asset ID (if activity is for an asset)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -31,7 +29,6 @@ class ActivityCreateDto {
/// ///
String? assetId; String? assetId;
/// Comment text (required if type is comment)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -40,7 +37,6 @@ class ActivityCreateDto {
/// ///
String? comment; String? comment;
/// Activity type (like or comment)
ReactionType type; ReactionType type;
@override @override
-5
View File
@@ -21,19 +21,14 @@ class ActivityResponseDto {
required this.user, required this.user,
}); });
/// Asset ID (if activity is for an asset)
String? assetId; String? assetId;
/// Comment text (for comment activities)
String? comment; String? comment;
/// Creation date
DateTime createdAt; DateTime createdAt;
/// Activity ID
String id; String id;
/// Activity type
ReactionType type; ReactionType type;
UserResponseDto user; UserResponseDto user;
@@ -17,10 +17,8 @@ class ActivityStatisticsResponseDto {
required this.likes, required this.likes,
}); });
/// Number of comments
int comments; int comments;
/// Number of likes
int likes; int likes;
@override @override
-1
View File
@@ -16,7 +16,6 @@ class AddUsersDto {
this.albumUsers = const [], this.albumUsers = const [],
}); });
/// Album users to add
List<AlbumUserAddDto> albumUsers; List<AlbumUserAddDto> albumUsers;
@override @override
@@ -16,7 +16,6 @@ class AdminOnboardingUpdateDto {
required this.isOnboarded, required this.isOnboarded,
}); });
/// Is admin onboarded
bool isOnboarded; bool isOnboarded;
@override @override
-15
View File
@@ -34,28 +34,22 @@ class AlbumResponseDto {
required this.updatedAt, required this.updatedAt,
}); });
/// Album name
String albumName; String albumName;
/// Thumbnail asset ID
String? albumThumbnailAssetId; String? albumThumbnailAssetId;
List<AlbumUserResponseDto> albumUsers; List<AlbumUserResponseDto> albumUsers;
/// Number of assets
int assetCount; int assetCount;
List<AssetResponseDto> assets; List<AssetResponseDto> assets;
List<ContributorCountResponseDto> contributorCounts; List<ContributorCountResponseDto> contributorCounts;
/// Creation date
DateTime createdAt; DateTime createdAt;
/// Album description
String description; String description;
/// End date (latest asset)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -64,16 +58,12 @@ class AlbumResponseDto {
/// ///
DateTime? endDate; DateTime? endDate;
/// Has shared link
bool hasSharedLink; bool hasSharedLink;
/// Album ID
String id; String id;
/// Activity feed enabled
bool isActivityEnabled; bool isActivityEnabled;
/// Last modified asset timestamp
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -82,7 +72,6 @@ class AlbumResponseDto {
/// ///
DateTime? lastModifiedAssetTimestamp; DateTime? lastModifiedAssetTimestamp;
/// Asset sort order
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -93,13 +82,10 @@ class AlbumResponseDto {
UserResponseDto owner; UserResponseDto owner;
/// Owner user ID
String ownerId; String ownerId;
/// Is shared album
bool shared; bool shared;
/// Start date (earliest asset)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -108,7 +94,6 @@ class AlbumResponseDto {
/// ///
DateTime? startDate; DateTime? startDate;
/// Last update date
DateTime updatedAt; DateTime updatedAt;
@override @override
@@ -18,13 +18,10 @@ class AlbumStatisticsResponseDto {
required this.shared, required this.shared,
}); });
/// Number of non-shared albums
int notShared; int notShared;
/// Number of owned albums
int owned; int owned;
/// Number of shared albums
int shared; int shared;
@override @override
-2
View File
@@ -17,10 +17,8 @@ class AlbumUserAddDto {
required this.userId, required this.userId,
}); });
/// Album user role
AlbumUserRole role; AlbumUserRole role;
/// User ID
String userId; String userId;
@override @override
-2
View File
@@ -17,10 +17,8 @@ class AlbumUserCreateDto {
required this.userId, required this.userId,
}); });
/// Album user role
AlbumUserRole role; AlbumUserRole role;
/// User ID
String userId; String userId;
@override @override
-1
View File
@@ -17,7 +17,6 @@ class AlbumUserResponseDto {
required this.user, required this.user,
}); });
/// Album user role
AlbumUserRole role; AlbumUserRole role;
UserResponseDto user; UserResponseDto user;
+1 -1
View File
@@ -10,7 +10,7 @@
part of openapi.api; part of openapi.api;
/// Album user role
class AlbumUserRole { class AlbumUserRole {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AlbumUserRole._(this.value); const AlbumUserRole._(this.value);
-2
View File
@@ -17,10 +17,8 @@ class AlbumsAddAssetsDto {
this.assetIds = const [], this.assetIds = const [],
}); });
/// Album IDs
List<String> albumIds; List<String> albumIds;
/// Asset IDs
List<String> assetIds; List<String> assetIds;
@override @override
@@ -17,7 +17,6 @@ class AlbumsAddAssetsResponseDto {
required this.success, required this.success,
}); });
/// Error reason
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -26,7 +25,6 @@ class AlbumsAddAssetsResponseDto {
/// ///
BulkIdErrorReason? error; BulkIdErrorReason? error;
/// Operation success
bool success; bool success;
@override @override
-1
View File
@@ -16,7 +16,6 @@ class AlbumsResponse {
this.defaultAssetOrder = AssetOrder.desc, this.defaultAssetOrder = AssetOrder.desc,
}); });
/// Default asset order for albums
AssetOrder defaultAssetOrder; AssetOrder defaultAssetOrder;
@override @override
-1
View File
@@ -16,7 +16,6 @@ class AlbumsUpdate {
this.defaultAssetOrder, this.defaultAssetOrder,
}); });
/// Default asset order for albums
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
-2
View File
@@ -17,7 +17,6 @@ class APIKeyCreateDto {
this.permissions = const [], this.permissions = const [],
}); });
/// API key name
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -26,7 +25,6 @@ class APIKeyCreateDto {
/// ///
String? name; String? name;
/// List of permissions
List<Permission> permissions; List<Permission> permissions;
@override @override
@@ -19,7 +19,6 @@ class APIKeyCreateResponseDto {
APIKeyResponseDto apiKey; APIKeyResponseDto apiKey;
/// API key secret (only shown once)
String secret; String secret;
@override @override
-5
View File
@@ -20,19 +20,14 @@ class APIKeyResponseDto {
required this.updatedAt, required this.updatedAt,
}); });
/// Creation date
DateTime createdAt; DateTime createdAt;
/// API key ID
String id; String id;
/// API key name
String name; String name;
/// List of permissions
List<Permission> permissions; List<Permission> permissions;
/// Last update date
DateTime updatedAt; DateTime updatedAt;
@override @override
-2
View File
@@ -17,7 +17,6 @@ class APIKeyUpdateDto {
this.permissions = const [], this.permissions = const [],
}); });
/// API key name
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -26,7 +25,6 @@ class APIKeyUpdateDto {
/// ///
String? name; String? name;
/// List of permissions
List<Permission> permissions; List<Permission> permissions;
@override @override
-2
View File
@@ -17,7 +17,6 @@ class AssetBulkDeleteDto {
this.ids = const [], this.ids = const [],
}); });
/// Force delete even if in use
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -26,7 +25,6 @@ class AssetBulkDeleteDto {
/// ///
bool? force; bool? force;
/// IDs to process
List<String> ids; List<String> ids;
@override @override
-12
View File
@@ -26,7 +26,6 @@ class AssetBulkUpdateDto {
this.visibility, this.visibility,
}); });
/// Original date and time
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -35,7 +34,6 @@ class AssetBulkUpdateDto {
/// ///
String? dateTimeOriginal; String? dateTimeOriginal;
/// Relative time offset in seconds
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -44,7 +42,6 @@ class AssetBulkUpdateDto {
/// ///
num? dateTimeRelative; num? dateTimeRelative;
/// Asset description
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -53,13 +50,10 @@ class AssetBulkUpdateDto {
/// ///
String? description; String? description;
/// Duplicate asset ID
String? duplicateId; String? duplicateId;
/// Asset IDs to update
List<String> ids; List<String> ids;
/// Mark as favorite
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -68,7 +62,6 @@ class AssetBulkUpdateDto {
/// ///
bool? isFavorite; bool? isFavorite;
/// Latitude coordinate
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -77,7 +70,6 @@ class AssetBulkUpdateDto {
/// ///
num? latitude; num? latitude;
/// Longitude coordinate
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -86,8 +78,6 @@ class AssetBulkUpdateDto {
/// ///
num? longitude; num? longitude;
/// Rating
///
/// Minimum value: -1 /// Minimum value: -1
/// Maximum value: 5 /// Maximum value: 5
/// ///
@@ -98,7 +88,6 @@ class AssetBulkUpdateDto {
/// ///
num? rating; num? rating;
/// Time zone (IANA timezone)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -107,7 +96,6 @@ class AssetBulkUpdateDto {
/// ///
String? timeZone; String? timeZone;
/// Asset visibility
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -16,7 +16,6 @@ class AssetBulkUploadCheckDto {
this.assets = const [], this.assets = const [],
}); });
/// Assets to check
List<AssetBulkUploadCheckItem> assets; List<AssetBulkUploadCheckItem> assets;
@override @override
+1 -2
View File
@@ -17,10 +17,9 @@ class AssetBulkUploadCheckItem {
required this.id, required this.id,
}); });
/// Base64 or hex encoded SHA1 hash /// base64 or hex encoded sha1 hash
String checksum; String checksum;
/// Asset ID
String id; String id;
@override @override
@@ -16,7 +16,6 @@ class AssetBulkUploadCheckResponseDto {
this.results = const [], this.results = const [],
}); });
/// Upload check results
List<AssetBulkUploadCheckResult> results; List<AssetBulkUploadCheckResult> results;
@override @override
@@ -20,10 +20,8 @@ class AssetBulkUploadCheckResult {
this.reason, this.reason,
}); });
/// Upload action
AssetBulkUploadCheckResultActionEnum action; AssetBulkUploadCheckResultActionEnum action;
/// Existing asset ID if duplicate
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -32,10 +30,8 @@ class AssetBulkUploadCheckResult {
/// ///
String? assetId; String? assetId;
/// Asset ID
String id; String id;
/// Whether existing asset is trashed
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -44,7 +40,6 @@ class AssetBulkUploadCheckResult {
/// ///
bool? isTrashed; bool? isTrashed;
/// Rejection reason if rejected
AssetBulkUploadCheckResultReasonEnum? reason; AssetBulkUploadCheckResultReasonEnum? reason;
@override @override
@@ -155,7 +150,7 @@ class AssetBulkUploadCheckResult {
}; };
} }
/// Upload action
class AssetBulkUploadCheckResultActionEnum { class AssetBulkUploadCheckResultActionEnum {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetBulkUploadCheckResultActionEnum._(this.value); const AssetBulkUploadCheckResultActionEnum._(this.value);
@@ -229,7 +224,7 @@ class AssetBulkUploadCheckResultActionEnumTypeTransformer {
} }
/// Rejection reason if rejected
class AssetBulkUploadCheckResultReasonEnum { class AssetBulkUploadCheckResultReasonEnum {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetBulkUploadCheckResultReasonEnum._(this.value); const AssetBulkUploadCheckResultReasonEnum._(this.value);
-7
View File
@@ -22,25 +22,18 @@ class AssetCopyDto {
required this.targetId, required this.targetId,
}); });
/// Copy album associations
bool albums; bool albums;
/// Copy favorite status
bool favorite; bool favorite;
/// Copy shared links
bool sharedLinks; bool sharedLinks;
/// Copy sidecar file
bool sidecar; bool sidecar;
/// Source asset ID
String sourceId; String sourceId;
/// Copy stack association
bool stack; bool stack;
/// Target asset ID
String targetId; String targetId;
@override @override
-2
View File
@@ -17,10 +17,8 @@ class AssetDeltaSyncDto {
this.userIds = const [], this.userIds = const [],
}); });
/// Sync assets updated after this date
DateTime updatedAfter; DateTime updatedAfter;
/// User IDs to sync
List<String> userIds; List<String> userIds;
@override @override
@@ -18,13 +18,10 @@ class AssetDeltaSyncResponseDto {
this.upserted = const [], this.upserted = const [],
}); });
/// Deleted asset IDs
List<String> deleted; List<String> deleted;
/// Whether full sync is needed
bool needsFullSync; bool needsFullSync;
/// Upserted assets
List<AssetResponseDto> upserted; List<AssetResponseDto> upserted;
@override @override
+1 -1
View File
@@ -10,7 +10,7 @@
part of openapi.api; part of openapi.api;
/// Type of edit action to perform
class AssetEditAction { class AssetEditAction {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetEditAction._(this.value); const AssetEditAction._(this.value);
-1
View File
@@ -17,7 +17,6 @@ class AssetEditActionCrop {
required this.parameters, required this.parameters,
}); });
/// Type of edit action to perform
AssetEditAction action; AssetEditAction action;
CropParameters parameters; CropParameters parameters;
+1 -1
View File
@@ -16,7 +16,7 @@ class AssetEditActionListDto {
this.edits = const [], this.edits = const [],
}); });
/// List of edit actions to apply (crop, rotate, or mirror) /// list of edits
List<AssetEditActionListDtoEditsInner> edits; List<AssetEditActionListDtoEditsInner> edits;
@override @override
@@ -17,7 +17,6 @@ class AssetEditActionListDtoEditsInner {
required this.parameters, required this.parameters,
}); });
/// Type of edit action to perform
AssetEditAction action; AssetEditAction action;
MirrorParameters parameters; MirrorParameters parameters;
-1
View File
@@ -17,7 +17,6 @@ class AssetEditActionMirror {
required this.parameters, required this.parameters,
}); });
/// Type of edit action to perform
AssetEditAction action; AssetEditAction action;
MirrorParameters parameters; MirrorParameters parameters;
-1
View File
@@ -17,7 +17,6 @@ class AssetEditActionRotate {
required this.parameters, required this.parameters,
}); });
/// Type of edit action to perform
AssetEditAction action; AssetEditAction action;
RotateParameters parameters; RotateParameters parameters;
+1 -2
View File
@@ -17,10 +17,9 @@ class AssetEditsDto {
this.edits = const [], this.edits = const [],
}); });
/// Asset ID to apply edits to
String assetId; String assetId;
/// List of edit actions to apply (crop, rotate, or mirror) /// list of edits
List<AssetEditActionListDtoEditsInner> edits; List<AssetEditActionListDtoEditsInner> edits;
@override @override
-8
View File
@@ -23,28 +23,20 @@ class AssetFaceCreateDto {
required this.y, required this.y,
}); });
/// Asset ID
String assetId; String assetId;
/// Face bounding box height
int height; int height;
/// Image height in pixels
int imageHeight; int imageHeight;
/// Image width in pixels
int imageWidth; int imageWidth;
/// Person ID
String personId; String personId;
/// Face bounding box width
int width; int width;
/// Face bounding box X coordinate
int x; int x;
/// Face bounding box Y coordinate
int y; int y;
@override @override
-1
View File
@@ -16,7 +16,6 @@ class AssetFaceDeleteDto {
required this.force, required this.force,
}); });
/// Force delete even if person has other faces
bool force; bool force;
@override @override
-9
View File
@@ -24,31 +24,22 @@ class AssetFaceResponseDto {
this.sourceType, this.sourceType,
}); });
/// Bounding box X1 coordinate
int boundingBoxX1; int boundingBoxX1;
/// Bounding box X2 coordinate
int boundingBoxX2; int boundingBoxX2;
/// Bounding box Y1 coordinate
int boundingBoxY1; int boundingBoxY1;
/// Bounding box Y2 coordinate
int boundingBoxY2; int boundingBoxY2;
/// Face ID
String id; String id;
/// Image height in pixels
int imageHeight; int imageHeight;
/// Image width in pixels
int imageWidth; int imageWidth;
/// Person associated with face
PersonResponseDto? person; PersonResponseDto? person;
/// Face detection source type
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
-1
View File
@@ -16,7 +16,6 @@ class AssetFaceUpdateDto {
this.data = const [], this.data = const [],
}); });
/// Face update items
List<AssetFaceUpdateItem> data; List<AssetFaceUpdateItem> data;
@override @override
-2
View File
@@ -17,10 +17,8 @@ class AssetFaceUpdateItem {
required this.personId, required this.personId,
}); });
/// Asset ID
String assetId; String assetId;
/// Person ID
String personId; String personId;
@override @override
@@ -23,28 +23,20 @@ class AssetFaceWithoutPersonResponseDto {
this.sourceType, this.sourceType,
}); });
/// Bounding box X1 coordinate
int boundingBoxX1; int boundingBoxX1;
/// Bounding box X2 coordinate
int boundingBoxX2; int boundingBoxX2;
/// Bounding box Y1 coordinate
int boundingBoxY1; int boundingBoxY1;
/// Bounding box Y2 coordinate
int boundingBoxY2; int boundingBoxY2;
/// Face ID
String id; String id;
/// Image height in pixels
int imageHeight; int imageHeight;
/// Image width in pixels
int imageWidth; int imageWidth;
/// Face detection source type
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
-5
View File
@@ -19,7 +19,6 @@ class AssetFullSyncDto {
this.userId, this.userId,
}); });
/// Last asset ID (pagination)
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
@@ -28,15 +27,11 @@ class AssetFullSyncDto {
/// ///
String? lastId; String? lastId;
/// Maximum number of assets to return
///
/// Minimum value: 1 /// Minimum value: 1
int limit; int limit;
/// Sync assets updated until this date
DateTime updatedUntil; DateTime updatedUntil;
/// Filter by user ID
/// ///
/// Please note: This property should have been non-nullable! Since the specification file /// 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 /// does not include a default value (using the "default:" property), however, the generated
-1
View File
@@ -16,7 +16,6 @@ class AssetIdsDto {
this.assetIds = const [], this.assetIds = const [],
}); });
/// Asset IDs
List<String> assetIds; List<String> assetIds;
@override @override
+1 -4
View File
@@ -18,13 +18,10 @@ class AssetIdsResponseDto {
required this.success, required this.success,
}); });
/// Asset ID
String assetId; String assetId;
/// Error reason if failed
AssetIdsResponseDtoErrorEnum? error; AssetIdsResponseDtoErrorEnum? error;
/// Whether operation succeeded
bool success; bool success;
@override @override
@@ -119,7 +116,7 @@ class AssetIdsResponseDto {
}; };
} }
/// Error reason if failed
class AssetIdsResponseDtoErrorEnum { class AssetIdsResponseDtoErrorEnum {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetIdsResponseDtoErrorEnum._(this.value); const AssetIdsResponseDtoErrorEnum._(this.value);
+1 -1
View File
@@ -10,7 +10,7 @@
part of openapi.api; part of openapi.api;
/// Job name
class AssetJobName { class AssetJobName {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetJobName._(this.value); const AssetJobName._(this.value);
-2
View File
@@ -17,10 +17,8 @@ class AssetJobsDto {
required this.name, required this.name,
}); });
/// Asset IDs
List<String> assetIds; List<String> assetIds;
/// Job name
AssetJobName name; AssetJobName name;
@override @override
-2
View File
@@ -17,10 +17,8 @@ class AssetMediaResponseDto {
required this.status, required this.status,
}); });
/// Asset media ID
String id; String id;
/// Upload status
AssetMediaStatus status; AssetMediaStatus status;
@override @override
+1 -1
View File
@@ -10,7 +10,7 @@
part of openapi.api; part of openapi.api;
/// Upload status
class AssetMediaStatus { class AssetMediaStatus {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetMediaStatus._(this.value); const AssetMediaStatus._(this.value);
@@ -16,7 +16,6 @@ class AssetMetadataBulkDeleteDto {
this.items = const [], this.items = const [],
}); });
/// Metadata items to delete
List<AssetMetadataBulkDeleteItemDto> items; List<AssetMetadataBulkDeleteItemDto> items;
@override @override
@@ -17,10 +17,8 @@ class AssetMetadataBulkDeleteItemDto {
required this.key, required this.key,
}); });
/// Asset ID
String assetId; String assetId;
/// Metadata key
String key; String key;
@override @override
@@ -19,16 +19,12 @@ class AssetMetadataBulkResponseDto {
required this.value, required this.value,
}); });
/// Asset ID
String assetId; String assetId;
/// Metadata key
String key; String key;
/// Last update date
DateTime updatedAt; DateTime updatedAt;
/// Metadata value (object)
Object value; Object value;
@override @override
@@ -16,7 +16,6 @@ class AssetMetadataBulkUpsertDto {
this.items = const [], this.items = const [],
}); });
/// Metadata items to upsert
List<AssetMetadataBulkUpsertItemDto> items; List<AssetMetadataBulkUpsertItemDto> items;
@override @override
@@ -18,13 +18,10 @@ class AssetMetadataBulkUpsertItemDto {
required this.value, required this.value,
}); });
/// Asset ID
String assetId; String assetId;
/// Metadata key
String key; String key;
/// Metadata value (object)
Object value; Object value;
@override @override
@@ -18,13 +18,10 @@ class AssetMetadataResponseDto {
required this.value, required this.value,
}); });
/// Metadata key
String key; String key;
/// Last update date
DateTime updatedAt; DateTime updatedAt;
/// Metadata value (object)
Object value; Object value;
@override @override
-1
View File
@@ -16,7 +16,6 @@ class AssetMetadataUpsertDto {
this.items = const [], this.items = const [],
}); });
/// Metadata items to upsert
List<AssetMetadataUpsertItemDto> items; List<AssetMetadataUpsertItemDto> items;
@override @override
@@ -17,10 +17,8 @@ class AssetMetadataUpsertItemDto {
required this.value, required this.value,
}); });
/// Metadata key
String key; String key;
/// Metadata value (object)
Object value; Object value;
@override @override
+1 -1
View File
@@ -10,7 +10,7 @@
part of openapi.api; part of openapi.api;
/// Asset sort order
class AssetOrder { class AssetOrder {
/// Instantiate a new enum with the provided [value]. /// Instantiate a new enum with the provided [value].
const AssetOrder._(this.value); const AssetOrder._(this.value);

Some files were not shown because too many files have changed in this diff Show More