Compare commits

..

3 Commits

Author SHA1 Message Date
timonrieger 182de9871a migrate mobile call sites 2026-05-18 17:17:56 +02:00
timonrieger 1ed8d32291 gen client 2026-05-18 17:17:56 +02:00
timonrieger a6d5e9a62c bump to v7.22.0 and update patching 2026-05-18 17:15:08 +02:00
397 changed files with 8283 additions and 5928 deletions
+1 -15
View File
@@ -897,7 +897,6 @@
"date_of_birth": "Date of birth",
"date_of_birth_saved": "Date of birth saved successfully",
"date_range": "Date range",
"date_time_original": "Date/Time Original",
"day": "Day",
"days": "Days",
"deduplicate_all": "Deduplicate All",
@@ -976,7 +975,6 @@
"downloading_asset_filename": "Downloading asset {filename}",
"downloading_from_icloud": "Downloading from iCloud",
"downloading_media": "Downloading media",
"drag_to_reorder": "Drag to reorder",
"drop_files_to_upload": "Drop files anywhere to upload",
"duplicates": "Duplicates",
"duplicates_description": "Resolve each group by indicating which, if any, are duplicates.",
@@ -1199,13 +1197,11 @@
"export_as_json": "Export as JSON",
"export_database": "Export Database",
"export_database_description": "Export the SQLite database",
"exposure_time": "Exposure Time",
"extension": "Extension",
"external": "External",
"external_libraries": "External Libraries",
"external_network": "External network",
"external_network_sheet_info": "When not on the preferred Wi-Fi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom",
"f_number": "F-Number",
"face_unassigned": "Unassigned",
"failed": "Failed",
"failed_count": "Failed: {count}",
@@ -1223,6 +1219,7 @@
"features_setting_description": "Manage the app features",
"file_name_or_extension": "File name or extension",
"file_name_text": "File name",
"file_name_with_value": "File name: {file_name}",
"file_size": "File size",
"filename": "Filename",
"filetype": "Filetype",
@@ -1235,7 +1232,6 @@
"find_them_fast": "Find them fast by name with search",
"first": "First",
"fix_incorrect_match": "Fix incorrect match",
"focal_length": "Focal Length",
"folder": "Folder",
"folder_not_found": "Folder not found",
"folders": "Folders",
@@ -1356,7 +1352,6 @@
"ios_debug_info_no_sync_yet": "No background sync job has run yet",
"ios_debug_info_processes_queued": "{count, plural, one {{count} background process queued} other {{count} background processes queued}}",
"ios_debug_info_processing_ran_at": "Processing ran {dateTime}",
"iso": "ISO",
"items_count": "{count, plural, one {# item} other {# items}}",
"jobs": "Jobs",
"json_editor": "JSON editor",
@@ -1589,7 +1584,6 @@
"mobile_app": "Mobile App",
"mobile_app_download_onboarding_note": "Download the companion mobile app using the following options",
"model": "Model",
"modify_date": "Modify Date",
"month": "Month",
"more": "More",
"motion": "Motion",
@@ -1712,7 +1706,6 @@
"organize_into_albums": "Organize into albums",
"organize_into_albums_description": "Put existing photos into albums using current sync settings",
"organize_your_library": "Organize your library",
"orientation": "Orientation",
"original": "original",
"other": "Other",
"other_devices": "Other devices",
@@ -1827,7 +1820,6 @@
"profile_drawer_readonly_mode": "Read-only mode enabled. Long-press the user avatar icon to exit.",
"profile_image_of_user": "Profile image of {user}",
"profile_picture_set": "Profile picture set.",
"projection_type": "Projection Type",
"public_album": "Public album",
"public_share": "Public Share",
"purchase_account_info": "Supporter",
@@ -2197,9 +2189,7 @@
"show_in_timeline": "Show in timeline",
"show_in_timeline_setting_description": "Show photos and videos from this user in your timeline",
"show_keyboard_shortcuts": "Show keyboard shortcuts",
"show_less": "Show less",
"show_metadata": "Show metadata",
"show_more_fields": "{count, plural, one {Show # more field} other {Show # more fields}}",
"show_or_hide_info": "Show or hide info",
"show_password": "Show password",
"show_person_options": "Show person options",
@@ -2255,7 +2245,6 @@
"step_delete_confirm": "Are you sure you want to delete this step?",
"step_details": "Step details",
"steps": "Steps",
"steps_count": "{count, plural, one {# step} other {# steps}}",
"stop_casting": "Stop casting",
"stop_motion_photo": "Stop Motion Photo",
"stop_photo_sharing": "Stop sharing your photos?",
@@ -2417,7 +2406,6 @@
"use_browser_locale_description": "Format dates, times, and numbers based on your browser locale",
"use_current_connection": "Use current connection",
"use_custom_date_range": "Use custom date range instead",
"use_template": "Use template",
"user": "User",
"user_has_been_deleted": "This user has been deleted.",
"user_id": "User ID",
@@ -2479,7 +2467,6 @@
"week": "Week",
"welcome": "Welcome",
"welcome_to_immich": "Welcome to Immich",
"when": "When",
"width": "Width",
"wifi_name": "Wi-Fi Name",
"workflow": "Workflow",
@@ -2492,7 +2479,6 @@
"workflow_name": "Workflow name",
"workflow_navigation_prompt": "Are you sure you want to leave without saving your changes?",
"workflow_summary": "Workflow summary",
"workflow_templates": "Workflow templates",
"workflow_update_success": "Workflow updated successfully",
"workflow_updated": "Workflow updated",
"workflows": "Workflows",
@@ -1,26 +0,0 @@
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
class AlbumConfig {
final AlbumSortMode sortMode;
final bool isReverse;
final bool isGrid;
const AlbumConfig({this.sortMode = AlbumSortMode.mostRecent, this.isReverse = true, this.isGrid = false});
AlbumConfig copyWith({AlbumSortMode? sortMode, bool? isReverse, bool? isGrid}) => AlbumConfig(
sortMode: sortMode ?? this.sortMode,
isReverse: isReverse ?? this.isReverse,
isGrid: isGrid ?? this.isGrid,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is AlbumConfig && other.sortMode == sortMode && other.isReverse == isReverse && other.isGrid == isGrid);
@override
int get hashCode => Object.hash(sortMode, isReverse, isGrid);
@override
String toString() => 'AlbumConfig(sortMode: $sortMode, isReverse: $isReverse, isGrid: $isGrid)';
}
@@ -1,11 +1,10 @@
import 'package:immich_mobile/domain/models/config/album_config.dart';
import 'package:immich_mobile/domain/models/config/cleanup_config.dart';
import 'package:immich_mobile/domain/models/config/image_config.dart';
import 'package:immich_mobile/domain/models/config/map_config.dart';
import 'package:immich_mobile/domain/models/config/slideshow_config.dart';
import 'package:immich_mobile/domain/models/config/theme_config.dart';
import 'package:immich_mobile/domain/models/config/timeline_config.dart';
import 'package:immich_mobile/domain/models/config/viewer_config.dart';
import 'package:immich_mobile/domain/models/config/slideshow_config.dart';
class AppConfig {
final ThemeConfig theme;
@@ -15,7 +14,6 @@ class AppConfig {
final ImageConfig image;
final ViewerConfig viewer;
final SlideshowConfig slideshow;
final AlbumConfig album;
const AppConfig({
this.theme = const .new(),
@@ -25,7 +23,6 @@ class AppConfig {
this.image = const .new(),
this.viewer = const .new(),
this.slideshow = const .new(),
this.album = const .new(),
});
AppConfig copyWith({
@@ -36,7 +33,6 @@ class AppConfig {
ImageConfig? image,
ViewerConfig? viewer,
SlideshowConfig? slideshow,
AlbumConfig? album,
}) => .new(
theme: theme ?? this.theme,
cleanup: cleanup ?? this.cleanup,
@@ -45,7 +41,6 @@ class AppConfig {
image: image ?? this.image,
viewer: viewer ?? this.viewer,
slideshow: slideshow ?? this.slideshow,
album: album ?? this.album,
);
@override
@@ -58,13 +53,12 @@ class AppConfig {
other.timeline == timeline &&
other.image == image &&
other.viewer == viewer &&
other.slideshow == slideshow &&
other.album == album);
other.slideshow == slideshow);
@override
int get hashCode => Object.hash(theme, cleanup, map, timeline, image, viewer, slideshow, album);
int get hashCode => Object.hash(theme, cleanup, map, timeline, image, viewer, slideshow);
@override
String toString() =>
'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer, slideshow: $slideshow, album: $album)';
'AppConfig(theme: $theme, cleanup: $cleanup, map: $map, timeline: $timeline, image: $image, viewer: $viewer, slideshow: $slideshow)';
}
@@ -1,54 +0,0 @@
import 'package:flutter/foundation.dart';
class NetworkConfig {
final bool autoEndpointSwitching;
final String? preferredWifiName;
final String? localEndpoint;
final List<String> externalEndpointList;
final Map<String, String> customHeaders;
const NetworkConfig({
this.autoEndpointSwitching = false,
this.preferredWifiName,
this.localEndpoint,
this.externalEndpointList = const [],
this.customHeaders = const {},
});
NetworkConfig copyWith({
bool? autoEndpointSwitching,
String? preferredWifiName,
String? localEndpoint,
List<String>? externalEndpointList,
Map<String, String>? customHeaders,
}) => NetworkConfig(
autoEndpointSwitching: autoEndpointSwitching ?? this.autoEndpointSwitching,
preferredWifiName: preferredWifiName ?? this.preferredWifiName,
localEndpoint: localEndpoint ?? this.localEndpoint,
externalEndpointList: externalEndpointList ?? this.externalEndpointList,
customHeaders: customHeaders ?? this.customHeaders,
);
@override
bool operator ==(Object other) =>
identical(this, other) ||
(other is NetworkConfig &&
other.autoEndpointSwitching == autoEndpointSwitching &&
other.preferredWifiName == preferredWifiName &&
other.localEndpoint == localEndpoint &&
listEquals(other.externalEndpointList, externalEndpointList) &&
mapEquals(other.customHeaders, customHeaders));
@override
int get hashCode => Object.hash(
autoEndpointSwitching,
preferredWifiName,
localEndpoint,
Object.hashAll(externalEndpointList),
Object.hashAllUnordered(customHeaders.entries.map((e) => Object.hash(e.key, e.value))),
);
@override
String toString() =>
'NetworkConfig(autoEndpointSwitching: $autoEndpointSwitching, preferredWifiName: $preferredWifiName, localEndpoint: $localEndpoint, externalEndpointList: $externalEndpointList, customHeaders: $customHeaders)';
}
@@ -1,22 +1,18 @@
import 'package:immich_mobile/domain/models/config/network_config.dart';
import 'package:immich_mobile/domain/models/log.model.dart';
class SystemConfig {
final LogLevel logLevel;
final NetworkConfig network;
const SystemConfig({this.logLevel = .info, this.network = const .new()});
const SystemConfig({this.logLevel = .info});
SystemConfig copyWith({LogLevel? logLevel, NetworkConfig? network}) =>
SystemConfig(logLevel: logLevel ?? this.logLevel, network: network ?? this.network);
SystemConfig copyWith({LogLevel? logLevel}) => SystemConfig(logLevel: logLevel ?? this.logLevel);
@override
bool operator ==(Object other) =>
identical(this, other) || (other is SystemConfig && other.logLevel == logLevel && other.network == network);
bool operator ==(Object other) => identical(this, other) || (other is SystemConfig && other.logLevel == logLevel);
@override
int get hashCode => Object.hash(logLevel, network);
int get hashCode => logLevel.hashCode;
@override
String toString() => 'SystemConfig(logLevel: $logLevel, network: $network)';
String toString() => 'SystemConfig(logLevel: $logLevel)';
}
@@ -8,7 +8,6 @@ import 'package:immich_mobile/domain/models/config/app_config.dart';
import 'package:immich_mobile/domain/models/config/system_config.dart';
import 'package:immich_mobile/domain/models/log.model.dart';
import 'package:immich_mobile/domain/models/timeline.model.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
enum MetadataDomain<T extends Object> {
appConfig<AppConfig>('config.app'),
@@ -35,33 +34,6 @@ enum MetadataKey<T extends Object> {
viewerAutoPlayVideo<bool>(.appConfig, 'viewer.autoPlayVideo', true),
viewerTapToNavigate<bool>(.appConfig, 'viewer.tapToNavigate', false),
// Network
networkAutoEndpointSwitching<bool>(.systemConfig, 'network.autoEndpointSwitching', false),
networkPreferredWifiName<String>(.systemConfig, 'network.preferredWifiName', ''),
networkLocalEndpoint<String>(.systemConfig, 'network.localEndpoint', ''),
networkExternalEndpointList<List<String>>(
.systemConfig,
'network.externalEndpointList',
[],
_ListCodec(_PrimitiveCodec.string),
),
networkCustomHeaders<Map<String, String>>(
.systemConfig,
'network.customHeaders',
{},
_MapCodec(_PrimitiveCodec.string, _PrimitiveCodec.string),
),
// Album
albumSortMode<AlbumSortMode>(
.appConfig,
'album.sortMode',
AlbumSortMode.mostRecent,
_EnumCodec(AlbumSortMode.values),
),
albumIsReverse<bool>(.appConfig, 'album.isReverse', true),
albumIsGrid<bool>(.appConfig, 'album.isGrid', false),
// Timeline
timelineTilesPerRow<int>(.appConfig, 'timeline.tilesPerRow', 4),
timelineGroupAssetsBy<GroupAssetsBy>(
@@ -171,47 +143,6 @@ final class _DateTimeCodec extends _MetadataCodec<DateTime> {
DateTime? decode(String raw) => DateTime.tryParse(raw);
}
final class _MapCodec<K extends Object, V extends Object> extends _MetadataCodec<Map<K, V>> {
final _MetadataCodec<K> _keyCodec;
final _MetadataCodec<V> _valueCodec;
const _MapCodec(this._keyCodec, this._valueCodec);
@override
String encode(Map<K, V> value) {
final entries = <String, String>{};
value.forEach((k, v) => entries[_keyCodec.encode(k)] = _valueCodec.encode(v));
return jsonEncode(entries);
}
@override
Map<K, V>? decode(String raw) {
try {
final decoded = jsonDecode(raw);
if (decoded is! Map) {
return null;
}
final result = <K, V>{};
for (final entry in decoded.entries) {
final rawKey = entry.key;
final rawValue = entry.value;
if (rawKey is! String || rawValue is! String) {
return null;
}
final k = _keyCodec.decode(rawKey);
final v = _valueCodec.decode(rawValue);
if (k == null || v == null) {
return null;
}
result[k] = v;
}
return result;
} on FormatException {
return null;
}
}
}
final class _ListCodec<T extends Object> extends _MetadataCodec<List<T>> {
final _MetadataCodec<T> _elementCodec;
+13 -8
View File
@@ -11,13 +11,26 @@ enum StoreKey<T> {
serverUrl<String>._(10),
accessToken<String>._(11),
serverEndpoint<String>._(12),
selectedAlbumSortOrder<int>._(113),
advancedTroubleshooting<bool>._(114),
selectedAlbumSortReverse<bool>._(123),
enableHapticFeedback<bool>._(126),
customHeaders<String>._(127),
syncAlbums<bool>._(131),
// Auto endpoint switching
autoEndpointSwitching<bool>._(132),
preferredWifiName<String>._(133),
localEndpoint<String>._(134),
externalEndpointList<String>._(135),
manageLocalMediaAndroid<bool>._(137),
// Read-only Mode settings
readonlyModeEnabled<bool>._(138),
albumGridView<bool>._(140),
// Image viewer navigation settings
tapToNavigate<bool>._(141),
// Experimental stuff
enableBackup<bool>._(1003),
@@ -26,14 +39,6 @@ enum StoreKey<T> {
syncMigrationStatus<String>._(1013),
// Legacy keys that have been migrated to the new metadata store
legacySelectedAlbumSortOrder<int>._(113),
legacySelectedAlbumSortReverse<bool>._(123),
legacyAlbumGridView<bool>._(140),
legacyAutoEndpointSwitching<bool>._(132),
legacyPreferredWifiName<String>._(133),
legacyLocalEndpoint<String>._(134),
legacyExternalEndpointList<String>._(135),
legacyCustomHeaders<String>._(127),
legacyLoopVideo<bool>._(117),
legacyLoadOriginalVideo<bool>._(136),
legacyAutoPlayVideo<bool>._(139),
+5 -5
View File
@@ -18,11 +18,11 @@ extension DTOToAsset on api.AssetResponseDto {
height: height?.toInt(),
width: width?.toInt(),
isFavorite: isFavorite,
livePhotoVideoId: livePhotoVideoId,
livePhotoVideoId: livePhotoVideoId.orElse(null),
thumbHash: thumbhash,
localId: null,
type: type.toAssetType(),
stackId: stack?.id,
stackId: stack.orElse(null)?.id,
isEdited: isEdited,
);
}
@@ -41,13 +41,13 @@ extension DTOToAsset on api.AssetResponseDto {
height: height?.toInt(),
width: width?.toInt(),
isFavorite: isFavorite,
livePhotoVideoId: livePhotoVideoId,
livePhotoVideoId: livePhotoVideoId.orElse(null),
thumbHash: thumbhash,
localId: null,
type: type.toAssetType(),
stackId: stack?.id,
stackId: stack.orElse(null)?.id,
isEdited: isEdited,
exifInfo: exifInfo != null ? ExifDtoConverter.fromDto(exifInfo!) : const ExifInfo(),
exifInfo: exifInfo.orElse(null) != null ? ExifDtoConverter.fromDto(exifInfo.orElse(null)!) : const ExifInfo(),
);
}
}
@@ -4,8 +4,6 @@ extension StringExtension on String {
String capitalize() {
return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" ");
}
String? get nullIfEmpty => isEmpty ? null : this;
}
extension DurationExtension on String {
@@ -2,7 +2,6 @@ import 'package:drift/drift.dart';
import 'package:immich_mobile/domain/models/config/app_config.dart';
import 'package:immich_mobile/domain/models/config/system_config.dart';
import 'package:immich_mobile/domain/models/metadata_key.dart';
import 'package:immich_mobile/extensions/string_extensions.dart';
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
@@ -147,23 +146,9 @@ extension<T extends Object> on MetadataDomain<T> {
look: repo._read(.slideshowLook),
direction: repo._read(.slideshowDirection),
),
album: .new(
sortMode: repo._read(.albumSortMode),
isReverse: repo._read(.albumIsReverse),
isGrid: repo._read(.albumIsGrid),
),
);
case .systemConfig:
repo._systemConfig = .new(
logLevel: repo._read(.logLevel),
network: .new(
autoEndpointSwitching: repo._read(.networkAutoEndpointSwitching),
preferredWifiName: repo._read(.networkPreferredWifiName).nullIfEmpty,
localEndpoint: repo._read(.networkLocalEndpoint).nullIfEmpty,
externalEndpointList: repo._read(.networkExternalEndpointList),
customHeaders: repo._read(.networkCustomHeaders),
),
);
repo._systemConfig = .new(logLevel: repo._read(.logLevel));
}
}
}
@@ -20,50 +20,64 @@ class SearchApiRepository extends ApiRepository {
(filter.assetId != null && filter.assetId!.isNotEmpty)) {
return _api.searchSmart(
SmartSearchDto(
query: filter.context,
queryAssetId: filter.assetId,
language: filter.language,
country: filter.location.country,
state: filter.location.state,
city: filter.location.city,
make: filter.camera.make,
model: filter.camera.model,
takenAfter: filter.date.takenAfter,
takenBefore: filter.date.takenBefore,
visibility: filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline,
rating: filter.rating.rating,
isFavorite: filter.display.isFavorite ? true : null,
isNotInAlbum: filter.display.isNotInAlbum ? true : null,
personIds: filter.people.map((e) => e.id).toList(),
tagIds: filter.tagIds,
type: type,
page: page,
size: 100,
query: filter.context == null ? const Optional.absent() : Optional.present(filter.context!),
queryAssetId: filter.assetId == null ? const Optional.absent() : Optional.present(filter.assetId!),
language: filter.language == null ? const Optional.absent() : Optional.present(filter.language!),
country: filter.location.country == null
? const Optional.absent()
: Optional.present(filter.location.country!),
state: filter.location.state == null ? const Optional.absent() : Optional.present(filter.location.state!),
city: filter.location.city == null ? const Optional.absent() : Optional.present(filter.location.city!),
make: filter.camera.make == null ? const Optional.absent() : Optional.present(filter.camera.make!),
model: filter.camera.model == null ? const Optional.absent() : Optional.present(filter.camera.model!),
takenAfter: filter.date.takenAfter == null
? const Optional.absent()
: Optional.present(filter.date.takenAfter!),
takenBefore: filter.date.takenBefore == null
? const Optional.absent()
: Optional.present(filter.date.takenBefore!),
visibility: Optional.present(filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline),
rating: filter.rating.rating == null ? const Optional.absent() : Optional.present(filter.rating.rating!),
isFavorite: filter.display.isFavorite ? const Optional.present(true) : const Optional.absent(),
isNotInAlbum: filter.display.isNotInAlbum ? const Optional.present(true) : const Optional.absent(),
personIds: Optional.present(filter.people.map((e) => e.id).toList()),
tagIds: filter.tagIds == null ? const Optional.absent() : Optional.present(filter.tagIds!),
type: type == null ? const Optional.absent() : Optional.present(type),
page: Optional.present(page),
size: const Optional.present(100),
),
);
}
return _api.searchAssets(
MetadataSearchDto(
originalFileName: filter.filename != null && filter.filename!.isNotEmpty ? filter.filename : null,
country: filter.location.country,
description: filter.description != null && filter.description!.isNotEmpty ? filter.description : null,
ocr: filter.ocr != null && filter.ocr!.isNotEmpty ? filter.ocr : null,
state: filter.location.state,
city: filter.location.city,
make: filter.camera.make,
model: filter.camera.model,
takenAfter: filter.date.takenAfter,
takenBefore: filter.date.takenBefore,
visibility: filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline,
rating: filter.rating.rating,
isFavorite: filter.display.isFavorite ? true : null,
isNotInAlbum: filter.display.isNotInAlbum ? true : null,
personIds: filter.people.map((e) => e.id).toList(),
tagIds: filter.tagIds,
type: type,
page: page,
size: 1000,
originalFileName: filter.filename != null && filter.filename!.isNotEmpty
? Optional.present(filter.filename!)
: const Optional.absent(),
country: filter.location.country == null ? const Optional.absent() : Optional.present(filter.location.country!),
description: filter.description != null && filter.description!.isNotEmpty
? Optional.present(filter.description!)
: const Optional.absent(),
ocr: filter.ocr != null && filter.ocr!.isNotEmpty ? Optional.present(filter.ocr!) : const Optional.absent(),
state: filter.location.state == null ? const Optional.absent() : Optional.present(filter.location.state!),
city: filter.location.city == null ? const Optional.absent() : Optional.present(filter.location.city!),
make: filter.camera.make == null ? const Optional.absent() : Optional.present(filter.camera.make!),
model: filter.camera.model == null ? const Optional.absent() : Optional.present(filter.camera.model!),
takenAfter: filter.date.takenAfter == null
? const Optional.absent()
: Optional.present(filter.date.takenAfter!),
takenBefore: filter.date.takenBefore == null
? const Optional.absent()
: Optional.present(filter.date.takenBefore!),
visibility: Optional.present(filter.display.isArchive ? AssetVisibility.archive : AssetVisibility.timeline),
rating: filter.rating.rating == null ? const Optional.absent() : Optional.present(filter.rating.rating!),
isFavorite: filter.display.isFavorite ? const Optional.present(true) : const Optional.absent(),
isNotInAlbum: filter.display.isNotInAlbum ? const Optional.present(true) : const Optional.absent(),
personIds: Optional.present(filter.people.map((e) => e.id).toList()),
tagIds: filter.tagIds == null ? const Optional.absent() : Optional.present(filter.tagIds!),
type: type == null ? const Optional.absent() : Optional.present(type),
page: Optional.present(page),
size: const Optional.present(1000),
),
);
}
@@ -20,7 +20,7 @@ class SyncApiRepository {
}
Future<void> deleteSyncAck(List<SyncEntityType> types) {
return _api.syncApi.deleteSyncAck(SyncAckDeleteDto(types: types));
return _api.syncApi.deleteSyncAck(SyncAckDeleteDto(types: Optional.present(types)));
}
Future<void> streamChanges(
@@ -91,7 +91,7 @@ class SyncStreamRepository extends DriftDatabaseRepository {
email: Value(user.email),
hasProfileImage: Value(user.hasProfileImage),
profileChangedAt: Value(user.profileChangedAt),
avatarColor: Value(user.avatarColor?.toAvatarColor() ?? AvatarColor.primary),
avatarColor: Value(user.avatarColor.orElse(null)?.toAvatarColor() ?? AvatarColor.primary),
isAdmin: Value(user.isAdmin),
pinCode: Value(user.pinCode),
quotaSizeInBytes: Value(user.quotaSizeInBytes ?? 0),
@@ -133,7 +133,7 @@ class SyncStreamRepository extends DriftDatabaseRepository {
email: Value(user.email),
hasProfileImage: Value(user.hasProfileImage),
profileChangedAt: Value(user.profileChangedAt),
avatarColor: Value(user.avatarColor?.toAvatarColor() ?? AvatarColor.primary),
avatarColor: Value(user.avatarColor.orElse(null)?.toAvatarColor() ?? AvatarColor.primary),
);
batch.insert(_db.userEntity, companion.copyWith(id: Value(user.id)), onConflict: DoUpdate((_) => companion));
@@ -5,24 +5,24 @@ import 'package:openapi/api.dart';
abstract final class ExifDtoConverter {
static ExifInfo fromDto(ExifResponseDto dto) {
return ExifInfo(
fileSize: dto.fileSizeInByte,
description: dto.description,
orientation: dto.orientation,
timeZone: dto.timeZone,
dateTimeOriginal: dto.dateTimeOriginal,
isFlipped: isOrientationFlipped(dto.orientation),
latitude: dto.latitude?.toDouble(),
longitude: dto.longitude?.toDouble(),
city: dto.city,
state: dto.state,
country: dto.country,
make: dto.make,
model: dto.model,
lens: dto.lensModel,
f: dto.fNumber?.toDouble(),
mm: dto.focalLength?.toDouble(),
iso: dto.iso?.toInt(),
exposureSeconds: exposureTimeToSeconds(dto.exposureTime),
fileSize: dto.fileSizeInByte.orElse(null),
description: dto.description.orElse(null),
orientation: dto.orientation.orElse(null),
timeZone: dto.timeZone.orElse(null),
dateTimeOriginal: dto.dateTimeOriginal.orElse(null),
isFlipped: isOrientationFlipped(dto.orientation.orElse(null)),
latitude: dto.latitude.orElse(null)?.toDouble(),
longitude: dto.longitude.orElse(null)?.toDouble(),
city: dto.city.orElse(null),
state: dto.state.orElse(null),
country: dto.country.orElse(null),
make: dto.make.orElse(null),
model: dto.model.orElse(null),
lens: dto.lensModel.orElse(null),
f: dto.fNumber.orElse(null)?.toDouble(),
mm: dto.focalLength.orElse(null)?.toDouble(),
iso: dto.iso.orElse(null)?.toInt(),
exposureSeconds: exposureTimeToSeconds(dto.exposureTime.orElse(null)),
);
}
@@ -40,7 +40,7 @@ abstract final class UserConverter {
updatedAt: DateTime.now(),
avatarColor: dto.avatarColor.toAvatarColor(),
memoryEnabled: false,
inTimeline: dto.inTimeline ?? false,
inTimeline: dto.inTimeline.orElse(null) ?? false,
isPartnerSharedBy: false,
isPartnerSharedWith: false,
profileChangedAt: dto.profileChangedAt,
@@ -73,10 +73,10 @@ class SharedLink {
slug = dto.slug,
type = dto.type == SharedLinkType.ALBUM ? SharedLinkSource.album : SharedLinkSource.individual,
title = dto.type == SharedLinkType.ALBUM
? dto.album?.albumName.toUpperCase() ?? "UNKNOWN SHARE"
? dto.album.orElse(null)?.albumName.toUpperCase() ?? "UNKNOWN SHARE"
: "INDIVIDUAL SHARE",
thumbAssetId = dto.type == SharedLinkType.ALBUM
? dto.album?.albumThumbnailAssetId
? dto.album.orElse(null)?.albumThumbnailAssetId
: dto.assets.isNotEmpty
? dto.assets[0].id
: null;
@@ -1,12 +1,14 @@
import 'dart:convert';
import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/metadata_key.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/generated/translations.g.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
class SettingsHeader {
String key = "";
@@ -22,14 +24,17 @@ class HeaderSettingsPage extends HookConsumerWidget {
final headers = useState<List<SettingsHeader>>([]);
final setInitialHeaders = useState(false);
final storedHeaders = ref.read(metadataProvider).systemConfig.network.customHeaders;
var headersStr = Store.get(StoreKey.customHeaders, "");
if (!setInitialHeaders.value) {
storedHeaders.forEach((k, v) {
final header = SettingsHeader();
header.key = k;
header.value = v;
headers.value.add(header);
});
if (headersStr.isNotEmpty) {
var customHeaders = jsonDecode(headersStr) as Map;
customHeaders.forEach((k, v) {
final header = SettingsHeader();
header.key = k;
header.value = v;
headers.value.add(header);
});
}
// add first one to help the user
if (headers.value.isEmpty) {
@@ -83,8 +88,8 @@ class HeaderSettingsPage extends HookConsumerWidget {
}
saveHeaders(WidgetRef ref, List<SettingsHeader> headers) async {
final headersMap = <String, String>{};
for (final header in headers) {
final headersMap = {};
for (var header in headers) {
final key = header.key.trim();
final value = header.value.trim();
@@ -94,7 +99,8 @@ class HeaderSettingsPage extends HookConsumerWidget {
headersMap[key] = value;
}
await ref.read(metadataProvider).write(MetadataKey.networkCustomHeaders, headersMap);
var encoded = jsonEncode(headersMap);
await Store.put(StoreKey.customHeaders, encoded);
await ref.read(apiServiceProvider).updateHeaders();
}
}
@@ -15,15 +15,15 @@ import 'package:immich_mobile/models/albums/album_search.model.dart';
import 'package:immich_mobile/presentation/widgets/album/album_tile.dart';
import 'package:immich_mobile/presentation/widgets/album/new_album_name_modal.widget.dart';
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
import 'package:immich_mobile/domain/models/metadata_key.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart';
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
import 'package:immich_mobile/providers/user.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/album_filter.utils.dart';
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
import 'package:immich_mobile/widgets/common/immich_toast.dart';
@@ -58,11 +58,19 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
final albumConfig = ref.read(metadataProvider).appConfig.album;
final appSettings = ref.read(appSettingsServiceProvider);
final savedSortMode = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortOrder);
final savedIsReverse = appSettings.getSetting(AppSettingsEnum.selectedAlbumSortReverse);
final savedIsGrid = appSettings.getSetting(AppSettingsEnum.albumGridView);
final albumSortMode = AlbumSortMode.values.firstWhere(
(e) => e.storeIndex == savedSortMode,
orElse: () => AlbumSortMode.lastModified,
);
setState(() {
sort = AlbumSort(mode: albumConfig.sortMode, isReverse: albumConfig.isReverse);
isGrid = albumConfig.isGrid;
sort = AlbumSort(mode: albumSortMode, isReverse: savedIsReverse);
isGrid = savedIsGrid;
});
ref.read(remoteAlbumProvider.notifier).refresh();
@@ -94,7 +102,7 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
setState(() {
isGrid = !isGrid;
});
ref.read(metadataProvider).write(MetadataKey.albumIsGrid, isGrid);
ref.read(appSettingsServiceProvider).setSetting(AppSettingsEnum.albumGridView, isGrid);
}
void changeFilter(QuickFilterMode mode) {
@@ -110,9 +118,9 @@ class _AlbumSelectorState extends ConsumerState<AlbumSelector> {
this.sort = sort;
});
final metadata = ref.read(metadataProvider);
await metadata.write(MetadataKey.albumSortMode, sort.mode);
await metadata.write(MetadataKey.albumIsReverse, sort.isReverse);
final appSettings = ref.read(appSettingsServiceProvider);
await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortOrder, sort.mode.storeIndex);
await appSettings.setSetting(AppSettingsEnum.selectedAlbumSortReverse, sort.isReverse);
await sortAlbums();
}
+5 -10
View File
@@ -1,9 +1,6 @@
import 'dart:convert';
import 'package:flutter_udid/flutter_udid.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/constants.dart';
import 'package:immich_mobile/domain/models/metadata_key.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/domain/models/user.model.dart';
import 'package:immich_mobile/domain/services/user.service.dart';
@@ -11,7 +8,6 @@ import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/models/auth/auth_state.model.dart';
import 'package:immich_mobile/models/auth/login_response.model.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/auth.service.dart';
@@ -130,8 +126,7 @@ class AuthNotifier extends StateNotifier<AuthState> {
await _apiService.updateHeaders();
final serverEndpoint = Store.get(StoreKey.serverEndpoint);
final headerMap = _ref.read(metadataProvider).systemConfig.network.customHeaders;
final customHeaders = headerMap.isEmpty ? null : jsonEncode(headerMap);
final customHeaders = Store.tryGet(StoreKey.customHeaders);
await _widgetService.writeCredentials(serverEndpoint, accessToken, customHeaders);
// Get the deviceid from the store if it exists, otherwise generate a new one
@@ -179,19 +174,19 @@ class AuthNotifier extends StateNotifier<AuthState> {
}
Future<void> saveWifiName(String wifiName) async {
await _ref.read(metadataProvider).write(MetadataKey.networkPreferredWifiName, wifiName);
await Store.put(StoreKey.preferredWifiName, wifiName);
}
Future<void> saveLocalEndpoint(String url) async {
await _ref.read(metadataProvider).write(MetadataKey.networkLocalEndpoint, url);
await Store.put(StoreKey.localEndpoint, url);
}
String? getSavedWifiName() {
return _ref.read(metadataProvider).systemConfig.network.preferredWifiName;
return Store.tryGet(StoreKey.preferredWifiName);
}
String? getSavedLocalEndpoint() {
return _ref.read(metadataProvider).systemConfig.network.localEndpoint;
return Store.tryGet(StoreKey.localEndpoint);
}
/// Returns the current server endpoint (with /api) URL from the store
@@ -29,7 +29,7 @@ final getAllPlacesProvider = FutureProvider.autoDispose<List<SearchCuratedConten
}
final curatedContent = assetPlaces
.map((data) => SearchCuratedContent(label: data.exifInfo!.city!, id: data.id))
.map((data) => SearchCuratedContent(label: data.exifInfo.orElse(null)!.city.orElse(null)!, id: data.id))
.toList();
return curatedContent;
@@ -23,8 +23,8 @@ class ActivityApiRepository extends ApiRepository {
final dto = ActivityCreateDto(
albumId: albumId,
type: type == ActivityType.comment ? ReactionType.comment : ReactionType.like,
assetId: assetId,
comment: comment,
assetId: assetId == null ? const Optional.absent() : Optional.present(assetId),
comment: comment == null ? const Optional.absent() : Optional.present(comment),
);
final response = await checkNull(_api.createActivity(dto));
return _toActivity(response);
@@ -45,6 +45,6 @@ class ActivityApiRepository extends ApiRepository {
type: dto.type == ReactionType.comment ? ActivityType.comment : ActivityType.like,
user: UserConverter.fromSimpleUserDto(dto.user),
assetId: dto.assetId,
comment: dto.comment,
comment: dto.comment.orElse(null),
);
}
@@ -24,7 +24,7 @@ class AssetApiRepository extends ApiRepository {
AssetApiRepository(this._api, this._stacksApi, this._trashApi);
Future<void> delete(List<String> ids, bool force) async {
return _api.deleteAssets(AssetBulkDeleteDto(ids: ids, force: force));
return _api.deleteAssets(AssetBulkDeleteDto(ids: ids, force: Optional.present(force)));
}
Future<void> restoreTrash(List<String> ids) async {
@@ -42,19 +42,27 @@ class AssetApiRepository extends ApiRepository {
}
Future<void> updateVisibility(List<String> ids, AssetVisibilityEnum visibility) async {
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, visibility: _mapVisibility(visibility)));
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, visibility: Optional.present(_mapVisibility(visibility))));
}
Future<void> updateFavorite(List<String> ids, bool isFavorite) async {
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, isFavorite: isFavorite));
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, isFavorite: Optional.present(isFavorite)));
}
Future<void> updateLocation(List<String> ids, LatLng location) async {
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, latitude: location.latitude, longitude: location.longitude));
return _api.updateAssets(
AssetBulkUpdateDto(
ids: ids,
latitude: Optional.present(location.latitude),
longitude: Optional.present(location.longitude),
),
);
}
Future<void> updateDateTime(List<String> ids, DateTime dateTime) async {
return _api.updateAssets(AssetBulkUpdateDto(ids: ids, dateTimeOriginal: dateTime.toIso8601String()));
return _api.updateAssets(
AssetBulkUpdateDto(ids: ids, dateTimeOriginal: Optional.present(dateTime.toIso8601String())),
);
}
Future<StackResponse> stack(List<String> ids) async {
@@ -82,15 +90,15 @@ class AssetApiRepository extends ApiRepository {
final response = await checkNull(_api.getAssetInfo(assetId));
// we need to get the MIME of the thumbnail once that gets added to the API
return response.originalMimeType;
return response.originalMimeType.orElse(null);
}
Future<void> updateDescription(String assetId, String description) {
return _api.updateAsset(assetId, UpdateAssetDto(description: description));
return _api.updateAsset(assetId, UpdateAssetDto(description: Optional.present(description)));
}
Future<void> updateRating(String assetId, int rating) {
return _api.updateAsset(assetId, UpdateAssetDto(rating: rating));
return _api.updateAsset(assetId, UpdateAssetDto(rating: Optional.present(rating)));
}
Future<AssetEditsResponseDto?> editAsset(String assetId, List<AssetEdit> edits) {
+19 -13
View File
@@ -1,40 +1,46 @@
import 'dart:convert';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart';
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
final authRepositoryProvider = Provider<AuthRepository>(
(ref) => AuthRepository(ref.watch(driftProvider), ref.watch(metadataProvider)),
);
final authRepositoryProvider = Provider<AuthRepository>((ref) => AuthRepository(ref.watch(driftProvider)));
class AuthRepository {
final Drift _drift;
final MetadataRepository _metadata;
const AuthRepository(this._drift, this._metadata);
const AuthRepository(this._drift);
Future<void> clearLocalData() async {
await SyncStreamRepository(_drift).reset();
}
bool getEndpointSwitchingFeature() {
return _metadata.systemConfig.network.autoEndpointSwitching;
return Store.tryGet(StoreKey.autoEndpointSwitching) ?? false;
}
String? getPreferredWifiName() {
return _metadata.systemConfig.network.preferredWifiName;
return Store.tryGet(StoreKey.preferredWifiName);
}
String? getLocalEndpoint() {
return _metadata.systemConfig.network.localEndpoint;
return Store.tryGet(StoreKey.localEndpoint);
}
List<AuxilaryEndpoint> getExternalEndpointList() {
return _metadata.systemConfig.network.externalEndpointList
.map((url) => AuxilaryEndpoint(url: url, status: .valid))
.toList();
final jsonString = Store.tryGet(StoreKey.externalEndpointList);
if (jsonString == null) {
return [];
}
final List<dynamic> jsonList = jsonDecode(jsonString);
final endpointList = jsonList.map((e) => AuxilaryEndpoint.fromJson(e)).toList();
return endpointList;
}
}
@@ -13,7 +13,7 @@ class AuthApiRepository extends ApiRepository {
AuthApiRepository(this._apiService);
Future<void> changePassword(String newPassword) async {
await _apiService.usersApi.updateMyUser(UserUpdateMeDto(password: newPassword));
await _apiService.usersApi.updateMyUser(UserUpdateMeDto(password: Optional.present(newPassword)));
}
Future<LoginResponse> login(String email, String password) async {
@@ -46,7 +46,7 @@ class AuthApiRepository extends ApiRepository {
Future<bool> unlockPinCode(String pinCode) async {
try {
await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: pinCode));
await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: Optional.present(pinCode)));
return true;
} catch (_) {
return false;
@@ -22,7 +22,13 @@ class DriftAlbumApiRepository extends ApiRepository {
String? description,
}) async {
final responseDto = await checkNull(
_api.createAlbum(CreateAlbumDto(albumName: name, description: description, assetIds: assetIds.toList())),
_api.createAlbum(
CreateAlbumDto(
albumName: name,
description: description == null ? const Optional.absent() : Optional.present(description),
assetIds: Optional.present(assetIds.toList()),
),
),
);
return responseDto.toRemoteAlbum(owner);
@@ -73,11 +79,13 @@ class DriftAlbumApiRepository extends ApiRepository {
_api.updateAlbumInfo(
albumId,
UpdateAlbumDto(
albumName: name,
description: description,
albumThumbnailAssetId: thumbnailAssetId,
isActivityEnabled: isActivityEnabled,
order: apiOrder,
albumName: name == null ? const Optional.absent() : Optional.present(name),
description: description == null ? const Optional.absent() : Optional.present(description),
albumThumbnailAssetId: thumbnailAssetId == null
? const Optional.absent()
: Optional.present(thumbnailAssetId),
isActivityEnabled: isActivityEnabled == null ? const Optional.absent() : Optional.present(isActivityEnabled),
order: apiOrder == null ? const Optional.absent() : Optional.present(apiOrder),
),
),
);
@@ -99,7 +107,9 @@ class DriftAlbumApiRepository extends ApiRepository {
}
Future<bool> setActivityStatus(String albumId, bool isEnabled) async {
final response = await checkNull(_api.updateAlbumInfo(albumId, UpdateAlbumDto(isActivityEnabled: isEnabled)));
final response = await checkNull(
_api.updateAlbumInfo(albumId, UpdateAlbumDto(isActivityEnabled: Optional.present(isEnabled))),
);
return response.isActivityEnabled;
}
}
@@ -116,7 +126,7 @@ extension on AlbumResponseDto {
updatedAt: updatedAt,
thumbnailAssetId: albumThumbnailAssetId,
isActivityEnabled: isActivityEnabled,
order: order == AssetOrder.asc ? AlbumAssetOrder.asc : AlbumAssetOrder.desc,
order: order.orElse(null) == AssetOrder.asc ? AlbumAssetOrder.asc : AlbumAssetOrder.desc,
assetCount: assetCount,
isShared: albumUsers.length > 2,
);
@@ -16,7 +16,7 @@ class PartnerApiRepository extends ApiRepository {
Future<List<UserDto>> getAll(Direction direction) async {
final response = await checkNull(
_api.getPartners(direction == Direction.sharedByMe ? PartnerDirection.by : PartnerDirection.with_),
_api.getPartners(direction == Direction.sharedByMe ? PartnerDirection.sharedBy : PartnerDirection.sharedWith),
);
return response.map(UserConverter.fromPartnerDto).toList();
}
@@ -18,7 +18,10 @@ class PersonApiRepository extends ApiRepository {
Future<PersonDto> update(String id, {String? name, DateTime? birthday}) async {
final birthdayUtc = birthday == null ? null : DateTime.utc(birthday.year, birthday.month, birthday.day);
final dto = PersonUpdateDto(name: name, birthDate: birthdayUtc);
final dto = PersonUpdateDto(
name: name == null ? const Optional.absent() : Optional.present(name),
birthDate: birthdayUtc == null ? const Optional.absent() : Optional.present(birthdayUtc),
);
final response = await checkNull(_api.updatePerson(id, dto));
return _toPerson(response);
}
@@ -15,7 +15,13 @@ class SessionsAPIRepository extends ApiRepository {
Future<SessionCreateResponse> createSession(String deviceType, String deviceOS, {int? duration}) async {
final dto = await checkNull(
_api.createSession(SessionCreateDto(deviceType: deviceType, deviceOS: deviceOS, duration: duration)),
_api.createSession(
SessionCreateDto(
deviceType: Optional.present(deviceType),
deviceOS: Optional.present(deviceOS),
duration: duration == null ? const Optional.absent() : Optional.present(duration),
),
),
);
return SessionCreateResponse(
@@ -23,7 +29,7 @@ class SessionsAPIRepository extends ApiRepository {
current: dto.current,
deviceType: deviceType,
deviceOS: deviceOS,
expiresAt: dto.expiresAt,
expiresAt: dto.expiresAt.orElse(null),
createdAt: dto.createdAt,
updatedAt: dto.updatedAt,
token: dto.token,
+1 -1
View File
@@ -55,7 +55,7 @@ class LockedGuard extends AutoRouteGuard {
return;
}
await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: securePinCode));
await _apiService.authenticationApi.unlockAuthSession(SessionUnlockDto(pinCode: Optional.present(securePinCode)));
resolver.next(true);
} on PlatformException catch (error) {
+17 -8
View File
@@ -5,8 +5,8 @@ import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/infrastructure/repositories/metadata.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/network.repository.dart';
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
import 'package:immich_mobile/utils/debug_print.dart';
import 'package:immich_mobile/utils/url_helper.dart';
import 'package:logging/logging.dart';
@@ -177,21 +177,30 @@ class ApiService {
if (serverEndpoint != null && serverEndpoint.isNotEmpty) {
urls.add(serverEndpoint);
}
final network = MetadataRepository.instance.systemConfig.network;
final localEndpoint = network.localEndpoint;
if (localEndpoint != null) {
final localEndpoint = Store.tryGet(StoreKey.localEndpoint);
if (localEndpoint != null && localEndpoint.isNotEmpty) {
urls.add(localEndpoint);
}
for (final url in network.externalEndpointList) {
if (url.isNotEmpty) {
urls.add(url);
final externalJson = Store.tryGet(StoreKey.externalEndpointList);
if (externalJson != null) {
final List<dynamic> list = jsonDecode(externalJson);
for (final entry in list) {
final url = AuxilaryEndpoint.fromJson(entry).url;
if (url.isNotEmpty) {
urls.add(url);
}
}
}
return urls;
}
static Map<String, String> getRequestHeaders() {
return MetadataRepository.instance.systemConfig.network.customHeaders;
var customHeadersStr = Store.get(StoreKey.customHeaders, "");
if (customHeadersStr.isEmpty) {
return const {};
}
return (jsonDecode(customHeadersStr) as Map).cast<String, String>();
}
ApiClient get apiClient => _apiClient;
@@ -2,14 +2,18 @@ import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
enum AppSettingsEnum<T> {
selectedAlbumSortOrder<int>(StoreKey.selectedAlbumSortOrder, "selectedAlbumSortOrder", 2),
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, null, false),
manageLocalMediaAndroid<bool>(StoreKey.manageLocalMediaAndroid, null, false),
selectedAlbumSortReverse<bool>(StoreKey.selectedAlbumSortReverse, null, true),
enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true),
syncAlbums<bool>(StoreKey.syncAlbums, null, false),
autoEndpointSwitching<bool>(StoreKey.autoEndpointSwitching, null, false),
enableBackup<bool>(StoreKey.enableBackup, null, false),
useCellularForUploadVideos<bool>(StoreKey.useWifiForUploadVideos, null, false),
useCellularForUploadPhotos<bool>(StoreKey.useWifiForUploadPhotos, null, false),
readonlyModeEnabled<bool>(StoreKey.readonlyModeEnabled, "readonlyModeEnabled", false),
albumGridView<bool>(StoreKey.albumGridView, "albumGridView", false),
backupRequireCharging<bool>(StoreKey.backupRequireCharging, null, false),
backupTriggerDelay<int>(StoreKey.backupTriggerDelay, null, 30);
+4
View File
@@ -123,6 +123,10 @@ class AuthService {
_authRepository.clearLocalData(),
Store.delete(StoreKey.currentUser),
Store.delete(StoreKey.accessToken),
Store.delete(StoreKey.autoEndpointSwitching),
Store.delete(StoreKey.preferredWifiName),
Store.delete(StoreKey.localEndpoint),
Store.delete(StoreKey.externalEndpointList),
]);
}
+6 -2
View File
@@ -18,7 +18,11 @@ class OAuthService {
log.info("Starting OAuth flow with redirect URI: $redirectUri");
final dto = await _apiService.oAuthApi.startOAuth(
OAuthConfigDto(redirectUri: redirectUri, state: state, codeChallenge: codeChallenge),
OAuthConfigDto(
redirectUri: redirectUri,
state: Optional.present(state),
codeChallenge: Optional.present(codeChallenge),
),
);
final authUrl = dto?.url;
@@ -37,7 +41,7 @@ class OAuthService {
}
return await _apiService.oAuthApi.finishOAuth(
OAuthCallbackDto(url: result, state: state, codeVerifier: codeVerifier),
OAuthCallbackDto(url: result, state: Optional.present(state), codeVerifier: Optional.present(codeVerifier)),
);
}
}
+24 -24
View File
@@ -48,26 +48,26 @@ class SharedLinkService {
if (type == SharedLinkType.ALBUM) {
dto = SharedLinkCreateDto(
type: type,
albumId: albumId,
showMetadata: showMeta,
allowDownload: allowDownload,
allowUpload: allowUpload,
expiresAt: expiresAt,
description: description,
password: password,
slug: slug,
albumId: albumId == null ? const Optional.absent() : Optional.present(albumId),
showMetadata: Optional.present(showMeta),
allowDownload: Optional.present(allowDownload),
allowUpload: Optional.present(allowUpload),
expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt),
description: description == null ? const Optional.absent() : Optional.present(description),
password: password == null ? const Optional.absent() : Optional.present(password),
slug: slug == null ? const Optional.absent() : Optional.present(slug),
);
} else if (assetIds != null) {
dto = SharedLinkCreateDto(
type: type,
showMetadata: showMeta,
allowDownload: allowDownload,
allowUpload: allowUpload,
expiresAt: expiresAt,
description: description,
password: password,
slug: slug,
assetIds: assetIds,
showMetadata: Optional.present(showMeta),
allowDownload: Optional.present(allowDownload),
allowUpload: Optional.present(allowUpload),
expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt),
description: description == null ? const Optional.absent() : Optional.present(description),
password: password == null ? const Optional.absent() : Optional.present(password),
slug: slug == null ? const Optional.absent() : Optional.present(slug),
assetIds: Optional.present(assetIds),
);
}
@@ -98,14 +98,14 @@ class SharedLinkService {
final responseDto = await _apiService.sharedLinksApi.updateSharedLink(
id,
SharedLinkEditDto(
showMetadata: showMeta,
allowDownload: allowDownload,
allowUpload: allowUpload,
expiresAt: expiresAt,
description: description,
password: password,
slug: slug,
changeExpiryTime: changeExpiry,
showMetadata: showMeta == null ? const Optional.absent() : Optional.present(showMeta),
allowDownload: allowDownload == null ? const Optional.absent() : Optional.present(allowDownload),
allowUpload: allowUpload == null ? const Optional.absent() : Optional.present(allowUpload),
expiresAt: expiresAt == null ? const Optional.absent() : Optional.present(expiresAt),
description: description == null ? const Optional.absent() : Optional.present(description),
password: password == null ? const Optional.absent() : Optional.present(password),
slug: slug == null ? const Optional.absent() : Optional.present(slug),
changeExpiryTime: changeExpiry == null ? const Optional.absent() : Optional.present(changeExpiry),
),
);
if (responseDto != null) {
+12 -116
View File
@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'package:drift/drift.dart';
import 'package:flutter/material.dart';
@@ -13,8 +12,7 @@ import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart';
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
import 'package:immich_mobile/infrastructure/repositories/network.repository.dart';
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
import 'package:immich_mobile/services/api.service.dart';
const int targetVersion = 26;
@@ -39,35 +37,12 @@ Future<void> _migrateTo25() async {
return;
}
final urls = <String>[];
final serverEndpoint = Store.tryGet(StoreKey.serverEndpoint);
if (serverEndpoint != null && serverEndpoint.isNotEmpty) {
urls.add(serverEndpoint);
}
final localEndpoint = Store.tryGet(StoreKey.legacyLocalEndpoint);
if (localEndpoint != null && localEndpoint.isNotEmpty) {
urls.add(localEndpoint);
}
final externalJson = Store.tryGet(StoreKey.legacyExternalEndpointList);
if (externalJson != null) {
final List<dynamic> list = jsonDecode(externalJson);
for (final entry in list) {
final url = AuxilaryEndpoint.fromJson(entry).url;
if (url.isNotEmpty) {
urls.add(url);
}
}
}
if (urls.isEmpty) {
final serverUrls = ApiService.getServerUrls();
if (serverUrls.isEmpty) {
return;
}
final customHeadersStr = Store.get(StoreKey.legacyCustomHeaders, "");
final headers = customHeadersStr.isEmpty
? const <String, String>{}
: (jsonDecode(customHeadersStr) as Map).cast<String, String>();
await NetworkRepository.setHeaders(headers, urls, token: accessToken);
await NetworkRepository.setHeaders(ApiService.getRequestHeaders(), serverUrls, token: accessToken);
}
Future<void> _migrateTo26(Drift drift) async {
@@ -82,7 +57,14 @@ Future<void> _migrateTo26(Drift drift) async {
final cleanupKeepAlbumIds = await migrator.readLegacyStoreString(StoreKey.legacyCleanupKeepAlbumIds.id);
if (cleanupKeepAlbumIds != null) {
final ids = cleanupKeepAlbumIds.split(',').where((id) => id.isNotEmpty).toList();
migrator.stage(StoreKey.legacyCleanupKeepAlbumIds, MetadataKey.cleanupKeepAlbumIds, ids);
await drift.metadataEntity.insertOnConflictUpdate(
MetadataEntityCompanion.insert(
key: MetadataKey.cleanupKeepAlbumIds.key,
value: MetadataKey.cleanupKeepAlbumIds.encode(ids),
updatedAt: Value(DateTime.now()),
),
);
await migrator.deleteLegacyStoreRows([StoreKey.legacyCleanupKeepAlbumIds.id]);
}
await migrator.migrateBool(StoreKey.legacyCleanupKeepFavorites, MetadataKey.cleanupKeepFavorites);
await migrator.migrateEnumIndex(
@@ -114,80 +96,9 @@ Future<void> _migrateTo26(Drift drift) async {
await migrator.migrateBool(StoreKey.legacyLoadOriginalVideo, MetadataKey.viewerLoadOriginalVideo);
await migrator.migrateBool(StoreKey.legacyAutoPlayVideo, MetadataKey.viewerAutoPlayVideo);
await migrator.migrateBool(StoreKey.legacyTapToNavigate, MetadataKey.viewerTapToNavigate);
// Network
await migrator.migrateBool(StoreKey.legacyAutoEndpointSwitching, MetadataKey.networkAutoEndpointSwitching);
await migrator.migrateString(StoreKey.legacyPreferredWifiName, MetadataKey.networkPreferredWifiName);
await migrator.migrateString(StoreKey.legacyLocalEndpoint, MetadataKey.networkLocalEndpoint);
await _migrateExternalEndpointList(migrator);
await _migrateCustomHeaders(migrator);
// Album
await _migrateAlbumSortMode(migrator);
await migrator.migrateBool(StoreKey.legacySelectedAlbumSortReverse, MetadataKey.albumIsReverse);
await migrator.migrateBool(StoreKey.legacyAlbumGridView, MetadataKey.albumIsGrid);
await migrator.complete();
}
Future<void> _migrateAlbumSortMode(_StoreMigrator migrator) async {
final raw = await migrator.readLegacyStoreInt(StoreKey.legacySelectedAlbumSortOrder.id);
if (raw == null) {
return;
}
final mode = AlbumSortMode.values.firstWhere(
(e) => e.storeIndex == raw,
orElse: () => MetadataKey.albumSortMode.defaultValue,
);
migrator.stage(StoreKey.legacySelectedAlbumSortOrder, MetadataKey.albumSortMode, mode);
}
Future<void> _migrateExternalEndpointList(_StoreMigrator migrator) async {
final raw = await migrator.readLegacyStoreString(StoreKey.legacyExternalEndpointList.id);
if (raw == null) {
return;
}
final urls = <String>[];
try {
final decoded = jsonDecode(raw);
if (decoded is List) {
for (final entry in decoded) {
final url = AuxilaryEndpoint.fromJson(entry).url;
if (url.isNotEmpty) {
urls.add(url);
}
}
}
} on FormatException {
// ignore invalid entries
}
migrator.stage(StoreKey.legacyExternalEndpointList, MetadataKey.networkExternalEndpointList, urls);
}
Future<void> _migrateCustomHeaders(_StoreMigrator migrator) async {
final raw = await migrator.readLegacyStoreString(StoreKey.legacyCustomHeaders.id);
if (raw == null) {
return;
}
final headers = <String, String>{};
try {
final decoded = jsonDecode(raw);
if (decoded is Map) {
decoded.forEach((key, value) {
if (key is String && value is String) {
headers[key] = value;
}
});
}
} on FormatException {
// ignore invalid entries
}
migrator.stage(StoreKey.legacyCustomHeaders, MetadataKey.networkCustomHeaders, headers);
}
class _StoreMigrator {
final Drift _db;
final Map<MetadataKey<Object>, Object> _cache = {};
@@ -242,21 +153,6 @@ class _StoreMigrator {
_migratedStoreIds.add(legacyKey.id);
}
Future<void> migrateString(StoreKey<String> legacyKey, MetadataKey<String> newKey) async {
final value = await readLegacyStoreString(legacyKey.id);
if (value == null) {
return;
}
_cache[newKey] = value;
_migratedStoreIds.add(legacyKey.id);
}
void stage<T extends Object>(StoreKey legacyKey, MetadataKey<T> newKey, T value) {
_cache[newKey] = value;
_migratedStoreIds.add(legacyKey.id);
}
Future<void> complete() async {
await _db.batch((batch) {
for (final entry in _cache.entries) {
@@ -397,16 +397,16 @@ class LoginForm extends HookConsumerWidget {
mainAxisSize: MainAxisSize.max,
children: [
ImmichForm(
onSubmit: getServerAuthSettings,
submitText: 'next'.t(context: context),
submitIcon: Icons.arrow_forward_rounded,
builder: (_, form) => ImmichURLInput(
onSubmit: getServerAuthSettings,
child: ImmichURLInput(
controller: serverEndpointController,
label: 'login_form_endpoint_url'.t(context: context),
hintText: 'login_form_endpoint_hint'.t(context: context),
validator: _validateUrl,
keyboardAction: .next,
onSubmit: (_) => form.submit(),
onSubmit: (ctx, _) => ImmichForm.of(ctx).submit(),
),
),
ImmichTextButton(
@@ -434,10 +434,10 @@ class LoginForm extends HookConsumerWidget {
),
if (isPasswordLoginEnable.value)
ImmichForm(
onSubmit: login,
submitText: 'login'.t(context: context),
submitIcon: Icons.login_rounded,
builder: (context, form) => Column(
onSubmit: login,
child: Column(
spacing: ImmichSpacing.md,
children: [
ImmichTextInput(
@@ -448,7 +448,7 @@ class LoginForm extends HookConsumerWidget {
keyboardAction: TextInputAction.next,
keyboardType: TextInputType.emailAddress,
autofillHints: const [AutofillHints.email],
onSubmit: (_) => passwordFocusNode.requestFocus(),
onSubmit: (_, _) => passwordFocusNode.requestFocus(),
),
ImmichPasswordInput(
controller: passwordController,
@@ -456,17 +456,17 @@ class LoginForm extends HookConsumerWidget {
label: 'password'.t(context: context),
hintText: 'login_form_password_hint'.t(context: context),
keyboardAction: TextInputAction.go,
onSubmit: (_) => form.submit(),
onSubmit: (ctx, _) => ImmichForm.of(ctx).submit(),
),
],
),
),
if (isOauthEnable.value)
ImmichForm(
onSubmit: oAuthLogin,
submitText: oAuthButtonLabel.value,
submitIcon: Icons.pin_outlined,
builder: (context, _) => isPasswordLoginEnable.value
onSubmit: oAuthLogin,
child: isPasswordLoginEnable.value
? Padding(
padding: const EdgeInsets.only(left: 18.0, right: 18.0, top: 12.0),
child: Divider(color: context.isDarkTheme ? Colors.white : Colors.black, height: 5),
@@ -1,11 +1,13 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/domain/models/metadata_key.dart';
import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
import 'package:immich_mobile/widgets/settings/networking_settings/endpoint_input.dart';
class ExternalNetworkPreference extends HookConsumerWidget {
@@ -21,12 +23,11 @@ class ExternalNetworkPreference extends HookConsumerWidget {
saveEndpointList() {
canSave.value = entries.value.every((e) => e.status == AuxCheckStatus.valid);
final urls = entries.value
.where((e) => e.status == AuxCheckStatus.valid && e.url.isNotEmpty)
.map((e) => e.url)
.toList();
final endpointList = entries.value.where((url) => url.status == AuxCheckStatus.valid).toList();
ref.read(metadataProvider).write(MetadataKey.networkExternalEndpointList, urls);
final jsonString = jsonEncode(endpointList);
Store.put(StoreKey.externalEndpointList, jsonString);
}
updateValidationStatus(String url, int index, AuxCheckStatus status) {
@@ -68,13 +69,14 @@ class ExternalNetworkPreference extends HookConsumerWidget {
}
useEffect(() {
final urls = ref.read(metadataProvider).systemConfig.network.externalEndpointList;
final jsonString = Store.tryGet(StoreKey.externalEndpointList);
if (urls.isEmpty) {
if (jsonString == null) {
return null;
}
entries.value = urls.map((url) => AuxilaryEndpoint(url: url, status: .valid)).toList();
final List<dynamic> jsonList = jsonDecode(jsonString);
entries.value = jsonList.map((e) => AuxilaryEndpoint.fromJson(e)).toList();
return null;
}, const []);
@@ -1,12 +1,13 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_hooks/flutter_hooks.dart' hide Store;
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/translate_extensions.dart';
import 'package:immich_mobile/models/auth/auxilary_endpoint.model.dart';
import 'package:immich_mobile/providers/infrastructure/metadata.provider.dart';
import 'package:immich_mobile/providers/network.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
import 'package:immich_mobile/utils/url_helper.dart';
import 'package:immich_mobile/widgets/settings/networking_settings/external_network_preference.dart';
import 'package:immich_mobile/widgets/settings/networking_settings/local_network_preference.dart';
@@ -19,10 +20,7 @@ class NetworkingSettings extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final currentEndpoint = getServerUrl();
final featureEnabled = useState(ref.read(systemConfigProvider).network.autoEndpointSwitching);
useValueChanged<bool, void>(featureEnabled.value, (_, __) {
ref.read(metadataProvider).write(.networkAutoEndpointSwitching, featureEnabled.value);
});
final featureEnabled = useAppSettingsState(AppSettingsEnum.autoEndpointSwitching);
Future<void> checkWifiReadPermission() async {
final [hasLocationInUse, hasLocationAlways] = await Future.wait([
+1 -1
View File
@@ -1 +1 @@
7.8.0
7.22.0
+1 -4
View File
@@ -4,7 +4,7 @@ Immich API
This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: 3.0.0
- Generator version: 7.8.0
- Generator version: 7.22.0
- Build package: org.openapitools.codegen.languages.DartClientCodegen
## Requirements
@@ -205,7 +205,6 @@ Class | Method | HTTP request | Description
*PeopleApi* | [**updatePeople**](doc//PeopleApi.md#updatepeople) | **PUT** /people | Update people
*PeopleApi* | [**updatePerson**](doc//PeopleApi.md#updateperson) | **PUT** /people/{id} | Update person
*PluginsApi* | [**getPlugin**](doc//PluginsApi.md#getplugin) | **GET** /plugins/{id} | Retrieve a plugin
*PluginsApi* | [**getTemplates**](doc//PluginsApi.md#gettemplates) | **GET** /plugins/templates | Retrieve workflow templates
*PluginsApi* | [**searchPluginMethods**](doc//PluginsApi.md#searchpluginmethods) | **GET** /plugins/methods | Retrieve plugin methods
*PluginsApi* | [**searchPlugins**](doc//PluginsApi.md#searchplugins) | **GET** /plugins | List all plugins
*QueuesApi* | [**emptyQueue**](doc//QueuesApi.md#emptyqueue) | **DELETE** /queues/{name}/jobs | Empty a queue
@@ -492,8 +491,6 @@ Class | Method | HTTP request | Description
- [PlacesResponseDto](doc//PlacesResponseDto.md)
- [PluginMethodResponseDto](doc//PluginMethodResponseDto.md)
- [PluginResponseDto](doc//PluginResponseDto.md)
- [PluginTemplateResponseDto](doc//PluginTemplateResponseDto.md)
- [PluginTemplateStepResponseDto](doc//PluginTemplateStepResponseDto.md)
- [PurchaseResponse](doc//PurchaseResponse.md)
- [PurchaseUpdate](doc//PurchaseUpdate.md)
- [QueueCommand](doc//QueueCommand.md)
+1 -2
View File
@@ -29,6 +29,7 @@ part 'auth/api_key_auth.dart';
part 'auth/oauth.dart';
part 'auth/http_basic_auth.dart';
part 'auth/http_bearer_auth.dart';
part 'optional.dart';
part 'api/api_keys_api.dart';
part 'api/activities_api.dart';
@@ -237,8 +238,6 @@ part 'model/pin_code_setup_dto.dart';
part 'model/places_response_dto.dart';
part 'model/plugin_method_response_dto.dart';
part 'model/plugin_response_dto.dart';
part 'model/plugin_template_response_dto.dart';
part 'model/plugin_template_step_response_dto.dart';
part 'model/purchase_response.dart';
part 'model/purchase_update.dart';
part 'model/queue_command.dart';
-51
View File
@@ -73,57 +73,6 @@ class PluginsApi {
return null;
}
/// Retrieve workflow templates
///
/// Retrieve premade workflow templates provided by installed plugins
///
/// Note: This method returns the HTTP [Response].
Future<Response> getTemplatesWithHttpInfo() async {
// ignore: prefer_const_declarations
final apiPath = r'/plugins/templates';
// ignore: prefer_final_locals
Object? postBody;
final queryParams = <QueryParam>[];
final headerParams = <String, String>{};
final formParams = <String, String>{};
const contentTypes = <String>[];
return apiClient.invokeAPI(
apiPath,
'GET',
queryParams,
postBody,
headerParams,
formParams,
contentTypes.isEmpty ? null : contentTypes.first,
);
}
/// Retrieve workflow templates
///
/// Retrieve premade workflow templates provided by installed plugins
Future<List<PluginTemplateResponseDto>?> getTemplates() async {
final response = await getTemplatesWithHttpInfo();
if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response));
}
// When a remote server returns no body with a status of 204, we shall not decode it.
// At the time of writing this, `dart:convert` will throw an "Unexpected end of input"
// FormatException when trying to decode an empty string.
if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) {
final responseBody = await _decodeBodyBytes(response);
return (await apiClient.deserializeAsync(responseBody, 'List<PluginTemplateResponseDto>') as List)
.cast<PluginTemplateResponseDto>()
.toList(growable: false);
}
return null;
}
/// Retrieve plugin methods
///
/// Retrieve a list of plugin methods
+3 -7
View File
@@ -143,19 +143,19 @@ class ApiClient {
);
}
Future<dynamic> deserializeAsync(String value, String targetType, {bool growable = false,}) =>
Future<dynamic> deserializeAsync(String value, String targetType, {bool growable = false,}) async =>
// ignore: deprecated_member_use_from_same_package
deserialize(value, targetType, growable: growable);
@Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.')
Future<dynamic> deserialize(String value, String targetType, {bool growable = false,}) async {
dynamic deserialize(String value, String targetType, {bool growable = false,}) {
// Remove all spaces. Necessary for regular expressions as well.
targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments
// If the expected target type is String, nothing to do...
return targetType == 'String'
? value
: fromJson(await compute((String j) => json.decode(j), value), targetType, growable: growable);
: fromJson(json.decode(value), targetType, growable: growable);
}
// ignore: deprecated_member_use_from_same_package
@@ -520,10 +520,6 @@ class ApiClient {
return PluginMethodResponseDto.fromJson(value);
case 'PluginResponseDto':
return PluginResponseDto.fromJson(value);
case 'PluginTemplateResponseDto':
return PluginTemplateResponseDto.fromJson(value);
case 'PluginTemplateStepResponseDto':
return PluginTemplateStepResponseDto.fromJson(value);
case 'PurchaseResponse':
return PurchaseResponse.fromJson(value);
case 'PurchaseUpdate':
+3
View File
@@ -220,6 +220,9 @@ Future<String> _decodeBodyBytes(Response response) async {
/// Returns a valid [T] value found at the specified Map [key], null otherwise.
T? mapValueOfType<T>(dynamic map, String key) {
final dynamic value = map is Map ? map[key] : null;
if (T == double && value is int) {
return value.toDouble() as T;
}
return value is T ? value : null;
}
+23 -14
View File
@@ -14,8 +14,8 @@ class ActivityCreateDto {
/// Returns a new [ActivityCreateDto] instance.
ActivityCreateDto({
required this.albumId,
this.assetId,
this.comment,
this.assetId = const Optional.absent(),
this.comment = const Optional.absent(),
required this.type,
});
@@ -29,7 +29,7 @@ class ActivityCreateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? assetId;
Optional<String?> assetId;
/// Comment text (required if type is comment)
///
@@ -38,7 +38,7 @@ class ActivityCreateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? comment;
Optional<String?> comment;
ReactionType type;
@@ -63,15 +63,13 @@ class ActivityCreateDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'albumId'] = this.albumId;
if (this.assetId != null) {
json[r'assetId'] = this.assetId;
} else {
// json[r'assetId'] = null;
if (this.assetId.isPresent) {
final value = this.assetId.value;
json[r'assetId'] = value;
}
if (this.comment != null) {
json[r'comment'] = this.comment;
} else {
// json[r'comment'] = null;
if (this.comment.isPresent) {
final value = this.comment.value;
json[r'comment'] = value;
}
json[r'type'] = this.type;
return json;
@@ -85,10 +83,21 @@ class ActivityCreateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'albumId'), 'Required key "ActivityCreateDto[albumId]" is missing from JSON.');
assert(json[r'albumId'] != null, 'Required key "ActivityCreateDto[albumId]" has a null value in JSON.');
assert(json.containsKey(r'type'), 'Required key "ActivityCreateDto[type]" is missing from JSON.');
assert(json[r'type'] != null, 'Required key "ActivityCreateDto[type]" has a null value in JSON.');
return true;
}());
return ActivityCreateDto(
albumId: mapValueOfType<String>(json, r'albumId')!,
assetId: mapValueOfType<String>(json, r'assetId'),
comment: mapValueOfType<String>(json, r'comment'),
assetId: json.containsKey(r'assetId') ? Optional.present(mapValueOfType<String>(json, r'assetId')) : const Optional.absent(),
comment: json.containsKey(r'comment') ? Optional.present(mapValueOfType<String>(json, r'comment')) : const Optional.absent(),
type: ReactionType.fromJson(json[r'type'])!,
);
}
+23 -8
View File
@@ -14,7 +14,7 @@ class ActivityResponseDto {
/// Returns a new [ActivityResponseDto] instance.
ActivityResponseDto({
required this.assetId,
this.comment,
this.comment = const Optional.absent(),
required this.createdAt,
required this.id,
required this.type,
@@ -25,7 +25,7 @@ class ActivityResponseDto {
String? assetId;
/// Comment text (for comment activities)
String? comment;
Optional<String?> comment;
/// Creation date
DateTime createdAt;
@@ -64,12 +64,11 @@ class ActivityResponseDto {
if (this.assetId != null) {
json[r'assetId'] = this.assetId;
} else {
// json[r'assetId'] = null;
json[r'assetId'] = null;
}
if (this.comment != null) {
json[r'comment'] = this.comment;
} else {
// json[r'comment'] = null;
if (this.comment.isPresent) {
final value = this.comment.value;
json[r'comment'] = value;
}
json[r'createdAt'] = _isEpochMarker(r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/')
? this.createdAt.millisecondsSinceEpoch
@@ -88,9 +87,25 @@ class ActivityResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "ActivityResponseDto[assetId]" is missing from JSON.');
assert(json.containsKey(r'createdAt'), 'Required key "ActivityResponseDto[createdAt]" is missing from JSON.');
assert(json[r'createdAt'] != null, 'Required key "ActivityResponseDto[createdAt]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "ActivityResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "ActivityResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'type'), 'Required key "ActivityResponseDto[type]" is missing from JSON.');
assert(json[r'type'] != null, 'Required key "ActivityResponseDto[type]" has a null value in JSON.');
assert(json.containsKey(r'user'), 'Required key "ActivityResponseDto[user]" is missing from JSON.');
assert(json[r'user'] != null, 'Required key "ActivityResponseDto[user]" has a null value in JSON.');
return true;
}());
return ActivityResponseDto(
assetId: mapValueOfType<String>(json, r'assetId'),
comment: mapValueOfType<String>(json, r'comment'),
comment: json.containsKey(r'comment') ? Optional.present(mapValueOfType<String>(json, r'comment')) : const Optional.absent(),
createdAt: mapDateTime(json, r'createdAt', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/')!,
id: mapValueOfType<String>(json, r'id')!,
type: ReactionType.fromJson(json[r'type'])!,
@@ -58,6 +58,17 @@ class ActivityStatisticsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'comments'), 'Required key "ActivityStatisticsResponseDto[comments]" is missing from JSON.');
assert(json[r'comments'] != null, 'Required key "ActivityStatisticsResponseDto[comments]" has a null value in JSON.');
assert(json.containsKey(r'likes'), 'Required key "ActivityStatisticsResponseDto[likes]" is missing from JSON.');
assert(json[r'likes'] != null, 'Required key "ActivityStatisticsResponseDto[likes]" has a null value in JSON.');
return true;
}());
return ActivityStatisticsResponseDto(
comments: mapValueOfType<int>(json, r'comments')!,
likes: mapValueOfType<int>(json, r'likes')!,
+9
View File
@@ -45,6 +45,15 @@ class AddUsersDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'albumUsers'), 'Required key "AddUsersDto[albumUsers]" is missing from JSON.');
assert(json[r'albumUsers'] != null, 'Required key "AddUsersDto[albumUsers]" has a null value in JSON.');
return true;
}());
return AddUsersDto(
albumUsers: AlbumUserAddDto.listFromJson(json[r'albumUsers']),
);
@@ -45,6 +45,15 @@ class AdminOnboardingUpdateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'isOnboarded'), 'Required key "AdminOnboardingUpdateDto[isOnboarded]" is missing from JSON.');
assert(json[r'isOnboarded'] != null, 'Required key "AdminOnboardingUpdateDto[isOnboarded]" has a null value in JSON.');
return true;
}());
return AdminOnboardingUpdateDto(
isOnboarded: mapValueOfType<bool>(json, r'isOnboarded')!,
);
+60 -33
View File
@@ -17,17 +17,17 @@ class AlbumResponseDto {
required this.albumThumbnailAssetId,
this.albumUsers = const [],
required this.assetCount,
this.contributorCounts = const [],
this.contributorCounts = const Optional.present(const []),
required this.createdAt,
required this.description,
this.endDate,
this.endDate = const Optional.absent(),
required this.hasSharedLink,
required this.id,
required this.isActivityEnabled,
this.lastModifiedAssetTimestamp,
this.order,
this.lastModifiedAssetTimestamp = const Optional.absent(),
this.order = const Optional.absent(),
required this.shared,
this.startDate,
this.startDate = const Optional.absent(),
required this.updatedAt,
});
@@ -46,7 +46,7 @@ class AlbumResponseDto {
/// Maximum value: 9007199254740991
int assetCount;
List<ContributorCountResponseDto> contributorCounts;
Optional<List<ContributorCountResponseDto>?> contributorCounts;
/// Creation date
DateTime createdAt;
@@ -61,7 +61,7 @@ class AlbumResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
DateTime? endDate;
Optional<DateTime?> endDate;
/// Has shared link
bool hasSharedLink;
@@ -79,7 +79,7 @@ class AlbumResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
DateTime? lastModifiedAssetTimestamp;
Optional<DateTime?> lastModifiedAssetTimestamp;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -87,7 +87,7 @@ class AlbumResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AssetOrder? order;
Optional<AssetOrder?> order;
/// Is shared album
bool shared;
@@ -99,7 +99,7 @@ class AlbumResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
DateTime? startDate;
Optional<DateTime?> startDate;
/// Last update date
DateTime updatedAt;
@@ -152,36 +152,35 @@ class AlbumResponseDto {
if (this.albumThumbnailAssetId != null) {
json[r'albumThumbnailAssetId'] = this.albumThumbnailAssetId;
} else {
// json[r'albumThumbnailAssetId'] = null;
json[r'albumThumbnailAssetId'] = null;
}
json[r'albumUsers'] = this.albumUsers;
json[r'assetCount'] = this.assetCount;
json[r'contributorCounts'] = this.contributorCounts;
if (this.contributorCounts.isPresent) {
final value = this.contributorCounts.value;
json[r'contributorCounts'] = value;
}
json[r'createdAt'] = this.createdAt.toUtc().toIso8601String();
json[r'description'] = this.description;
if (this.endDate != null) {
json[r'endDate'] = this.endDate!.toUtc().toIso8601String();
} else {
// json[r'endDate'] = null;
if (this.endDate.isPresent) {
final value = this.endDate.value;
json[r'endDate'] = value == null ? null : value.toUtc().toIso8601String();
}
json[r'hasSharedLink'] = this.hasSharedLink;
json[r'id'] = this.id;
json[r'isActivityEnabled'] = this.isActivityEnabled;
if (this.lastModifiedAssetTimestamp != null) {
json[r'lastModifiedAssetTimestamp'] = this.lastModifiedAssetTimestamp!.toUtc().toIso8601String();
} else {
// json[r'lastModifiedAssetTimestamp'] = null;
if (this.lastModifiedAssetTimestamp.isPresent) {
final value = this.lastModifiedAssetTimestamp.value;
json[r'lastModifiedAssetTimestamp'] = value == null ? null : value.toUtc().toIso8601String();
}
if (this.order != null) {
json[r'order'] = this.order;
} else {
// json[r'order'] = null;
if (this.order.isPresent) {
final value = this.order.value;
json[r'order'] = value;
}
json[r'shared'] = this.shared;
if (this.startDate != null) {
json[r'startDate'] = this.startDate!.toUtc().toIso8601String();
} else {
// json[r'startDate'] = null;
if (this.startDate.isPresent) {
final value = this.startDate.value;
json[r'startDate'] = value == null ? null : value.toUtc().toIso8601String();
}
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
return json;
@@ -195,22 +194,50 @@ class AlbumResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'albumName'), 'Required key "AlbumResponseDto[albumName]" is missing from JSON.');
assert(json[r'albumName'] != null, 'Required key "AlbumResponseDto[albumName]" has a null value in JSON.');
assert(json.containsKey(r'albumThumbnailAssetId'), 'Required key "AlbumResponseDto[albumThumbnailAssetId]" is missing from JSON.');
assert(json.containsKey(r'albumUsers'), 'Required key "AlbumResponseDto[albumUsers]" is missing from JSON.');
assert(json[r'albumUsers'] != null, 'Required key "AlbumResponseDto[albumUsers]" has a null value in JSON.');
assert(json.containsKey(r'assetCount'), 'Required key "AlbumResponseDto[assetCount]" is missing from JSON.');
assert(json[r'assetCount'] != null, 'Required key "AlbumResponseDto[assetCount]" has a null value in JSON.');
assert(json.containsKey(r'createdAt'), 'Required key "AlbumResponseDto[createdAt]" is missing from JSON.');
assert(json[r'createdAt'] != null, 'Required key "AlbumResponseDto[createdAt]" has a null value in JSON.');
assert(json.containsKey(r'description'), 'Required key "AlbumResponseDto[description]" is missing from JSON.');
assert(json[r'description'] != null, 'Required key "AlbumResponseDto[description]" has a null value in JSON.');
assert(json.containsKey(r'hasSharedLink'), 'Required key "AlbumResponseDto[hasSharedLink]" is missing from JSON.');
assert(json[r'hasSharedLink'] != null, 'Required key "AlbumResponseDto[hasSharedLink]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AlbumResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AlbumResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'isActivityEnabled'), 'Required key "AlbumResponseDto[isActivityEnabled]" is missing from JSON.');
assert(json[r'isActivityEnabled'] != null, 'Required key "AlbumResponseDto[isActivityEnabled]" has a null value in JSON.');
assert(json.containsKey(r'shared'), 'Required key "AlbumResponseDto[shared]" is missing from JSON.');
assert(json[r'shared'] != null, 'Required key "AlbumResponseDto[shared]" has a null value in JSON.');
assert(json.containsKey(r'updatedAt'), 'Required key "AlbumResponseDto[updatedAt]" is missing from JSON.');
assert(json[r'updatedAt'] != null, 'Required key "AlbumResponseDto[updatedAt]" has a null value in JSON.');
return true;
}());
return AlbumResponseDto(
albumName: mapValueOfType<String>(json, r'albumName')!,
albumThumbnailAssetId: mapValueOfType<String>(json, r'albumThumbnailAssetId'),
albumUsers: AlbumUserResponseDto.listFromJson(json[r'albumUsers']),
assetCount: mapValueOfType<int>(json, r'assetCount')!,
contributorCounts: ContributorCountResponseDto.listFromJson(json[r'contributorCounts']),
contributorCounts: json.containsKey(r'contributorCounts') ? Optional.present(ContributorCountResponseDto.listFromJson(json[r'contributorCounts'])) : const Optional.absent(),
createdAt: mapDateTime(json, r'createdAt', r'')!,
description: mapValueOfType<String>(json, r'description')!,
endDate: mapDateTime(json, r'endDate', r''),
endDate: json.containsKey(r'endDate') ? Optional.present(mapDateTime(json, r'endDate', r'')) : const Optional.absent(),
hasSharedLink: mapValueOfType<bool>(json, r'hasSharedLink')!,
id: mapValueOfType<String>(json, r'id')!,
isActivityEnabled: mapValueOfType<bool>(json, r'isActivityEnabled')!,
lastModifiedAssetTimestamp: mapDateTime(json, r'lastModifiedAssetTimestamp', r''),
order: AssetOrder.fromJson(json[r'order']),
lastModifiedAssetTimestamp: json.containsKey(r'lastModifiedAssetTimestamp') ? Optional.present(mapDateTime(json, r'lastModifiedAssetTimestamp', r'')) : const Optional.absent(),
order: json.containsKey(r'order') ? Optional.present(AssetOrder.fromJson(json[r'order'])) : const Optional.absent(),
shared: mapValueOfType<bool>(json, r'shared')!,
startDate: mapDateTime(json, r'startDate', r''),
startDate: json.containsKey(r'startDate') ? Optional.present(mapDateTime(json, r'startDate', r'')) : const Optional.absent(),
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
);
}
@@ -68,6 +68,19 @@ class AlbumStatisticsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'notShared'), 'Required key "AlbumStatisticsResponseDto[notShared]" is missing from JSON.');
assert(json[r'notShared'] != null, 'Required key "AlbumStatisticsResponseDto[notShared]" has a null value in JSON.');
assert(json.containsKey(r'owned'), 'Required key "AlbumStatisticsResponseDto[owned]" is missing from JSON.');
assert(json[r'owned'] != null, 'Required key "AlbumStatisticsResponseDto[owned]" has a null value in JSON.');
assert(json.containsKey(r'shared'), 'Required key "AlbumStatisticsResponseDto[shared]" is missing from JSON.');
assert(json[r'shared'] != null, 'Required key "AlbumStatisticsResponseDto[shared]" has a null value in JSON.');
return true;
}());
return AlbumStatisticsResponseDto(
notShared: mapValueOfType<int>(json, r'notShared')!,
owned: mapValueOfType<int>(json, r'owned')!,
+15 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class AlbumUserAddDto {
/// Returns a new [AlbumUserAddDto] instance.
AlbumUserAddDto({
this.role,
this.role = const Optional.absent(),
required this.userId,
});
@@ -23,7 +23,7 @@ class AlbumUserAddDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AlbumUserRole? role;
Optional<AlbumUserRole?> role;
/// User ID
String userId;
@@ -44,10 +44,9 @@ class AlbumUserAddDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.role != null) {
json[r'role'] = this.role;
} else {
// json[r'role'] = null;
if (this.role.isPresent) {
final value = this.role.value;
json[r'role'] = value;
}
json[r'userId'] = this.userId;
return json;
@@ -61,8 +60,17 @@ class AlbumUserAddDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'userId'), 'Required key "AlbumUserAddDto[userId]" is missing from JSON.');
assert(json[r'userId'] != null, 'Required key "AlbumUserAddDto[userId]" has a null value in JSON.');
return true;
}());
return AlbumUserAddDto(
role: AlbumUserRole.fromJson(json[r'role']),
role: json.containsKey(r'role') ? Optional.present(AlbumUserRole.fromJson(json[r'role'])) : const Optional.absent(),
userId: mapValueOfType<String>(json, r'userId')!,
);
}
+11
View File
@@ -51,6 +51,17 @@ class AlbumUserCreateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'role'), 'Required key "AlbumUserCreateDto[role]" is missing from JSON.');
assert(json[r'role'] != null, 'Required key "AlbumUserCreateDto[role]" has a null value in JSON.');
assert(json.containsKey(r'userId'), 'Required key "AlbumUserCreateDto[userId]" is missing from JSON.');
assert(json[r'userId'] != null, 'Required key "AlbumUserCreateDto[userId]" has a null value in JSON.');
return true;
}());
return AlbumUserCreateDto(
role: AlbumUserRole.fromJson(json[r'role'])!,
userId: mapValueOfType<String>(json, r'userId')!,
+11
View File
@@ -50,6 +50,17 @@ class AlbumUserResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'role'), 'Required key "AlbumUserResponseDto[role]" is missing from JSON.');
assert(json[r'role'] != null, 'Required key "AlbumUserResponseDto[role]" has a null value in JSON.');
assert(json.containsKey(r'user'), 'Required key "AlbumUserResponseDto[user]" is missing from JSON.');
assert(json[r'user'] != null, 'Required key "AlbumUserResponseDto[user]" has a null value in JSON.');
return true;
}());
return AlbumUserResponseDto(
role: AlbumUserRole.fromJson(json[r'role'])!,
user: UserResponseDto.fromJson(json[r'user'])!,
+11
View File
@@ -52,6 +52,17 @@ class AlbumsAddAssetsDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'albumIds'), 'Required key "AlbumsAddAssetsDto[albumIds]" is missing from JSON.');
assert(json[r'albumIds'] != null, 'Required key "AlbumsAddAssetsDto[albumIds]" has a null value in JSON.');
assert(json.containsKey(r'assetIds'), 'Required key "AlbumsAddAssetsDto[assetIds]" is missing from JSON.');
assert(json[r'assetIds'] != null, 'Required key "AlbumsAddAssetsDto[assetIds]" has a null value in JSON.');
return true;
}());
return AlbumsAddAssetsDto(
albumIds: json[r'albumIds'] is Iterable
? (json[r'albumIds'] as Iterable).cast<String>().toList(growable: false)
+15 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class AlbumsAddAssetsResponseDto {
/// Returns a new [AlbumsAddAssetsResponseDto] instance.
AlbumsAddAssetsResponseDto({
this.error,
this.error = const Optional.absent(),
required this.success,
});
@@ -23,7 +23,7 @@ class AlbumsAddAssetsResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
BulkIdErrorReason? error;
Optional<BulkIdErrorReason?> error;
/// Operation success
bool success;
@@ -44,10 +44,9 @@ class AlbumsAddAssetsResponseDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.error != null) {
json[r'error'] = this.error;
} else {
// json[r'error'] = null;
if (this.error.isPresent) {
final value = this.error.value;
json[r'error'] = value;
}
json[r'success'] = this.success;
return json;
@@ -61,8 +60,17 @@ class AlbumsAddAssetsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'success'), 'Required key "AlbumsAddAssetsResponseDto[success]" is missing from JSON.');
assert(json[r'success'] != null, 'Required key "AlbumsAddAssetsResponseDto[success]" has a null value in JSON.');
return true;
}());
return AlbumsAddAssetsResponseDto(
error: BulkIdErrorReason.fromJson(json[r'error']),
error: json.containsKey(r'error') ? Optional.present(BulkIdErrorReason.fromJson(json[r'error'])) : const Optional.absent(),
success: mapValueOfType<bool>(json, r'success')!,
);
}
+9
View File
@@ -44,6 +44,15 @@ class AlbumsResponse {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'defaultAssetOrder'), 'Required key "AlbumsResponse[defaultAssetOrder]" is missing from JSON.');
assert(json[r'defaultAssetOrder'] != null, 'Required key "AlbumsResponse[defaultAssetOrder]" has a null value in JSON.');
return true;
}());
return AlbumsResponse(
defaultAssetOrder: AssetOrder.fromJson(json[r'defaultAssetOrder'])!,
);
+13 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class AlbumsUpdate {
/// Returns a new [AlbumsUpdate] instance.
AlbumsUpdate({
this.defaultAssetOrder,
this.defaultAssetOrder = const Optional.absent(),
});
///
@@ -22,7 +22,7 @@ class AlbumsUpdate {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AssetOrder? defaultAssetOrder;
Optional<AssetOrder?> defaultAssetOrder;
@override
bool operator ==(Object other) => identical(this, other) || other is AlbumsUpdate &&
@@ -38,10 +38,9 @@ class AlbumsUpdate {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.defaultAssetOrder != null) {
json[r'defaultAssetOrder'] = this.defaultAssetOrder;
} else {
// json[r'defaultAssetOrder'] = null;
if (this.defaultAssetOrder.isPresent) {
final value = this.defaultAssetOrder.value;
json[r'defaultAssetOrder'] = value;
}
return json;
}
@@ -54,8 +53,15 @@ class AlbumsUpdate {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
return true;
}());
return AlbumsUpdate(
defaultAssetOrder: AssetOrder.fromJson(json[r'defaultAssetOrder']),
defaultAssetOrder: json.containsKey(r'defaultAssetOrder') ? Optional.present(AssetOrder.fromJson(json[r'defaultAssetOrder'])) : const Optional.absent(),
);
}
return null;
+15 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class ApiKeyCreateDto {
/// Returns a new [ApiKeyCreateDto] instance.
ApiKeyCreateDto({
this.name,
this.name = const Optional.absent(),
this.permissions = const [],
});
@@ -24,7 +24,7 @@ class ApiKeyCreateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? name;
Optional<String?> name;
/// List of permissions
List<Permission> permissions;
@@ -45,10 +45,9 @@ class ApiKeyCreateDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.name != null) {
json[r'name'] = this.name;
} else {
// json[r'name'] = null;
if (this.name.isPresent) {
final value = this.name.value;
json[r'name'] = value;
}
json[r'permissions'] = this.permissions;
return json;
@@ -62,8 +61,17 @@ class ApiKeyCreateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'permissions'), 'Required key "ApiKeyCreateDto[permissions]" is missing from JSON.');
assert(json[r'permissions'] != null, 'Required key "ApiKeyCreateDto[permissions]" has a null value in JSON.');
return true;
}());
return ApiKeyCreateDto(
name: mapValueOfType<String>(json, r'name'),
name: json.containsKey(r'name') ? Optional.present(mapValueOfType<String>(json, r'name')) : const Optional.absent(),
permissions: Permission.listFromJson(json[r'permissions']),
);
}
@@ -51,6 +51,17 @@ class ApiKeyCreateResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'apiKey'), 'Required key "ApiKeyCreateResponseDto[apiKey]" is missing from JSON.');
assert(json[r'apiKey'] != null, 'Required key "ApiKeyCreateResponseDto[apiKey]" has a null value in JSON.');
assert(json.containsKey(r'secret'), 'Required key "ApiKeyCreateResponseDto[secret]" is missing from JSON.');
assert(json[r'secret'] != null, 'Required key "ApiKeyCreateResponseDto[secret]" has a null value in JSON.');
return true;
}());
return ApiKeyCreateResponseDto(
apiKey: ApiKeyResponseDto.fromJson(json[r'apiKey'])!,
secret: mapValueOfType<String>(json, r'secret')!,
+17
View File
@@ -77,6 +77,23 @@ class ApiKeyResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'createdAt'), 'Required key "ApiKeyResponseDto[createdAt]" is missing from JSON.');
assert(json[r'createdAt'] != null, 'Required key "ApiKeyResponseDto[createdAt]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "ApiKeyResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "ApiKeyResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'name'), 'Required key "ApiKeyResponseDto[name]" is missing from JSON.');
assert(json[r'name'] != null, 'Required key "ApiKeyResponseDto[name]" has a null value in JSON.');
assert(json.containsKey(r'permissions'), 'Required key "ApiKeyResponseDto[permissions]" is missing from JSON.');
assert(json[r'permissions'] != null, 'Required key "ApiKeyResponseDto[permissions]" has a null value in JSON.');
assert(json.containsKey(r'updatedAt'), 'Required key "ApiKeyResponseDto[updatedAt]" is missing from JSON.');
assert(json[r'updatedAt'] != null, 'Required key "ApiKeyResponseDto[updatedAt]" has a null value in JSON.');
return true;
}());
return ApiKeyResponseDto(
createdAt: mapDateTime(json, r'createdAt', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/')!,
id: mapValueOfType<String>(json, r'id')!,
+20 -11
View File
@@ -13,8 +13,8 @@ part of openapi.api;
class ApiKeyUpdateDto {
/// Returns a new [ApiKeyUpdateDto] instance.
ApiKeyUpdateDto({
this.name,
this.permissions = const [],
this.name = const Optional.absent(),
this.permissions = const Optional.present(const []),
});
/// API key name
@@ -24,10 +24,10 @@ class ApiKeyUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? name;
Optional<String?> name;
/// List of permissions
List<Permission> permissions;
Optional<List<Permission>?> permissions;
@override
bool operator ==(Object other) => identical(this, other) || other is ApiKeyUpdateDto &&
@@ -45,12 +45,14 @@ class ApiKeyUpdateDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.name != null) {
json[r'name'] = this.name;
} else {
// json[r'name'] = null;
if (this.name.isPresent) {
final value = this.name.value;
json[r'name'] = value;
}
if (this.permissions.isPresent) {
final value = this.permissions.value;
json[r'permissions'] = value;
}
json[r'permissions'] = this.permissions;
return json;
}
@@ -62,9 +64,16 @@ class ApiKeyUpdateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
return true;
}());
return ApiKeyUpdateDto(
name: mapValueOfType<String>(json, r'name'),
permissions: Permission.listFromJson(json[r'permissions']),
name: json.containsKey(r'name') ? Optional.present(mapValueOfType<String>(json, r'name')) : const Optional.absent(),
permissions: json.containsKey(r'permissions') ? Optional.present(Permission.listFromJson(json[r'permissions'])) : const Optional.absent(),
);
}
return null;
+15 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class AssetBulkDeleteDto {
/// Returns a new [AssetBulkDeleteDto] instance.
AssetBulkDeleteDto({
this.force,
this.force = const Optional.absent(),
this.ids = const [],
});
@@ -24,7 +24,7 @@ class AssetBulkDeleteDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? force;
Optional<bool?> force;
/// IDs to process
List<String> ids;
@@ -45,10 +45,9 @@ class AssetBulkDeleteDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.force != null) {
json[r'force'] = this.force;
} else {
// json[r'force'] = null;
if (this.force.isPresent) {
final value = this.force.value;
json[r'force'] = value;
}
json[r'ids'] = this.ids;
return json;
@@ -62,8 +61,17 @@ class AssetBulkDeleteDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'ids'), 'Required key "AssetBulkDeleteDto[ids]" is missing from JSON.');
assert(json[r'ids'] != null, 'Required key "AssetBulkDeleteDto[ids]" has a null value in JSON.');
return true;
}());
return AssetBulkDeleteDto(
force: mapValueOfType<bool>(json, r'force'),
force: json.containsKey(r'force') ? Optional.present(mapValueOfType<bool>(json, r'force')) : const Optional.absent(),
ids: json[r'ids'] is Iterable
? (json[r'ids'] as Iterable).cast<String>().toList(growable: false)
: const [],
+69 -70
View File
@@ -13,17 +13,17 @@ part of openapi.api;
class AssetBulkUpdateDto {
/// Returns a new [AssetBulkUpdateDto] instance.
AssetBulkUpdateDto({
this.dateTimeOriginal,
this.dateTimeRelative,
this.description,
this.duplicateId,
this.dateTimeOriginal = const Optional.absent(),
this.dateTimeRelative = const Optional.absent(),
this.description = const Optional.absent(),
this.duplicateId = const Optional.absent(),
this.ids = const [],
this.isFavorite,
this.latitude,
this.longitude,
this.rating,
this.timeZone,
this.visibility,
this.isFavorite = const Optional.absent(),
this.latitude = const Optional.absent(),
this.longitude = const Optional.absent(),
this.rating = const Optional.absent(),
this.timeZone = const Optional.absent(),
this.visibility = const Optional.absent(),
});
/// Original date and time
@@ -33,7 +33,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? dateTimeOriginal;
Optional<String?> dateTimeOriginal;
/// Relative time offset in seconds
///
@@ -45,7 +45,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
int? dateTimeRelative;
Optional<int?> dateTimeRelative;
/// Asset description
///
@@ -54,10 +54,10 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? description;
Optional<String?> description;
/// Duplicate ID
String? duplicateId;
Optional<String?> duplicateId;
/// Asset IDs to update
List<String> ids;
@@ -69,7 +69,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? isFavorite;
Optional<bool?> isFavorite;
/// Latitude coordinate
///
@@ -81,7 +81,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
num? latitude;
Optional<num?> latitude;
/// Longitude coordinate
///
@@ -93,13 +93,13 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
num? longitude;
Optional<num?> longitude;
/// Rating in range [1-5], or null for unrated
///
/// Minimum value: -1
/// Maximum value: 5
int? rating;
Optional<int?> rating;
/// Time zone (IANA timezone)
///
@@ -108,7 +108,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? timeZone;
Optional<String?> timeZone;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -116,7 +116,7 @@ class AssetBulkUpdateDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AssetVisibility? visibility;
Optional<AssetVisibility?> visibility;
@override
bool operator ==(Object other) => identical(this, other) || other is AssetBulkUpdateDto &&
@@ -152,56 +152,46 @@ class AssetBulkUpdateDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.dateTimeOriginal != null) {
json[r'dateTimeOriginal'] = this.dateTimeOriginal;
} else {
// json[r'dateTimeOriginal'] = null;
if (this.dateTimeOriginal.isPresent) {
final value = this.dateTimeOriginal.value;
json[r'dateTimeOriginal'] = value;
}
if (this.dateTimeRelative != null) {
json[r'dateTimeRelative'] = this.dateTimeRelative;
} else {
// json[r'dateTimeRelative'] = null;
if (this.dateTimeRelative.isPresent) {
final value = this.dateTimeRelative.value;
json[r'dateTimeRelative'] = value;
}
if (this.description != null) {
json[r'description'] = this.description;
} else {
// json[r'description'] = null;
if (this.description.isPresent) {
final value = this.description.value;
json[r'description'] = value;
}
if (this.duplicateId != null) {
json[r'duplicateId'] = this.duplicateId;
} else {
// json[r'duplicateId'] = null;
if (this.duplicateId.isPresent) {
final value = this.duplicateId.value;
json[r'duplicateId'] = value;
}
json[r'ids'] = this.ids;
if (this.isFavorite != null) {
json[r'isFavorite'] = this.isFavorite;
} else {
// json[r'isFavorite'] = null;
if (this.isFavorite.isPresent) {
final value = this.isFavorite.value;
json[r'isFavorite'] = value;
}
if (this.latitude != null) {
json[r'latitude'] = this.latitude;
} else {
// json[r'latitude'] = null;
if (this.latitude.isPresent) {
final value = this.latitude.value;
json[r'latitude'] = value;
}
if (this.longitude != null) {
json[r'longitude'] = this.longitude;
} else {
// json[r'longitude'] = null;
if (this.longitude.isPresent) {
final value = this.longitude.value;
json[r'longitude'] = value;
}
if (this.rating != null) {
json[r'rating'] = this.rating;
} else {
// json[r'rating'] = null;
if (this.rating.isPresent) {
final value = this.rating.value;
json[r'rating'] = value;
}
if (this.timeZone != null) {
json[r'timeZone'] = this.timeZone;
} else {
// json[r'timeZone'] = null;
if (this.timeZone.isPresent) {
final value = this.timeZone.value;
json[r'timeZone'] = value;
}
if (this.visibility != null) {
json[r'visibility'] = this.visibility;
} else {
// json[r'visibility'] = null;
if (this.visibility.isPresent) {
final value = this.visibility.value;
json[r'visibility'] = value;
}
return json;
}
@@ -214,20 +204,29 @@ class AssetBulkUpdateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'ids'), 'Required key "AssetBulkUpdateDto[ids]" is missing from JSON.');
assert(json[r'ids'] != null, 'Required key "AssetBulkUpdateDto[ids]" has a null value in JSON.');
return true;
}());
return AssetBulkUpdateDto(
dateTimeOriginal: mapValueOfType<String>(json, r'dateTimeOriginal'),
dateTimeRelative: mapValueOfType<int>(json, r'dateTimeRelative'),
description: mapValueOfType<String>(json, r'description'),
duplicateId: mapValueOfType<String>(json, r'duplicateId'),
dateTimeOriginal: json.containsKey(r'dateTimeOriginal') ? Optional.present(mapValueOfType<String>(json, r'dateTimeOriginal')) : const Optional.absent(),
dateTimeRelative: json.containsKey(r'dateTimeRelative') ? Optional.present(json[r'dateTimeRelative'] == null ? null : int.parse('${json[r'dateTimeRelative']}')) : const Optional.absent(),
description: json.containsKey(r'description') ? Optional.present(mapValueOfType<String>(json, r'description')) : const Optional.absent(),
duplicateId: json.containsKey(r'duplicateId') ? Optional.present(mapValueOfType<String>(json, r'duplicateId')) : const Optional.absent(),
ids: json[r'ids'] is Iterable
? (json[r'ids'] as Iterable).cast<String>().toList(growable: false)
: const [],
isFavorite: mapValueOfType<bool>(json, r'isFavorite'),
latitude: num.parse('${json[r'latitude']}'),
longitude: num.parse('${json[r'longitude']}'),
rating: mapValueOfType<int>(json, r'rating'),
timeZone: mapValueOfType<String>(json, r'timeZone'),
visibility: AssetVisibility.fromJson(json[r'visibility']),
isFavorite: json.containsKey(r'isFavorite') ? Optional.present(mapValueOfType<bool>(json, r'isFavorite')) : const Optional.absent(),
latitude: json.containsKey(r'latitude') ? Optional.present(json[r'latitude'] == null ? null : num.parse('${json[r'latitude']}')) : const Optional.absent(),
longitude: json.containsKey(r'longitude') ? Optional.present(json[r'longitude'] == null ? null : num.parse('${json[r'longitude']}')) : const Optional.absent(),
rating: json.containsKey(r'rating') ? Optional.present(json[r'rating'] == null ? null : int.parse('${json[r'rating']}')) : const Optional.absent(),
timeZone: json.containsKey(r'timeZone') ? Optional.present(mapValueOfType<String>(json, r'timeZone')) : const Optional.absent(),
visibility: json.containsKey(r'visibility') ? Optional.present(AssetVisibility.fromJson(json[r'visibility'])) : const Optional.absent(),
);
}
return null;
@@ -45,6 +45,15 @@ class AssetBulkUploadCheckDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assets'), 'Required key "AssetBulkUploadCheckDto[assets]" is missing from JSON.');
assert(json[r'assets'] != null, 'Required key "AssetBulkUploadCheckDto[assets]" has a null value in JSON.');
return true;
}());
return AssetBulkUploadCheckDto(
assets: AssetBulkUploadCheckItem.listFromJson(json[r'assets']),
);
@@ -52,6 +52,17 @@ class AssetBulkUploadCheckItem {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'checksum'), 'Required key "AssetBulkUploadCheckItem[checksum]" is missing from JSON.');
assert(json[r'checksum'] != null, 'Required key "AssetBulkUploadCheckItem[checksum]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetBulkUploadCheckItem[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetBulkUploadCheckItem[id]" has a null value in JSON.');
return true;
}());
return AssetBulkUploadCheckItem(
checksum: mapValueOfType<String>(json, r'checksum')!,
id: mapValueOfType<String>(json, r'id')!,
@@ -45,6 +45,15 @@ class AssetBulkUploadCheckResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'results'), 'Required key "AssetBulkUploadCheckResponseDto[results]" is missing from JSON.');
assert(json[r'results'] != null, 'Required key "AssetBulkUploadCheckResponseDto[results]" has a null value in JSON.');
return true;
}());
return AssetBulkUploadCheckResponseDto(
results: AssetBulkUploadCheckResult.listFromJson(json[r'results']),
);
+29 -21
View File
@@ -14,10 +14,10 @@ class AssetBulkUploadCheckResult {
/// Returns a new [AssetBulkUploadCheckResult] instance.
AssetBulkUploadCheckResult({
required this.action,
this.assetId,
this.assetId = const Optional.absent(),
required this.id,
this.isTrashed,
this.reason,
this.isTrashed = const Optional.absent(),
this.reason = const Optional.absent(),
});
AssetUploadAction action;
@@ -29,7 +29,7 @@ class AssetBulkUploadCheckResult {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? assetId;
Optional<String?> assetId;
/// Asset ID
String id;
@@ -41,7 +41,7 @@ class AssetBulkUploadCheckResult {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? isTrashed;
Optional<bool?> isTrashed;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -49,7 +49,7 @@ class AssetBulkUploadCheckResult {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AssetRejectReason? reason;
Optional<AssetRejectReason?> reason;
@override
bool operator ==(Object other) => identical(this, other) || other is AssetBulkUploadCheckResult &&
@@ -74,21 +74,18 @@ class AssetBulkUploadCheckResult {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'action'] = this.action;
if (this.assetId != null) {
json[r'assetId'] = this.assetId;
} else {
// json[r'assetId'] = null;
if (this.assetId.isPresent) {
final value = this.assetId.value;
json[r'assetId'] = value;
}
json[r'id'] = this.id;
if (this.isTrashed != null) {
json[r'isTrashed'] = this.isTrashed;
} else {
// json[r'isTrashed'] = null;
if (this.isTrashed.isPresent) {
final value = this.isTrashed.value;
json[r'isTrashed'] = value;
}
if (this.reason != null) {
json[r'reason'] = this.reason;
} else {
// json[r'reason'] = null;
if (this.reason.isPresent) {
final value = this.reason.value;
json[r'reason'] = value;
}
return json;
}
@@ -101,12 +98,23 @@ class AssetBulkUploadCheckResult {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'action'), 'Required key "AssetBulkUploadCheckResult[action]" is missing from JSON.');
assert(json[r'action'] != null, 'Required key "AssetBulkUploadCheckResult[action]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetBulkUploadCheckResult[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetBulkUploadCheckResult[id]" has a null value in JSON.');
return true;
}());
return AssetBulkUploadCheckResult(
action: AssetUploadAction.fromJson(json[r'action'])!,
assetId: mapValueOfType<String>(json, r'assetId'),
assetId: json.containsKey(r'assetId') ? Optional.present(mapValueOfType<String>(json, r'assetId')) : const Optional.absent(),
id: mapValueOfType<String>(json, r'id')!,
isTrashed: mapValueOfType<bool>(json, r'isTrashed'),
reason: AssetRejectReason.fromJson(json[r'reason']),
isTrashed: json.containsKey(r'isTrashed') ? Optional.present(mapValueOfType<bool>(json, r'isTrashed')) : const Optional.absent(),
reason: json.containsKey(r'reason') ? Optional.present(AssetRejectReason.fromJson(json[r'reason'])) : const Optional.absent(),
);
}
return null;
+46 -20
View File
@@ -13,32 +13,32 @@ part of openapi.api;
class AssetCopyDto {
/// Returns a new [AssetCopyDto] instance.
AssetCopyDto({
this.albums = true,
this.favorite = true,
this.sharedLinks = true,
this.sidecar = true,
this.albums = const Optional.present(true),
this.favorite = const Optional.present(true),
this.sharedLinks = const Optional.present(true),
this.sidecar = const Optional.present(true),
required this.sourceId,
this.stack = true,
this.stack = const Optional.present(true),
required this.targetId,
});
/// Copy album associations
bool albums;
Optional<bool?> albums;
/// Copy favorite status
bool favorite;
Optional<bool?> favorite;
/// Copy shared links
bool sharedLinks;
Optional<bool?> sharedLinks;
/// Copy sidecar file
bool sidecar;
Optional<bool?> sidecar;
/// Source asset ID
String sourceId;
/// Copy stack association
bool stack;
Optional<bool?> stack;
/// Target asset ID
String targetId;
@@ -69,12 +69,27 @@ class AssetCopyDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'albums'] = this.albums;
json[r'favorite'] = this.favorite;
json[r'sharedLinks'] = this.sharedLinks;
json[r'sidecar'] = this.sidecar;
if (this.albums.isPresent) {
final value = this.albums.value;
json[r'albums'] = value;
}
if (this.favorite.isPresent) {
final value = this.favorite.value;
json[r'favorite'] = value;
}
if (this.sharedLinks.isPresent) {
final value = this.sharedLinks.value;
json[r'sharedLinks'] = value;
}
if (this.sidecar.isPresent) {
final value = this.sidecar.value;
json[r'sidecar'] = value;
}
json[r'sourceId'] = this.sourceId;
json[r'stack'] = this.stack;
if (this.stack.isPresent) {
final value = this.stack.value;
json[r'stack'] = value;
}
json[r'targetId'] = this.targetId;
return json;
}
@@ -87,13 +102,24 @@ class AssetCopyDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'sourceId'), 'Required key "AssetCopyDto[sourceId]" is missing from JSON.');
assert(json[r'sourceId'] != null, 'Required key "AssetCopyDto[sourceId]" has a null value in JSON.');
assert(json.containsKey(r'targetId'), 'Required key "AssetCopyDto[targetId]" is missing from JSON.');
assert(json[r'targetId'] != null, 'Required key "AssetCopyDto[targetId]" has a null value in JSON.');
return true;
}());
return AssetCopyDto(
albums: mapValueOfType<bool>(json, r'albums') ?? true,
favorite: mapValueOfType<bool>(json, r'favorite') ?? true,
sharedLinks: mapValueOfType<bool>(json, r'sharedLinks') ?? true,
sidecar: mapValueOfType<bool>(json, r'sidecar') ?? true,
albums: json.containsKey(r'albums') ? Optional.present(mapValueOfType<bool>(json, r'albums')) : const Optional.absent(),
favorite: json.containsKey(r'favorite') ? Optional.present(mapValueOfType<bool>(json, r'favorite')) : const Optional.absent(),
sharedLinks: json.containsKey(r'sharedLinks') ? Optional.present(mapValueOfType<bool>(json, r'sharedLinks')) : const Optional.absent(),
sidecar: json.containsKey(r'sidecar') ? Optional.present(mapValueOfType<bool>(json, r'sidecar')) : const Optional.absent(),
sourceId: mapValueOfType<String>(json, r'sourceId')!,
stack: mapValueOfType<bool>(json, r'stack') ?? true,
stack: json.containsKey(r'stack') ? Optional.present(mapValueOfType<bool>(json, r'stack')) : const Optional.absent(),
targetId: mapValueOfType<String>(json, r'targetId')!,
);
}
+11
View File
@@ -50,6 +50,17 @@ class AssetEditActionItemDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'action'), 'Required key "AssetEditActionItemDto[action]" is missing from JSON.');
assert(json[r'action'] != null, 'Required key "AssetEditActionItemDto[action]" has a null value in JSON.');
assert(json.containsKey(r'parameters'), 'Required key "AssetEditActionItemDto[parameters]" is missing from JSON.');
assert(json[r'parameters'] != null, 'Required key "AssetEditActionItemDto[parameters]" has a null value in JSON.');
return true;
}());
return AssetEditActionItemDto(
action: AssetEditAction.fromJson(json[r'action'])!,
parameters: json[r'parameters'],
@@ -91,6 +91,25 @@ class AssetEditActionItemDtoParameters {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'height'), 'Required key "AssetEditActionItemDtoParameters[height]" is missing from JSON.');
assert(json[r'height'] != null, 'Required key "AssetEditActionItemDtoParameters[height]" has a null value in JSON.');
assert(json.containsKey(r'width'), 'Required key "AssetEditActionItemDtoParameters[width]" is missing from JSON.');
assert(json[r'width'] != null, 'Required key "AssetEditActionItemDtoParameters[width]" has a null value in JSON.');
assert(json.containsKey(r'x'), 'Required key "AssetEditActionItemDtoParameters[x]" is missing from JSON.');
assert(json[r'x'] != null, 'Required key "AssetEditActionItemDtoParameters[x]" has a null value in JSON.');
assert(json.containsKey(r'y'), 'Required key "AssetEditActionItemDtoParameters[y]" is missing from JSON.');
assert(json[r'y'] != null, 'Required key "AssetEditActionItemDtoParameters[y]" has a null value in JSON.');
assert(json.containsKey(r'angle'), 'Required key "AssetEditActionItemDtoParameters[angle]" is missing from JSON.');
assert(json[r'angle'] != null, 'Required key "AssetEditActionItemDtoParameters[angle]" has a null value in JSON.');
assert(json.containsKey(r'axis'), 'Required key "AssetEditActionItemDtoParameters[axis]" is missing from JSON.');
assert(json[r'axis'] != null, 'Required key "AssetEditActionItemDtoParameters[axis]" has a null value in JSON.');
return true;
}());
return AssetEditActionItemDtoParameters(
height: mapValueOfType<int>(json, r'height')!,
width: mapValueOfType<int>(json, r'width')!,
@@ -57,6 +57,19 @@ class AssetEditActionItemResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'action'), 'Required key "AssetEditActionItemResponseDto[action]" is missing from JSON.');
assert(json[r'action'] != null, 'Required key "AssetEditActionItemResponseDto[action]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetEditActionItemResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetEditActionItemResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'parameters'), 'Required key "AssetEditActionItemResponseDto[parameters]" is missing from JSON.');
assert(json[r'parameters'] != null, 'Required key "AssetEditActionItemResponseDto[parameters]" has a null value in JSON.');
return true;
}());
return AssetEditActionItemResponseDto(
action: AssetEditAction.fromJson(json[r'action'])!,
id: mapValueOfType<String>(json, r'id')!,
+9
View File
@@ -45,6 +45,15 @@ class AssetEditsCreateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'edits'), 'Required key "AssetEditsCreateDto[edits]" is missing from JSON.');
assert(json[r'edits'] != null, 'Required key "AssetEditsCreateDto[edits]" has a null value in JSON.');
return true;
}());
return AssetEditsCreateDto(
edits: AssetEditActionItemDto.listFromJson(json[r'edits']),
);
+11
View File
@@ -52,6 +52,17 @@ class AssetEditsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetEditsResponseDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetEditsResponseDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'edits'), 'Required key "AssetEditsResponseDto[edits]" is missing from JSON.');
assert(json[r'edits'] != null, 'Required key "AssetEditsResponseDto[edits]" has a null value in JSON.');
return true;
}());
return AssetEditsResponseDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
edits: AssetEditActionItemResponseDto.listFromJson(json[r'edits']),
+23
View File
@@ -112,6 +112,29 @@ class AssetFaceCreateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetFaceCreateDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetFaceCreateDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'height'), 'Required key "AssetFaceCreateDto[height]" is missing from JSON.');
assert(json[r'height'] != null, 'Required key "AssetFaceCreateDto[height]" has a null value in JSON.');
assert(json.containsKey(r'imageHeight'), 'Required key "AssetFaceCreateDto[imageHeight]" is missing from JSON.');
assert(json[r'imageHeight'] != null, 'Required key "AssetFaceCreateDto[imageHeight]" has a null value in JSON.');
assert(json.containsKey(r'imageWidth'), 'Required key "AssetFaceCreateDto[imageWidth]" is missing from JSON.');
assert(json[r'imageWidth'] != null, 'Required key "AssetFaceCreateDto[imageWidth]" has a null value in JSON.');
assert(json.containsKey(r'personId'), 'Required key "AssetFaceCreateDto[personId]" is missing from JSON.');
assert(json[r'personId'] != null, 'Required key "AssetFaceCreateDto[personId]" has a null value in JSON.');
assert(json.containsKey(r'width'), 'Required key "AssetFaceCreateDto[width]" is missing from JSON.');
assert(json[r'width'] != null, 'Required key "AssetFaceCreateDto[width]" has a null value in JSON.');
assert(json.containsKey(r'x'), 'Required key "AssetFaceCreateDto[x]" is missing from JSON.');
assert(json[r'x'] != null, 'Required key "AssetFaceCreateDto[x]" has a null value in JSON.');
assert(json.containsKey(r'y'), 'Required key "AssetFaceCreateDto[y]" is missing from JSON.');
assert(json[r'y'] != null, 'Required key "AssetFaceCreateDto[y]" has a null value in JSON.');
return true;
}());
return AssetFaceCreateDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
height: mapValueOfType<int>(json, r'height')!,
+9
View File
@@ -45,6 +45,15 @@ class AssetFaceDeleteDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'force'), 'Required key "AssetFaceDeleteDto[force]" is missing from JSON.');
assert(json[r'force'] != null, 'Required key "AssetFaceDeleteDto[force]" has a null value in JSON.');
return true;
}());
return AssetFaceDeleteDto(
force: mapValueOfType<bool>(json, r'force')!,
);
+29 -8
View File
@@ -21,7 +21,7 @@ class AssetFaceResponseDto {
required this.imageHeight,
required this.imageWidth,
required this.person,
this.sourceType,
this.sourceType = const Optional.absent(),
});
/// Bounding box X1 coordinate
@@ -71,7 +71,7 @@ class AssetFaceResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
SourceType? sourceType;
Optional<SourceType?> sourceType;
@override
bool operator ==(Object other) => identical(this, other) || other is AssetFaceResponseDto &&
@@ -113,12 +113,11 @@ class AssetFaceResponseDto {
if (this.person != null) {
json[r'person'] = this.person;
} else {
// json[r'person'] = null;
json[r'person'] = null;
}
if (this.sourceType != null) {
json[r'sourceType'] = this.sourceType;
} else {
// json[r'sourceType'] = null;
if (this.sourceType.isPresent) {
final value = this.sourceType.value;
json[r'sourceType'] = value;
}
return json;
}
@@ -131,6 +130,28 @@ class AssetFaceResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'boundingBoxX1'), 'Required key "AssetFaceResponseDto[boundingBoxX1]" is missing from JSON.');
assert(json[r'boundingBoxX1'] != null, 'Required key "AssetFaceResponseDto[boundingBoxX1]" has a null value in JSON.');
assert(json.containsKey(r'boundingBoxX2'), 'Required key "AssetFaceResponseDto[boundingBoxX2]" is missing from JSON.');
assert(json[r'boundingBoxX2'] != null, 'Required key "AssetFaceResponseDto[boundingBoxX2]" has a null value in JSON.');
assert(json.containsKey(r'boundingBoxY1'), 'Required key "AssetFaceResponseDto[boundingBoxY1]" is missing from JSON.');
assert(json[r'boundingBoxY1'] != null, 'Required key "AssetFaceResponseDto[boundingBoxY1]" has a null value in JSON.');
assert(json.containsKey(r'boundingBoxY2'), 'Required key "AssetFaceResponseDto[boundingBoxY2]" is missing from JSON.');
assert(json[r'boundingBoxY2'] != null, 'Required key "AssetFaceResponseDto[boundingBoxY2]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetFaceResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetFaceResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'imageHeight'), 'Required key "AssetFaceResponseDto[imageHeight]" is missing from JSON.');
assert(json[r'imageHeight'] != null, 'Required key "AssetFaceResponseDto[imageHeight]" has a null value in JSON.');
assert(json.containsKey(r'imageWidth'), 'Required key "AssetFaceResponseDto[imageWidth]" is missing from JSON.');
assert(json[r'imageWidth'] != null, 'Required key "AssetFaceResponseDto[imageWidth]" has a null value in JSON.');
assert(json.containsKey(r'person'), 'Required key "AssetFaceResponseDto[person]" is missing from JSON.');
return true;
}());
return AssetFaceResponseDto(
boundingBoxX1: mapValueOfType<int>(json, r'boundingBoxX1')!,
boundingBoxX2: mapValueOfType<int>(json, r'boundingBoxX2')!,
@@ -140,7 +161,7 @@ class AssetFaceResponseDto {
imageHeight: mapValueOfType<int>(json, r'imageHeight')!,
imageWidth: mapValueOfType<int>(json, r'imageWidth')!,
person: PersonResponseDto.fromJson(json[r'person']),
sourceType: SourceType.fromJson(json[r'sourceType']),
sourceType: json.containsKey(r'sourceType') ? Optional.present(SourceType.fromJson(json[r'sourceType'])) : const Optional.absent(),
);
}
return null;
+9
View File
@@ -45,6 +45,15 @@ class AssetFaceUpdateDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'data'), 'Required key "AssetFaceUpdateDto[data]" is missing from JSON.');
assert(json[r'data'] != null, 'Required key "AssetFaceUpdateDto[data]" has a null value in JSON.');
return true;
}());
return AssetFaceUpdateDto(
data: AssetFaceUpdateItem.listFromJson(json[r'data']),
);
+11
View File
@@ -52,6 +52,17 @@ class AssetFaceUpdateItem {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetFaceUpdateItem[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetFaceUpdateItem[assetId]" has a null value in JSON.');
assert(json.containsKey(r'personId'), 'Required key "AssetFaceUpdateItem[personId]" is missing from JSON.');
assert(json[r'personId'] != null, 'Required key "AssetFaceUpdateItem[personId]" has a null value in JSON.');
return true;
}());
return AssetFaceUpdateItem(
assetId: mapValueOfType<String>(json, r'assetId')!,
personId: mapValueOfType<String>(json, r'personId')!,
+9
View File
@@ -45,6 +45,15 @@ class AssetIdsDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetIds'), 'Required key "AssetIdsDto[assetIds]" is missing from JSON.');
assert(json[r'assetIds'] != null, 'Required key "AssetIdsDto[assetIds]" has a null value in JSON.');
return true;
}());
return AssetIdsDto(
assetIds: json[r'assetIds'] is Iterable
? (json[r'assetIds'] as Iterable).cast<String>().toList(growable: false)
+17 -7
View File
@@ -14,7 +14,7 @@ class AssetIdsResponseDto {
/// Returns a new [AssetIdsResponseDto] instance.
AssetIdsResponseDto({
required this.assetId,
this.error,
this.error = const Optional.absent(),
required this.success,
});
@@ -27,7 +27,7 @@ class AssetIdsResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
AssetIdErrorReason? error;
Optional<AssetIdErrorReason?> error;
/// Whether operation succeeded
bool success;
@@ -51,10 +51,9 @@ class AssetIdsResponseDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
json[r'assetId'] = this.assetId;
if (this.error != null) {
json[r'error'] = this.error;
} else {
// json[r'error'] = null;
if (this.error.isPresent) {
final value = this.error.value;
json[r'error'] = value;
}
json[r'success'] = this.success;
return json;
@@ -68,9 +67,20 @@ class AssetIdsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetIdsResponseDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetIdsResponseDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'success'), 'Required key "AssetIdsResponseDto[success]" is missing from JSON.');
assert(json[r'success'] != null, 'Required key "AssetIdsResponseDto[success]" has a null value in JSON.');
return true;
}());
return AssetIdsResponseDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
error: AssetIdErrorReason.fromJson(json[r'error']),
error: json.containsKey(r'error') ? Optional.present(AssetIdErrorReason.fromJson(json[r'error'])) : const Optional.absent(),
success: mapValueOfType<bool>(json, r'success')!,
);
}
+11
View File
@@ -51,6 +51,17 @@ class AssetJobsDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetIds'), 'Required key "AssetJobsDto[assetIds]" is missing from JSON.');
assert(json[r'assetIds'] != null, 'Required key "AssetJobsDto[assetIds]" has a null value in JSON.');
assert(json.containsKey(r'name'), 'Required key "AssetJobsDto[name]" is missing from JSON.');
assert(json[r'name'] != null, 'Required key "AssetJobsDto[name]" has a null value in JSON.');
return true;
}());
return AssetJobsDto(
assetIds: json[r'assetIds'] is Iterable
? (json[r'assetIds'] as Iterable).cast<String>().toList(growable: false)
+11
View File
@@ -51,6 +51,17 @@ class AssetMediaResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'id'), 'Required key "AssetMediaResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetMediaResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'status'), 'Required key "AssetMediaResponseDto[status]" is missing from JSON.');
assert(json[r'status'] != null, 'Required key "AssetMediaResponseDto[status]" has a null value in JSON.');
return true;
}());
return AssetMediaResponseDto(
id: mapValueOfType<String>(json, r'id')!,
status: AssetMediaStatus.fromJson(json[r'status'])!,
@@ -45,6 +45,15 @@ class AssetMetadataBulkDeleteDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'items'), 'Required key "AssetMetadataBulkDeleteDto[items]" is missing from JSON.');
assert(json[r'items'] != null, 'Required key "AssetMetadataBulkDeleteDto[items]" has a null value in JSON.');
return true;
}());
return AssetMetadataBulkDeleteDto(
items: AssetMetadataBulkDeleteItemDto.listFromJson(json[r'items']),
);
@@ -52,6 +52,17 @@ class AssetMetadataBulkDeleteItemDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetMetadataBulkDeleteItemDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetMetadataBulkDeleteItemDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'key'), 'Required key "AssetMetadataBulkDeleteItemDto[key]" is missing from JSON.');
assert(json[r'key'] != null, 'Required key "AssetMetadataBulkDeleteItemDto[key]" has a null value in JSON.');
return true;
}());
return AssetMetadataBulkDeleteItemDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
key: mapValueOfType<String>(json, r'key')!,
@@ -68,6 +68,21 @@ class AssetMetadataBulkResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetMetadataBulkResponseDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetMetadataBulkResponseDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'key'), 'Required key "AssetMetadataBulkResponseDto[key]" is missing from JSON.');
assert(json[r'key'] != null, 'Required key "AssetMetadataBulkResponseDto[key]" has a null value in JSON.');
assert(json.containsKey(r'updatedAt'), 'Required key "AssetMetadataBulkResponseDto[updatedAt]" is missing from JSON.');
assert(json[r'updatedAt'] != null, 'Required key "AssetMetadataBulkResponseDto[updatedAt]" has a null value in JSON.');
assert(json.containsKey(r'value'), 'Required key "AssetMetadataBulkResponseDto[value]" is missing from JSON.');
assert(json[r'value'] != null, 'Required key "AssetMetadataBulkResponseDto[value]" has a null value in JSON.');
return true;
}());
return AssetMetadataBulkResponseDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
key: mapValueOfType<String>(json, r'key')!,
@@ -45,6 +45,15 @@ class AssetMetadataBulkUpsertDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'items'), 'Required key "AssetMetadataBulkUpsertDto[items]" is missing from JSON.');
assert(json[r'items'] != null, 'Required key "AssetMetadataBulkUpsertDto[items]" has a null value in JSON.');
return true;
}());
return AssetMetadataBulkUpsertDto(
items: AssetMetadataBulkUpsertItemDto.listFromJson(json[r'items']),
);
@@ -59,6 +59,19 @@ class AssetMetadataBulkUpsertItemDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetMetadataBulkUpsertItemDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetMetadataBulkUpsertItemDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'key'), 'Required key "AssetMetadataBulkUpsertItemDto[key]" is missing from JSON.');
assert(json[r'key'] != null, 'Required key "AssetMetadataBulkUpsertItemDto[key]" has a null value in JSON.');
assert(json.containsKey(r'value'), 'Required key "AssetMetadataBulkUpsertItemDto[value]" is missing from JSON.');
assert(json[r'value'] != null, 'Required key "AssetMetadataBulkUpsertItemDto[value]" has a null value in JSON.');
return true;
}());
return AssetMetadataBulkUpsertItemDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
key: mapValueOfType<String>(json, r'key')!,
@@ -61,6 +61,19 @@ class AssetMetadataResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'key'), 'Required key "AssetMetadataResponseDto[key]" is missing from JSON.');
assert(json[r'key'] != null, 'Required key "AssetMetadataResponseDto[key]" has a null value in JSON.');
assert(json.containsKey(r'updatedAt'), 'Required key "AssetMetadataResponseDto[updatedAt]" is missing from JSON.');
assert(json[r'updatedAt'] != null, 'Required key "AssetMetadataResponseDto[updatedAt]" has a null value in JSON.');
assert(json.containsKey(r'value'), 'Required key "AssetMetadataResponseDto[value]" is missing from JSON.');
assert(json[r'value'] != null, 'Required key "AssetMetadataResponseDto[value]" has a null value in JSON.');
return true;
}());
return AssetMetadataResponseDto(
key: mapValueOfType<String>(json, r'key')!,
updatedAt: mapDateTime(json, r'updatedAt', r'/^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$/')!,
+9
View File
@@ -45,6 +45,15 @@ class AssetMetadataUpsertDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'items'), 'Required key "AssetMetadataUpsertDto[items]" is missing from JSON.');
assert(json[r'items'] != null, 'Required key "AssetMetadataUpsertDto[items]" has a null value in JSON.');
return true;
}());
return AssetMetadataUpsertDto(
items: AssetMetadataUpsertItemDto.listFromJson(json[r'items']),
);
@@ -52,6 +52,17 @@ class AssetMetadataUpsertItemDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'key'), 'Required key "AssetMetadataUpsertItemDto[key]" is missing from JSON.');
assert(json[r'key'] != null, 'Required key "AssetMetadataUpsertItemDto[key]" has a null value in JSON.');
assert(json.containsKey(r'value'), 'Required key "AssetMetadataUpsertItemDto[value]" is missing from JSON.');
assert(json[r'value'] != null, 'Required key "AssetMetadataUpsertItemDto[value]" has a null value in JSON.');
return true;
}());
return AssetMetadataUpsertItemDto(
key: mapValueOfType<String>(json, r'key')!,
value: mapCastOfType<String, Object>(json, r'value')!,
+43 -10
View File
@@ -127,20 +127,53 @@ class AssetOcrResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetId'), 'Required key "AssetOcrResponseDto[assetId]" is missing from JSON.');
assert(json[r'assetId'] != null, 'Required key "AssetOcrResponseDto[assetId]" has a null value in JSON.');
assert(json.containsKey(r'boxScore'), 'Required key "AssetOcrResponseDto[boxScore]" is missing from JSON.');
assert(json[r'boxScore'] != null, 'Required key "AssetOcrResponseDto[boxScore]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetOcrResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetOcrResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'text'), 'Required key "AssetOcrResponseDto[text]" is missing from JSON.');
assert(json[r'text'] != null, 'Required key "AssetOcrResponseDto[text]" has a null value in JSON.');
assert(json.containsKey(r'textScore'), 'Required key "AssetOcrResponseDto[textScore]" is missing from JSON.');
assert(json[r'textScore'] != null, 'Required key "AssetOcrResponseDto[textScore]" has a null value in JSON.');
assert(json.containsKey(r'x1'), 'Required key "AssetOcrResponseDto[x1]" is missing from JSON.');
assert(json[r'x1'] != null, 'Required key "AssetOcrResponseDto[x1]" has a null value in JSON.');
assert(json.containsKey(r'x2'), 'Required key "AssetOcrResponseDto[x2]" is missing from JSON.');
assert(json[r'x2'] != null, 'Required key "AssetOcrResponseDto[x2]" has a null value in JSON.');
assert(json.containsKey(r'x3'), 'Required key "AssetOcrResponseDto[x3]" is missing from JSON.');
assert(json[r'x3'] != null, 'Required key "AssetOcrResponseDto[x3]" has a null value in JSON.');
assert(json.containsKey(r'x4'), 'Required key "AssetOcrResponseDto[x4]" is missing from JSON.');
assert(json[r'x4'] != null, 'Required key "AssetOcrResponseDto[x4]" has a null value in JSON.');
assert(json.containsKey(r'y1'), 'Required key "AssetOcrResponseDto[y1]" is missing from JSON.');
assert(json[r'y1'] != null, 'Required key "AssetOcrResponseDto[y1]" has a null value in JSON.');
assert(json.containsKey(r'y2'), 'Required key "AssetOcrResponseDto[y2]" is missing from JSON.');
assert(json[r'y2'] != null, 'Required key "AssetOcrResponseDto[y2]" has a null value in JSON.');
assert(json.containsKey(r'y3'), 'Required key "AssetOcrResponseDto[y3]" is missing from JSON.');
assert(json[r'y3'] != null, 'Required key "AssetOcrResponseDto[y3]" has a null value in JSON.');
assert(json.containsKey(r'y4'), 'Required key "AssetOcrResponseDto[y4]" is missing from JSON.');
assert(json[r'y4'] != null, 'Required key "AssetOcrResponseDto[y4]" has a null value in JSON.');
return true;
}());
return AssetOcrResponseDto(
assetId: mapValueOfType<String>(json, r'assetId')!,
boxScore: (mapValueOfType<num>(json, r'boxScore')!).toDouble(),
boxScore: mapValueOfType<double>(json, r'boxScore')!,
id: mapValueOfType<String>(json, r'id')!,
text: mapValueOfType<String>(json, r'text')!,
textScore: (mapValueOfType<num>(json, r'textScore')!).toDouble(),
x1: (mapValueOfType<num>(json, r'x1')!).toDouble(),
x2: (mapValueOfType<num>(json, r'x2')!).toDouble(),
x3: (mapValueOfType<num>(json, r'x3')!).toDouble(),
x4: (mapValueOfType<num>(json, r'x4')!).toDouble(),
y1: (mapValueOfType<num>(json, r'y1')!).toDouble(),
y2: (mapValueOfType<num>(json, r'y2')!).toDouble(),
y3: (mapValueOfType<num>(json, r'y3')!).toDouble(),
y4: (mapValueOfType<num>(json, r'y4')!).toDouble(),
textScore: mapValueOfType<double>(json, r'textScore')!,
x1: mapValueOfType<double>(json, r'x1')!,
x2: mapValueOfType<double>(json, r'x2')!,
x3: mapValueOfType<double>(json, r'x3')!,
x4: mapValueOfType<double>(json, r'x4')!,
y1: mapValueOfType<double>(json, r'y1')!,
y2: mapValueOfType<double>(json, r'y2')!,
y3: mapValueOfType<double>(json, r'y3')!,
y4: mapValueOfType<double>(json, r'y4')!,
);
}
return null;
+113 -68
View File
@@ -15,9 +15,9 @@ class AssetResponseDto {
AssetResponseDto({
required this.checksum,
required this.createdAt,
this.duplicateId,
this.duplicateId = const Optional.absent(),
required this.duration,
this.exifInfo,
this.exifInfo = const Optional.absent(),
required this.fileCreatedAt,
required this.fileModifiedAt,
required this.hasMetadata,
@@ -28,18 +28,18 @@ class AssetResponseDto {
required this.isFavorite,
required this.isOffline,
required this.isTrashed,
this.libraryId,
this.livePhotoVideoId,
this.libraryId = const Optional.absent(),
this.livePhotoVideoId = const Optional.absent(),
required this.localDateTime,
required this.originalFileName,
this.originalMimeType,
this.originalMimeType = const Optional.absent(),
required this.originalPath,
this.owner,
this.owner = const Optional.absent(),
required this.ownerId,
this.people = const [],
this.resized,
this.stack,
this.tags = const [],
this.people = const Optional.present(const []),
this.resized = const Optional.absent(),
this.stack = const Optional.absent(),
this.tags = const Optional.present(const []),
required this.thumbhash,
required this.type,
required this.updatedAt,
@@ -54,7 +54,7 @@ class AssetResponseDto {
DateTime createdAt;
/// Duplicate group ID
String? duplicateId;
Optional<String?> duplicateId;
/// Video/gif duration in milliseconds (null for static images)
///
@@ -68,7 +68,7 @@ class AssetResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
ExifResponseDto? exifInfo;
Optional<ExifResponseDto?> exifInfo;
/// The actual UTC timestamp when the file was created/captured, preserving timezone information. This is the authoritative timestamp for chronological sorting within timeline groups. Combined with timezone data, this can be used to determine the exact moment the photo was taken.
DateTime fileCreatedAt;
@@ -104,10 +104,10 @@ class AssetResponseDto {
bool isTrashed;
/// Library ID
String? libraryId;
Optional<String?> libraryId;
/// Live photo video ID
String? livePhotoVideoId;
Optional<String?> livePhotoVideoId;
/// The local date and time when the photo/video was taken, derived from EXIF metadata. This represents the photographer's local time regardless of timezone, stored as a timezone-agnostic timestamp. Used for timeline grouping by \"local\" days and months.
DateTime localDateTime;
@@ -122,7 +122,7 @@ class AssetResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? originalMimeType;
Optional<String?> originalMimeType;
/// Original file path
String originalPath;
@@ -133,12 +133,12 @@ class AssetResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
UserResponseDto? owner;
Optional<UserResponseDto?> owner;
/// Owner user ID
String ownerId;
List<PersonResponseDto> people;
Optional<List<PersonResponseDto>?> people;
/// Is resized
///
@@ -147,11 +147,11 @@ class AssetResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
bool? resized;
Optional<bool?> resized;
AssetStackResponseDto? stack;
Optional<AssetStackResponseDto?> stack;
List<TagResponseDto> tags;
Optional<List<TagResponseDto>?> tags;
/// Thumbhash for thumbnail generation (base64) also used as the c query param for thumbnail cache busting.
String? thumbhash;
@@ -247,20 +247,18 @@ class AssetResponseDto {
final json = <String, dynamic>{};
json[r'checksum'] = this.checksum;
json[r'createdAt'] = this.createdAt.toUtc().toIso8601String();
if (this.duplicateId != null) {
json[r'duplicateId'] = this.duplicateId;
} else {
// json[r'duplicateId'] = null;
if (this.duplicateId.isPresent) {
final value = this.duplicateId.value;
json[r'duplicateId'] = value;
}
if (this.duration != null) {
json[r'duration'] = this.duration;
} else {
// json[r'duration'] = null;
json[r'duration'] = null;
}
if (this.exifInfo != null) {
json[r'exifInfo'] = this.exifInfo;
} else {
// json[r'exifInfo'] = null;
if (this.exifInfo.isPresent) {
final value = this.exifInfo.value;
json[r'exifInfo'] = value;
}
json[r'fileCreatedAt'] = this.fileCreatedAt.toUtc().toIso8601String();
json[r'fileModifiedAt'] = this.fileModifiedAt.toUtc().toIso8601String();
@@ -268,7 +266,7 @@ class AssetResponseDto {
if (this.height != null) {
json[r'height'] = this.height;
} else {
// json[r'height'] = null;
json[r'height'] = null;
}
json[r'id'] = this.id;
json[r'isArchived'] = this.isArchived;
@@ -276,46 +274,46 @@ class AssetResponseDto {
json[r'isFavorite'] = this.isFavorite;
json[r'isOffline'] = this.isOffline;
json[r'isTrashed'] = this.isTrashed;
if (this.libraryId != null) {
json[r'libraryId'] = this.libraryId;
} else {
// json[r'libraryId'] = null;
if (this.libraryId.isPresent) {
final value = this.libraryId.value;
json[r'libraryId'] = value;
}
if (this.livePhotoVideoId != null) {
json[r'livePhotoVideoId'] = this.livePhotoVideoId;
} else {
// json[r'livePhotoVideoId'] = null;
if (this.livePhotoVideoId.isPresent) {
final value = this.livePhotoVideoId.value;
json[r'livePhotoVideoId'] = value;
}
json[r'localDateTime'] = this.localDateTime.toUtc().toIso8601String();
json[r'originalFileName'] = this.originalFileName;
if (this.originalMimeType != null) {
json[r'originalMimeType'] = this.originalMimeType;
} else {
// json[r'originalMimeType'] = null;
if (this.originalMimeType.isPresent) {
final value = this.originalMimeType.value;
json[r'originalMimeType'] = value;
}
json[r'originalPath'] = this.originalPath;
if (this.owner != null) {
json[r'owner'] = this.owner;
} else {
// json[r'owner'] = null;
if (this.owner.isPresent) {
final value = this.owner.value;
json[r'owner'] = value;
}
json[r'ownerId'] = this.ownerId;
json[r'people'] = this.people;
if (this.resized != null) {
json[r'resized'] = this.resized;
} else {
// json[r'resized'] = null;
if (this.people.isPresent) {
final value = this.people.value;
json[r'people'] = value;
}
if (this.stack != null) {
json[r'stack'] = this.stack;
} else {
// json[r'stack'] = null;
if (this.resized.isPresent) {
final value = this.resized.value;
json[r'resized'] = value;
}
if (this.stack.isPresent) {
final value = this.stack.value;
json[r'stack'] = value;
}
if (this.tags.isPresent) {
final value = this.tags.value;
json[r'tags'] = value;
}
json[r'tags'] = this.tags;
if (this.thumbhash != null) {
json[r'thumbhash'] = this.thumbhash;
} else {
// json[r'thumbhash'] = null;
json[r'thumbhash'] = null;
}
json[r'type'] = this.type;
json[r'updatedAt'] = this.updatedAt.toUtc().toIso8601String();
@@ -323,7 +321,7 @@ class AssetResponseDto {
if (this.width != null) {
json[r'width'] = this.width;
} else {
// json[r'width'] = null;
json[r'width'] = null;
}
return json;
}
@@ -336,12 +334,59 @@ class AssetResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'checksum'), 'Required key "AssetResponseDto[checksum]" is missing from JSON.');
assert(json[r'checksum'] != null, 'Required key "AssetResponseDto[checksum]" has a null value in JSON.');
assert(json.containsKey(r'createdAt'), 'Required key "AssetResponseDto[createdAt]" is missing from JSON.');
assert(json[r'createdAt'] != null, 'Required key "AssetResponseDto[createdAt]" has a null value in JSON.');
assert(json.containsKey(r'duration'), 'Required key "AssetResponseDto[duration]" is missing from JSON.');
assert(json.containsKey(r'fileCreatedAt'), 'Required key "AssetResponseDto[fileCreatedAt]" is missing from JSON.');
assert(json[r'fileCreatedAt'] != null, 'Required key "AssetResponseDto[fileCreatedAt]" has a null value in JSON.');
assert(json.containsKey(r'fileModifiedAt'), 'Required key "AssetResponseDto[fileModifiedAt]" is missing from JSON.');
assert(json[r'fileModifiedAt'] != null, 'Required key "AssetResponseDto[fileModifiedAt]" has a null value in JSON.');
assert(json.containsKey(r'hasMetadata'), 'Required key "AssetResponseDto[hasMetadata]" is missing from JSON.');
assert(json[r'hasMetadata'] != null, 'Required key "AssetResponseDto[hasMetadata]" has a null value in JSON.');
assert(json.containsKey(r'height'), 'Required key "AssetResponseDto[height]" is missing from JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'isArchived'), 'Required key "AssetResponseDto[isArchived]" is missing from JSON.');
assert(json[r'isArchived'] != null, 'Required key "AssetResponseDto[isArchived]" has a null value in JSON.');
assert(json.containsKey(r'isEdited'), 'Required key "AssetResponseDto[isEdited]" is missing from JSON.');
assert(json[r'isEdited'] != null, 'Required key "AssetResponseDto[isEdited]" has a null value in JSON.');
assert(json.containsKey(r'isFavorite'), 'Required key "AssetResponseDto[isFavorite]" is missing from JSON.');
assert(json[r'isFavorite'] != null, 'Required key "AssetResponseDto[isFavorite]" has a null value in JSON.');
assert(json.containsKey(r'isOffline'), 'Required key "AssetResponseDto[isOffline]" is missing from JSON.');
assert(json[r'isOffline'] != null, 'Required key "AssetResponseDto[isOffline]" has a null value in JSON.');
assert(json.containsKey(r'isTrashed'), 'Required key "AssetResponseDto[isTrashed]" is missing from JSON.');
assert(json[r'isTrashed'] != null, 'Required key "AssetResponseDto[isTrashed]" has a null value in JSON.');
assert(json.containsKey(r'localDateTime'), 'Required key "AssetResponseDto[localDateTime]" is missing from JSON.');
assert(json[r'localDateTime'] != null, 'Required key "AssetResponseDto[localDateTime]" has a null value in JSON.');
assert(json.containsKey(r'originalFileName'), 'Required key "AssetResponseDto[originalFileName]" is missing from JSON.');
assert(json[r'originalFileName'] != null, 'Required key "AssetResponseDto[originalFileName]" has a null value in JSON.');
assert(json.containsKey(r'originalPath'), 'Required key "AssetResponseDto[originalPath]" is missing from JSON.');
assert(json[r'originalPath'] != null, 'Required key "AssetResponseDto[originalPath]" has a null value in JSON.');
assert(json.containsKey(r'ownerId'), 'Required key "AssetResponseDto[ownerId]" is missing from JSON.');
assert(json[r'ownerId'] != null, 'Required key "AssetResponseDto[ownerId]" has a null value in JSON.');
assert(json.containsKey(r'thumbhash'), 'Required key "AssetResponseDto[thumbhash]" is missing from JSON.');
assert(json.containsKey(r'type'), 'Required key "AssetResponseDto[type]" is missing from JSON.');
assert(json[r'type'] != null, 'Required key "AssetResponseDto[type]" has a null value in JSON.');
assert(json.containsKey(r'updatedAt'), 'Required key "AssetResponseDto[updatedAt]" is missing from JSON.');
assert(json[r'updatedAt'] != null, 'Required key "AssetResponseDto[updatedAt]" has a null value in JSON.');
assert(json.containsKey(r'visibility'), 'Required key "AssetResponseDto[visibility]" is missing from JSON.');
assert(json[r'visibility'] != null, 'Required key "AssetResponseDto[visibility]" has a null value in JSON.');
assert(json.containsKey(r'width'), 'Required key "AssetResponseDto[width]" is missing from JSON.');
return true;
}());
return AssetResponseDto(
checksum: mapValueOfType<String>(json, r'checksum')!,
createdAt: mapDateTime(json, r'createdAt', r'')!,
duplicateId: mapValueOfType<String>(json, r'duplicateId'),
duplicateId: json.containsKey(r'duplicateId') ? Optional.present(mapValueOfType<String>(json, r'duplicateId')) : const Optional.absent(),
duration: mapValueOfType<int>(json, r'duration'),
exifInfo: ExifResponseDto.fromJson(json[r'exifInfo']),
exifInfo: json.containsKey(r'exifInfo') ? Optional.present(ExifResponseDto.fromJson(json[r'exifInfo'])) : const Optional.absent(),
fileCreatedAt: mapDateTime(json, r'fileCreatedAt', r'')!,
fileModifiedAt: mapDateTime(json, r'fileModifiedAt', r'')!,
hasMetadata: mapValueOfType<bool>(json, r'hasMetadata')!,
@@ -352,18 +397,18 @@ class AssetResponseDto {
isFavorite: mapValueOfType<bool>(json, r'isFavorite')!,
isOffline: mapValueOfType<bool>(json, r'isOffline')!,
isTrashed: mapValueOfType<bool>(json, r'isTrashed')!,
libraryId: mapValueOfType<String>(json, r'libraryId'),
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
libraryId: json.containsKey(r'libraryId') ? Optional.present(mapValueOfType<String>(json, r'libraryId')) : const Optional.absent(),
livePhotoVideoId: json.containsKey(r'livePhotoVideoId') ? Optional.present(mapValueOfType<String>(json, r'livePhotoVideoId')) : const Optional.absent(),
localDateTime: mapDateTime(json, r'localDateTime', r'')!,
originalFileName: mapValueOfType<String>(json, r'originalFileName')!,
originalMimeType: mapValueOfType<String>(json, r'originalMimeType'),
originalMimeType: json.containsKey(r'originalMimeType') ? Optional.present(mapValueOfType<String>(json, r'originalMimeType')) : const Optional.absent(),
originalPath: mapValueOfType<String>(json, r'originalPath')!,
owner: UserResponseDto.fromJson(json[r'owner']),
owner: json.containsKey(r'owner') ? Optional.present(UserResponseDto.fromJson(json[r'owner'])) : const Optional.absent(),
ownerId: mapValueOfType<String>(json, r'ownerId')!,
people: PersonResponseDto.listFromJson(json[r'people']),
resized: mapValueOfType<bool>(json, r'resized'),
stack: AssetStackResponseDto.fromJson(json[r'stack']),
tags: TagResponseDto.listFromJson(json[r'tags']),
people: json.containsKey(r'people') ? Optional.present(PersonResponseDto.listFromJson(json[r'people'])) : const Optional.absent(),
resized: json.containsKey(r'resized') ? Optional.present(mapValueOfType<bool>(json, r'resized')) : const Optional.absent(),
stack: json.containsKey(r'stack') ? Optional.present(AssetStackResponseDto.fromJson(json[r'stack'])) : const Optional.absent(),
tags: json.containsKey(r'tags') ? Optional.present(TagResponseDto.listFromJson(json[r'tags'])) : const Optional.absent(),
thumbhash: mapValueOfType<String>(json, r'thumbhash'),
type: AssetTypeEnum.fromJson(json[r'type'])!,
updatedAt: mapDateTime(json, r'updatedAt', r'')!,
+13
View File
@@ -62,6 +62,19 @@ class AssetStackResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'assetCount'), 'Required key "AssetStackResponseDto[assetCount]" is missing from JSON.');
assert(json[r'assetCount'] != null, 'Required key "AssetStackResponseDto[assetCount]" has a null value in JSON.');
assert(json.containsKey(r'id'), 'Required key "AssetStackResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "AssetStackResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'primaryAssetId'), 'Required key "AssetStackResponseDto[primaryAssetId]" is missing from JSON.');
assert(json[r'primaryAssetId'] != null, 'Required key "AssetStackResponseDto[primaryAssetId]" has a null value in JSON.');
return true;
}());
return AssetStackResponseDto(
assetCount: mapValueOfType<int>(json, r'assetCount')!,
id: mapValueOfType<String>(json, r'id')!,
+13
View File
@@ -68,6 +68,19 @@ class AssetStatsResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'images'), 'Required key "AssetStatsResponseDto[images]" is missing from JSON.');
assert(json[r'images'] != null, 'Required key "AssetStatsResponseDto[images]" has a null value in JSON.');
assert(json.containsKey(r'total'), 'Required key "AssetStatsResponseDto[total]" is missing from JSON.');
assert(json[r'total'] != null, 'Required key "AssetStatsResponseDto[total]" has a null value in JSON.');
assert(json.containsKey(r'videos'), 'Required key "AssetStatsResponseDto[videos]" is missing from JSON.');
assert(json[r'videos'] != null, 'Required key "AssetStatsResponseDto[videos]" has a null value in JSON.');
return true;
}());
return AssetStatsResponseDto(
images: mapValueOfType<int>(json, r'images')!,
total: mapValueOfType<int>(json, r'total')!,
+25 -14
View File
@@ -13,11 +13,11 @@ part of openapi.api;
class AuthStatusResponseDto {
/// Returns a new [AuthStatusResponseDto] instance.
AuthStatusResponseDto({
this.expiresAt,
this.expiresAt = const Optional.absent(),
required this.isElevated,
required this.password,
required this.pinCode,
this.pinExpiresAt,
this.pinExpiresAt = const Optional.absent(),
});
/// Session expiration date
@@ -27,7 +27,7 @@ class AuthStatusResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? expiresAt;
Optional<String?> expiresAt;
/// Is elevated session
bool isElevated;
@@ -45,7 +45,7 @@ class AuthStatusResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? pinExpiresAt;
Optional<String?> pinExpiresAt;
@override
bool operator ==(Object other) => identical(this, other) || other is AuthStatusResponseDto &&
@@ -69,18 +69,16 @@ class AuthStatusResponseDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.expiresAt != null) {
json[r'expiresAt'] = this.expiresAt;
} else {
// json[r'expiresAt'] = null;
if (this.expiresAt.isPresent) {
final value = this.expiresAt.value;
json[r'expiresAt'] = value;
}
json[r'isElevated'] = this.isElevated;
json[r'password'] = this.password;
json[r'pinCode'] = this.pinCode;
if (this.pinExpiresAt != null) {
json[r'pinExpiresAt'] = this.pinExpiresAt;
} else {
// json[r'pinExpiresAt'] = null;
if (this.pinExpiresAt.isPresent) {
final value = this.pinExpiresAt.value;
json[r'pinExpiresAt'] = value;
}
return json;
}
@@ -93,12 +91,25 @@ class AuthStatusResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'isElevated'), 'Required key "AuthStatusResponseDto[isElevated]" is missing from JSON.');
assert(json[r'isElevated'] != null, 'Required key "AuthStatusResponseDto[isElevated]" has a null value in JSON.');
assert(json.containsKey(r'password'), 'Required key "AuthStatusResponseDto[password]" is missing from JSON.');
assert(json[r'password'] != null, 'Required key "AuthStatusResponseDto[password]" has a null value in JSON.');
assert(json.containsKey(r'pinCode'), 'Required key "AuthStatusResponseDto[pinCode]" is missing from JSON.');
assert(json[r'pinCode'] != null, 'Required key "AuthStatusResponseDto[pinCode]" has a null value in JSON.');
return true;
}());
return AuthStatusResponseDto(
expiresAt: mapValueOfType<String>(json, r'expiresAt'),
expiresAt: json.containsKey(r'expiresAt') ? Optional.present(mapValueOfType<String>(json, r'expiresAt')) : const Optional.absent(),
isElevated: mapValueOfType<bool>(json, r'isElevated')!,
password: mapValueOfType<bool>(json, r'password')!,
pinCode: mapValueOfType<bool>(json, r'pinCode')!,
pinExpiresAt: mapValueOfType<String>(json, r'pinExpiresAt'),
pinExpiresAt: json.containsKey(r'pinExpiresAt') ? Optional.present(mapValueOfType<String>(json, r'pinExpiresAt')) : const Optional.absent(),
);
}
return null;
+13 -7
View File
@@ -13,7 +13,7 @@ part of openapi.api;
class AvatarUpdate {
/// Returns a new [AvatarUpdate] instance.
AvatarUpdate({
this.color,
this.color = const Optional.absent(),
});
///
@@ -22,7 +22,7 @@ class AvatarUpdate {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
UserAvatarColor? color;
Optional<UserAvatarColor?> color;
@override
bool operator ==(Object other) => identical(this, other) || other is AvatarUpdate &&
@@ -38,10 +38,9 @@ class AvatarUpdate {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.color != null) {
json[r'color'] = this.color;
} else {
// json[r'color'] = null;
if (this.color.isPresent) {
final value = this.color.value;
json[r'color'] = value;
}
return json;
}
@@ -54,8 +53,15 @@ class AvatarUpdate {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
return true;
}());
return AvatarUpdate(
color: UserAvatarColor.fromJson(json[r'color']),
color: json.containsKey(r'color') ? Optional.present(UserAvatarColor.fromJson(json[r'color'])) : const Optional.absent(),
);
}
return null;
+23 -14
View File
@@ -13,8 +13,8 @@ part of openapi.api;
class BulkIdResponseDto {
/// Returns a new [BulkIdResponseDto] instance.
BulkIdResponseDto({
this.error,
this.errorMessage,
this.error = const Optional.absent(),
this.errorMessage = const Optional.absent(),
required this.id,
required this.success,
});
@@ -25,7 +25,7 @@ class BulkIdResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
BulkIdErrorReason? error;
Optional<BulkIdErrorReason?> error;
///
/// Please note: This property should have been non-nullable! Since the specification file
@@ -33,7 +33,7 @@ class BulkIdResponseDto {
/// source code must fall back to having a nullable type.
/// Consider adding a "default:" property in the specification file to hide this note.
///
String? errorMessage;
Optional<String?> errorMessage;
/// ID
String id;
@@ -61,15 +61,13 @@ class BulkIdResponseDto {
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.error != null) {
json[r'error'] = this.error;
} else {
// json[r'error'] = null;
if (this.error.isPresent) {
final value = this.error.value;
json[r'error'] = value;
}
if (this.errorMessage != null) {
json[r'errorMessage'] = this.errorMessage;
} else {
// json[r'errorMessage'] = null;
if (this.errorMessage.isPresent) {
final value = this.errorMessage.value;
json[r'errorMessage'] = value;
}
json[r'id'] = this.id;
json[r'success'] = this.success;
@@ -84,9 +82,20 @@ class BulkIdResponseDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'id'), 'Required key "BulkIdResponseDto[id]" is missing from JSON.');
assert(json[r'id'] != null, 'Required key "BulkIdResponseDto[id]" has a null value in JSON.');
assert(json.containsKey(r'success'), 'Required key "BulkIdResponseDto[success]" is missing from JSON.');
assert(json[r'success'] != null, 'Required key "BulkIdResponseDto[success]" has a null value in JSON.');
return true;
}());
return BulkIdResponseDto(
error: BulkIdErrorReason.fromJson(json[r'error']),
errorMessage: mapValueOfType<String>(json, r'errorMessage'),
error: json.containsKey(r'error') ? Optional.present(BulkIdErrorReason.fromJson(json[r'error'])) : const Optional.absent(),
errorMessage: json.containsKey(r'errorMessage') ? Optional.present(mapValueOfType<String>(json, r'errorMessage')) : const Optional.absent(),
id: mapValueOfType<String>(json, r'id')!,
success: mapValueOfType<bool>(json, r'success')!,
);
+9
View File
@@ -45,6 +45,15 @@ class BulkIdsDto {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'ids'), 'Required key "BulkIdsDto[ids]" is missing from JSON.');
assert(json[r'ids'] != null, 'Required key "BulkIdsDto[ids]" has a null value in JSON.');
return true;
}());
return BulkIdsDto(
ids: json[r'ids'] is Iterable
? (json[r'ids'] as Iterable).cast<String>().toList(growable: false)
+9
View File
@@ -45,6 +45,15 @@ class CastResponse {
if (value is Map) {
final json = value.cast<String, dynamic>();
// Ensure that the map contains the required keys.
// Note 1: the values aren't checked for validity beyond being non-null.
// Note 2: this code is stripped in release mode!
assert(() {
assert(json.containsKey(r'gCastEnabled'), 'Required key "CastResponse[gCastEnabled]" is missing from JSON.');
assert(json[r'gCastEnabled'] != null, 'Required key "CastResponse[gCastEnabled]" has a null value in JSON.');
return true;
}());
return CastResponse(
gCastEnabled: mapValueOfType<bool>(json, r'gCastEnabled')!,
);

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