diff --git a/lib/models/attachment.dart b/lib/models/attachment.dart index 61b7e13..f4c7dc3 100644 --- a/lib/models/attachment.dart +++ b/lib/models/attachment.dart @@ -12,7 +12,8 @@ class Attachment { String usage; String mimetype; String hash; - String destination; + int destination; + bool isAnalyzed; Map? metadata; bool isMature; Account? account; @@ -31,6 +32,7 @@ class Attachment { required this.mimetype, required this.hash, required this.destination, + required this.isAnalyzed, required this.metadata, required this.isMature, required this.account, @@ -50,6 +52,7 @@ class Attachment { mimetype: json['mimetype'], hash: json['hash'], destination: json['destination'], + isAnalyzed: json['is_analyzed'], metadata: json['metadata'], isMature: json['is_mature'], account: json['account'] != null ? Account.fromJson(json['account']) : null, @@ -69,6 +72,7 @@ class Attachment { 'mimetype': mimetype, 'hash': hash, 'destination': destination, + 'is_analyzed': isAnalyzed, 'metadata': metadata, 'is_mature': isMature, 'account': account?.toJson(), diff --git a/lib/providers/content/attachment.dart b/lib/providers/content/attachment.dart index e046954..2c278f0 100644 --- a/lib/providers/content/attachment.dart +++ b/lib/providers/content/attachment.dart @@ -6,6 +6,7 @@ import 'dart:typed_data'; import 'package:crypto/crypto.dart'; import 'package:get/get.dart'; import 'package:path/path.dart'; +import 'package:solian/models/attachment.dart'; import 'package:solian/platform.dart'; import 'package:solian/providers/auth.dart'; import 'package:solian/services.dart'; @@ -65,17 +66,24 @@ class AttachmentProvider extends GetConnect { httpClient.baseUrl = ServiceFinder.buildUrl('files', null); } - final Map _cachedResponses = {}; + final Map _cachedResponses = {}; - Future getMetadata(int id, {noCache = false}) async { + Future getMetadata(int id, {noCache = false}) async { if (!noCache && _cachedResponses.containsKey(id)) { return _cachedResponses[id]!; } final resp = await get('/attachments/$id/meta'); - _cachedResponses[id] = resp; + if (resp.statusCode == 200) { + final result = Attachment.fromJson(resp.body); + if (result.destination != 0 && result.isAnalyzed) { + _cachedResponses[id] = result; + } + print(result); + return result; + } - return resp; + return null; } Future createAttachment( diff --git a/lib/widgets/attachments/attachment_item.dart b/lib/widgets/attachments/attachment_item.dart index 0011e26..ac8ea02 100644 --- a/lib/widgets/attachments/attachment_item.dart +++ b/lib/widgets/attachments/attachment_item.dart @@ -1,5 +1,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; import 'package:get/get.dart'; import 'package:media_kit/media_kit.dart'; import 'package:media_kit_video/media_kit_video.dart'; @@ -83,7 +84,9 @@ class _AttachmentItemState extends State { onPressed: () { launchUrlString( ServiceFinder.buildUrl( - 'files', '/attachments/${widget.item.id}'), + 'files', + '/attachments/${widget.item.id}', + ), ); }, ), @@ -125,14 +128,27 @@ class _AttachmentItemImage extends StatelessWidget { if (PlatformInfo.canCacheImage) CachedNetworkImage( fit: fit, - imageUrl: - ServiceFinder.buildUrl('files', '/attachments/${item.id}'), - progressIndicatorBuilder: (context, url, downloadProgress) => - Center( - child: CircularProgressIndicator( - value: downloadProgress.progress, - ), + imageUrl: ServiceFinder.buildUrl( + 'files', + '/attachments/${item.id}', ), + progressIndicatorBuilder: (context, url, downloadProgress) { + return Center( + child: CircularProgressIndicator( + value: downloadProgress.progress, + ), + ); + }, + errorWidget: (context, url, error) { + return Material( + color: Theme.of(context).colorScheme.surface, + child: Center( + child: const Icon(Icons.close, size: 32) + .animate(onPlay: (e) => e.repeat(reverse: true)) + .fade(duration: 500.ms), + ), + ); + }, ) else Image.network( @@ -150,6 +166,16 @@ class _AttachmentItemImage extends StatelessWidget { ), ); }, + errorBuilder: (context, error, stackTrace) { + return Material( + color: Theme.of(context).colorScheme.surface, + child: Center( + child: const Icon(Icons.close, size: 32) + .animate(onPlay: (e) => e.repeat(reverse: true)) + .fade(duration: 500.ms), + ), + ); + }, ), if (showBadge && badge != null) Positioned( diff --git a/lib/widgets/attachments/attachment_list.dart b/lib/widgets/attachments/attachment_list.dart index 7f6bbca..beef923 100644 --- a/lib/widgets/attachments/attachment_list.dart +++ b/lib/widgets/attachments/attachment_list.dart @@ -4,6 +4,7 @@ import 'dart:ui'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:dismissible_page/dismissible_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; import 'package:get/get.dart'; import 'package:solian/models/attachment.dart'; import 'package:solian/widgets/attachments/attachment_item.dart'; @@ -43,7 +44,7 @@ class _AttachmentListState extends State { List _attachmentsMeta = List.empty(); - void getMetadataList() { + void _getMetadataList() { final AttachmentProvider provider = Get.find(); if (widget.attachmentsId.isEmpty) { @@ -56,8 +57,8 @@ class _AttachmentListState extends State { for (var idx = 0; idx < widget.attachmentsId.length; idx++) { provider.getMetadata(widget.attachmentsId[idx]).then((resp) { progress++; - if (resp.body != null) { - _attachmentsMeta[idx] = Attachment.fromJson(resp.body); + if (resp != null) { + _attachmentsMeta[idx] = resp; } if (progress == widget.attachmentsId.length) { calculateAspectRatio(); @@ -125,7 +126,7 @@ class _AttachmentListState extends State { @override void initState() { super.initState(); - getMetadataList(); + _getMetadataList(); } @override @@ -234,19 +235,13 @@ class AttachmentListEntry extends StatelessWidget { Widget build(BuildContext context) { if (item == null) { return Center( - child: Container( - constraints: const BoxConstraints(maxWidth: 280), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.close, - size: 32, - color: Theme.of(context).colorScheme.onSurface, - ), - ], - ), - ), + child: Icon( + Icons.close, + size: 32, + color: Theme.of(context).colorScheme.onSurface, + ) + .animate(onPlay: (e) => e.repeat(reverse: true)) + .fade(duration: 500.ms), ); } diff --git a/lib/widgets/attachments/attachment_publish.dart b/lib/widgets/attachments/attachment_publish.dart index 4bc24bb..394a0b4 100644 --- a/lib/widgets/attachments/attachment_publish.dart +++ b/lib/widgets/attachments/attachment_publish.dart @@ -226,7 +226,7 @@ class _AttachmentPublishPopupState extends State { for (var idx = 0; idx < widget.current.length; idx++) { provider.getMetadata(widget.current[idx]).then((resp) { progress++; - _attachments[idx] = Attachment.fromJson(resp.body); + _attachments[idx] = resp; if (progress == widget.current.length) { setState(() { _isBusy = false; diff --git a/pubspec.yaml b/pubspec.yaml index ffea993..7ecf9ad 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: solian description: "The Solar Network App" publish_to: "none" -version: 1.1.0+50 +version: 1.2.0 environment: sdk: ">=3.3.4 <4.0.0"