💄 Optimize file viewer

This commit is contained in:
2025-07-30 00:29:26 +08:00
parent 97226ae96b
commit e4bb031138
3 changed files with 46 additions and 76 deletions

View File

@@ -122,7 +122,7 @@ class WebSocketService {
void _scheduleHeartbeat() { void _scheduleHeartbeat() {
_heartbeatTimer?.cancel(); _heartbeatTimer?.cancel();
_heartbeatTimer = Timer.periodic(const Duration(seconds: 3), (_) { _heartbeatTimer = Timer.periodic(const Duration(seconds: 60), (_) {
_beatTheHeart(); _beatTheHeart();
}); });
} }

View File

@@ -30,7 +30,7 @@ class CloudFileList extends HookConsumerWidget {
const CloudFileList({ const CloudFileList({
super.key, super.key,
required this.files, required this.files,
this.maxHeight = 360, this.maxHeight = 560,
this.maxWidth = double.infinity, this.maxWidth = double.infinity,
this.minWidth, this.minWidth,
this.disableZoomIn = false, this.disableZoomIn = false,
@@ -98,53 +98,8 @@ class CloudFileList extends HookConsumerWidget {
).padding(horizontal: 3); ).padding(horizontal: 3);
} }
final allImages =
!files.any(
(e) => e.mimeType == null || !e.mimeType!.startsWith('image'),
);
if (allImages) {
return ConstrainedBox(
constraints: BoxConstraints(maxHeight: maxHeight, minWidth: maxWidth),
child: AspectRatio(
aspectRatio: calculateAspectRatio(),
child: CarouselView(
itemExtent: math.min(
MediaQuery.of(context).size.width * 0.85,
maxWidth * 0.85,
),
itemSnapping: true,
shape: RoundedRectangleBorder(
borderRadius: const BorderRadius.all(Radius.circular(16)),
),
children: [
for (var i = 0; i < files.length; i++)
_CloudFileListEntry(
file: files[i],
heroTag: heroTags[i],
isImage: files[i].mimeType?.startsWith('image') ?? false,
disableZoomIn: disableZoomIn,
fit: BoxFit.cover,
),
],
onTap: (i) {
if (!(files[i].mimeType?.startsWith('image') ?? false)) {
return;
}
if (!disableZoomIn) {
context.pushTransparentRoute(
CloudFileZoomIn(item: files[i], heroTag: heroTags[i]),
rootNavigator: true,
);
}
},
),
),
);
}
return ConstrainedBox( return ConstrainedBox(
constraints: BoxConstraints(maxHeight: maxHeight, minWidth: maxWidth), constraints: BoxConstraints(maxHeight: maxHeight),
child: AspectRatio( child: AspectRatio(
aspectRatio: calculateAspectRatio(), aspectRatio: calculateAspectRatio(),
child: ListView.separated( child: ListView.separated(
@@ -152,26 +107,49 @@ class CloudFileList extends HookConsumerWidget {
itemCount: files.length, itemCount: files.length,
padding: EdgeInsets.symmetric(horizontal: 3), padding: EdgeInsets.symmetric(horizontal: 3),
itemBuilder: (context, index) { itemBuilder: (context, index) {
return ClipRRect( return AspectRatio(
borderRadius: const BorderRadius.all(Radius.circular(16)), aspectRatio:
child: _CloudFileListEntry( files[index].fileMeta?['ratio'] is num
file: files[index], ? files[index].fileMeta!['ratio'].toDouble()
heroTag: heroTags[index], : 1.0,
isImage: files[index].mimeType?.startsWith('image') ?? false, child: Stack(
disableZoomIn: disableZoomIn, children: [
onTap: () { ClipRRect(
if (!(files[index].mimeType?.startsWith('image') ?? false)) { borderRadius: const BorderRadius.all(Radius.circular(16)),
return; child: _CloudFileListEntry(
} file: files[index],
if (!disableZoomIn) { heroTag: heroTags[index],
context.pushTransparentRoute( isImage:
CloudFileZoomIn( files[index].mimeType?.startsWith('image') ?? false,
item: files[index], disableZoomIn: disableZoomIn,
heroTag: heroTags[index], onTap: () {
), if (!(files[index].mimeType?.startsWith('image') ??
); false)) {
} return;
}, }
if (!disableZoomIn) {
context.pushTransparentRoute(
CloudFileZoomIn(
item: files[index],
heroTag: heroTags[index],
),
);
}
},
),
),
Positioned(
bottom: 12,
left: 16,
child: Text('${index + 1}/${files.length}')
.textColor(Colors.white)
.textShadow(
color: Colors.black54,
offset: Offset(1, 1),
blurRadius: 3,
),
),
],
), ),
); );
}, },

View File

@@ -174,10 +174,6 @@ class PostItem extends HookConsumerWidget {
MediaQuery.of(context).size.width, MediaQuery.of(context).size.width,
kWideScreenWidth, kWideScreenWidth,
), ),
minWidth: math.min(
MediaQuery.of(context).size.width,
kWideScreenWidth,
),
), ),
if (item.meta?['embeds'] != null) if (item.meta?['embeds'] != null)
...((item.meta!['embeds'] as List<dynamic>) ...((item.meta!['embeds'] as List<dynamic>)
@@ -410,10 +406,6 @@ class PostItem extends HookConsumerWidget {
MediaQuery.of(context).size.width * 0.85, MediaQuery.of(context).size.width * 0.85,
kWideScreenWidth - 160, kWideScreenWidth - 160,
), ),
minWidth: math.min(
MediaQuery.of(context).size.width * 0.9,
kWideScreenWidth - 160,
),
), ),
// Render embed links // Render embed links
if (item.meta?['embeds'] != null) if (item.meta?['embeds'] != null)