delete image working
This commit is contained in:
@@ -550,6 +550,85 @@ class ImmichService {
|
||||
};
|
||||
}
|
||||
|
||||
/// Deletes assets from Immich.
|
||||
///
|
||||
/// [assetIds] - List of asset UUIDs to delete.
|
||||
///
|
||||
/// Throws [ImmichException] if deletion fails.
|
||||
Future<void> deleteAssets(List<String> assetIds) async {
|
||||
if (assetIds.isEmpty) {
|
||||
throw ImmichException('No asset IDs provided for deletion');
|
||||
}
|
||||
|
||||
try {
|
||||
debugPrint('=== Immich Delete Assets ===');
|
||||
debugPrint('Asset IDs to delete: $assetIds');
|
||||
debugPrint('Count: ${assetIds.length}');
|
||||
|
||||
// DELETE /api/assets with ids in request body
|
||||
// According to Immich API: DELETE /api/assets with body: {"ids": ["uuid1", "uuid2", ...]}
|
||||
final requestBody = {
|
||||
'ids': assetIds,
|
||||
};
|
||||
|
||||
debugPrint('Request body: $requestBody');
|
||||
|
||||
final response = await _dio.delete(
|
||||
'/api/assets',
|
||||
data: requestBody,
|
||||
options: Options(
|
||||
headers: {
|
||||
'x-api-key': _apiKey,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
debugPrint('=== Immich Delete Response ===');
|
||||
debugPrint('Status Code: ${response.statusCode}');
|
||||
debugPrint('Response Data: ${response.data}');
|
||||
|
||||
if (response.statusCode != 200 && response.statusCode != 204) {
|
||||
final errorMessage = response.data is Map
|
||||
? (response.data as Map)['message']?.toString() ??
|
||||
response.statusMessage
|
||||
: response.statusMessage;
|
||||
throw ImmichException(
|
||||
'Delete failed: $errorMessage',
|
||||
response.statusCode,
|
||||
);
|
||||
}
|
||||
|
||||
// Remove deleted assets from local cache
|
||||
for (final assetId in assetIds) {
|
||||
try {
|
||||
await _localStorage.deleteItem('immich_$assetId');
|
||||
} catch (e) {
|
||||
debugPrint('Warning: Failed to remove asset $assetId from cache: $e');
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('Successfully deleted ${assetIds.length} asset(s)');
|
||||
} on DioException catch (e) {
|
||||
final statusCode = e.response?.statusCode;
|
||||
final errorData = e.response?.data;
|
||||
String errorMessage;
|
||||
|
||||
if (errorData is Map) {
|
||||
errorMessage = errorData['message']?.toString() ?? errorData.toString();
|
||||
} else {
|
||||
errorMessage = errorData?.toString() ?? e.message ?? 'Unknown error';
|
||||
}
|
||||
|
||||
throw ImmichException(
|
||||
'Delete failed: $errorMessage',
|
||||
statusCode,
|
||||
);
|
||||
} catch (e) {
|
||||
throw ImmichException('Delete failed: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Tests the connection to Immich server by calling the /api/server/about endpoint.
|
||||
///
|
||||
/// Returns server information including version and status.
|
||||
|
||||
@@ -127,7 +127,8 @@ class NostrService {
|
||||
}
|
||||
|
||||
// WebSocketChannel.connect can throw synchronously (e.g., host lookup failure)
|
||||
// Wrap in try-catch to ensure it's caught
|
||||
// But errors can also occur asynchronously in the stream
|
||||
// Wrap in try-catch to ensure synchronous errors are caught
|
||||
WebSocketChannel channel;
|
||||
try {
|
||||
channel = WebSocketChannel.connect(Uri.parse(relayUrl));
|
||||
@@ -139,8 +140,8 @@ class NostrService {
|
||||
final controller = StreamController<Map<String, dynamic>>.broadcast();
|
||||
_messageControllers[relayUrl] = controller;
|
||||
|
||||
// Update relay status (relay already found above)
|
||||
relay.isConnected = true;
|
||||
// Don't set isConnected = true immediately - wait for actual connection
|
||||
// The connection might fail asynchronously
|
||||
|
||||
// Listen for messages
|
||||
channel.stream.listen(
|
||||
@@ -265,10 +266,53 @@ class NostrService {
|
||||
throw Exception('Connection timeout');
|
||||
},
|
||||
);
|
||||
// Start listening to establish connection, then cancel immediately
|
||||
final subscription = stream.listen(null);
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
||||
// Wait for connection to be established or fail
|
||||
// Listen to the stream to catch connection errors
|
||||
final completer = Completer<bool>();
|
||||
late StreamSubscription subscription;
|
||||
bool gotFirstMessage = false;
|
||||
|
||||
subscription = stream.listen(
|
||||
(data) {
|
||||
// Connection successful - we received data
|
||||
gotFirstMessage = true;
|
||||
if (!completer.isCompleted) {
|
||||
completer.complete(true);
|
||||
}
|
||||
},
|
||||
onError: (error) {
|
||||
// Connection failed
|
||||
if (!completer.isCompleted) {
|
||||
completer.complete(false);
|
||||
}
|
||||
},
|
||||
onDone: () {
|
||||
// Stream closed before connection established
|
||||
if (!completer.isCompleted) {
|
||||
completer.complete(false);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Wait for connection to establish (first message) or fail
|
||||
// Give it a short timeout to see if connection succeeds
|
||||
final connected = await completer.future.timeout(
|
||||
const Duration(seconds: 2),
|
||||
onTimeout: () {
|
||||
subscription.cancel();
|
||||
// If we got a first message, connection was established
|
||||
return gotFirstMessage;
|
||||
},
|
||||
);
|
||||
|
||||
subscription.cancel();
|
||||
|
||||
// Check if relay is actually connected
|
||||
if (!connected || !relay.isConnected) {
|
||||
results[relay.url] = false;
|
||||
continue;
|
||||
}
|
||||
} catch (e) {
|
||||
results[relay.url] = false;
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user