added a swipeable media gallery for chat and folder images and videos with server previews, on-demand originals and zoom, and marked document previews in chat so they no longer pass for photos

This commit is contained in:
MineTec committed 2026-10-28 22:15:57 +01:00
1 parent 952f916231
commit aa176c90e3
22 files changed
+1658 -103

No files matched your search

@@ -10,14 +10,16 @@ import '../../../../api/marianumcloud/talk/get_shared_items/get_shared_items_res
import '../../../../api/marianumcloud/talk/room/get_room_response.dart';
import '../../../../extensions/date_time.dart';
import '../../../../model/endpoint_data.dart';
import '../../../../routing/app_routes.dart';
import '../../../../session/session_manager.dart';
import '../../../../share_intent/remote_file_ref.dart';
import '../../../../utils/downloads/download_job.dart';
import '../../../../widget/app_progress_indicator.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/downloads/download_trigger.dart';
import '../data/talk_gallery_source.dart';
const int _sharedItemsPageSize = 20;
const int sharedItemsPageSize = 20;
/// The non-media shared-item categories Talk exposes, in tab order. `media` is
/// handled separately (split into Bilder/Videos). `location`/`deckcard` are rich
@@ -64,7 +66,7 @@ SharedItemsPage buildSharedItemsPage(
) {
final lastGiven = response.lastGivenMessageId;
final hasMore =
response.items.length >= _sharedItemsPageSize &&
response.items.length >= sharedItemsPageSize &&
lastGiven != null &&
lastGiven != previousMessageId;
return SharedItemsPage(
@@ -79,7 +81,7 @@ SharedItemsPage buildSharedItemsPage(
/// its `X-Chat-Last-Given` header. [hasMore] is a heuristic — a full page from
/// the overview means there are probably older items to fetch on scroll.
SharedItemsPage _seedFromOverview(List<GetChatResponseObject> rawItems) {
final hasMore = rawItems.length >= _sharedItemsPageSize;
final hasMore = rawItems.length >= sharedItemsPageSize;
final oldestId = rawItems.isEmpty
? null
: rawItems.map((item) => item.id).reduce((a, b) => a < b ? a : b);
@@ -106,7 +108,7 @@ class SharedItemsView extends StatefulWidget {
/// screen, so opening this view needs no round-trip.
static Future<GetSharedItemsOverviewResponse> prefetchOverview(
String token,
) => GetSharedItemsOverview(token, limit: _sharedItemsPageSize).run();
) => GetSharedItemsOverview(token, limit: sharedItemsPageSize).run();
@override
State<SharedItemsView> createState() => _SharedItemsViewState();
@@ -362,7 +364,7 @@ class _SharedItemsTabState extends State<_SharedItemsTab>
final response = await GetSharedItems(
widget.token,
objectType: widget.objectType,
limit: _sharedItemsPageSize,
limit: sharedItemsPageSize,
lastKnownMessageId: _lastKnownMessageId,
).run();
if (!mounted) return;
@@ -445,6 +447,7 @@ class _SharedItemsTabState extends State<_SharedItemsTab>
),
delegate: SliverChildBuilderDelegate(
(context, index) => _SharedItemTile(
token: widget.token,
item: _items[index],
layout: _SharedItemsLayout.grid,
),
@@ -456,6 +459,7 @@ class _SharedItemsTabState extends State<_SharedItemsTab>
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => _SharedItemTile(
token: widget.token,
item: _items[index],
layout: _SharedItemsLayout.list,
),
@@ -470,10 +474,15 @@ class _SharedItemsTabState extends State<_SharedItemsTab>
}
class _SharedItemTile extends StatefulWidget {
final String token;
final GetChatResponseObject item;
final _SharedItemsLayout layout;
const _SharedItemTile({required this.item, required this.layout});
const _SharedItemTile({
required this.token,
required this.item,
required this.layout,
});
@override
State<_SharedItemTile> createState() => _SharedItemTileState();
@@ -502,12 +511,18 @@ class _SharedItemTileState extends State<_SharedItemTile>
if (guardDemoAction(context)) return;
if (isDownloading) {
confirmCancelDownload();
} else {
startDownload(
name: _file.name,
remoteFile: RemoteFileRef.fromTalk(_file),
);
return;
}
final galleryItem = galleryItemFromTalk(widget.item);
if (galleryItem != null) {
AppRoutes.openMediaGallery(
context,
source: TalkGallerySource(token: widget.token, initial: galleryItem),
initialKey: galleryItem.key,
);
return;
}
startDownload(name: _file.name, remoteFile: RemoteFileRef.fromTalk(_file));
}
String get _previewUrl =>