Fix document preview modal UI and gestures

This commit is contained in:
ssbg04 committed 2026-07-02 20:35:27 +08:00
1 parent 3b7561daaf
commit ced6ca57c4
4 files changed
+15 -72

No files matched your search

@@ -1863,12 +1863,9 @@ class _DocumentsScreenState extends ConsumerState<DocumentsScreen>
itemBuilder: (ctx, i) {
final folder = paginatedFolders[i];
return GestureDetector(
onSecondaryTapDown: defaultTargetPlatform == TargetPlatform.windows ? (details) => _showFolderContextMenu(context, details.globalPosition, folder) : null,
onLongPressStart: (details) => _showFolderContextMenu(context, details.globalPosition, folder),
onSecondaryTapDown: (details) => _showFolderContextMenu(context, details.globalPosition, folder),
child: InkWell(
onLongPress: defaultTargetPlatform == TargetPlatform.android ? () {
final box = ctx.findRenderObject() as RenderBox;
_showFolderContextMenu(context, box.localToGlobal(Offset.zero), folder);
} : null,
onTap: () {
if (folder.studentId != null) {
setState(() {
@@ -1982,12 +1979,9 @@ class _DocumentsScreenState extends ConsumerState<DocumentsScreen>
itemBuilder: (ctx, i) {
final folder = paginatedFolders[i];
return GestureDetector(
onSecondaryTapDown: defaultTargetPlatform == TargetPlatform.windows ? (details) => _showFolderContextMenu(context, details.globalPosition, folder) : null,
onLongPressStart: (details) => _showFolderContextMenu(context, details.globalPosition, folder),
onSecondaryTapDown: (details) => _showFolderContextMenu(context, details.globalPosition, folder),
child: InkWell(
onLongPress: defaultTargetPlatform == TargetPlatform.android ? () {
final box = ctx.findRenderObject() as RenderBox;
_showFolderContextMenu(context, box.localToGlobal(Offset.zero), folder);
} : null,
onTap: () {
if (folder.studentId != null) {
setState(() {
@@ -182,7 +182,7 @@ class _DocumentPreviewDialogState extends State<_DocumentPreviewDialog> {
headerActions: [
if (_isImage || _isPdf) ...[
IconButton(
icon: const Icon(Icons.zoom_out, color: AppColors.textSecondary, size: 22),
icon: const Icon(Icons.zoom_out, color: Colors.white, size: 22),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: _isImage ? _zoomImageOut : _zoomPdfOut,
@@ -190,7 +190,7 @@ class _DocumentPreviewDialogState extends State<_DocumentPreviewDialog> {
),
const SizedBox(width: 12),
IconButton(
icon: const Icon(Icons.zoom_in, color: AppColors.textSecondary, size: 22),
icon: const Icon(Icons.zoom_in, color: Colors.white, size: 22),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: _isImage ? _zoomImageIn : _zoomPdfIn,
@@ -199,15 +199,7 @@ class _DocumentPreviewDialogState extends State<_DocumentPreviewDialog> {
const SizedBox(width: 12),
],
],
content: SizedBox(
height: MediaQuery.of(context).size.height * 0.8,
child: Column(
children: [
Expanded(child: _buildContent(isMobile)),
_buildFooter(),
],
),
),
content: _buildContent(isMobile),
);
}
@@ -510,46 +502,7 @@ class _DocumentPreviewDialogState extends State<_DocumentPreviewDialog> {
);
}
// ── Footer metadata bar ───────────────────────────────────
Widget _buildFooter() {
if (widget.document == null) {
return const SizedBox.shrink(); // No footer for local files
}
final doc = widget.document!;
final studentLabel = doc.studentName ?? doc.studentLrn ?? '—';
final dateStr = _formatDate(doc.createdAt);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14),
decoration: BoxDecoration(
color: Colors.grey.shade50,
border: Border(
top: BorderSide(color: Colors.grey.shade200),
),
),
child: Row(
children: [
_footerChip(Icons.person_outline_rounded, studentLabel),
const SizedBox(width: 12),
if (doc.documentType != null)
_footerChip(Icons.label_outline_rounded, doc.documentType!),
const Spacer(),
_footerChip(Icons.calendar_today_outlined, dateStr),
],
),
);
}
Widget _footerChip(IconData icon, String label) => Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 14, color: AppColors.textSecondary),
const SizedBox(width: 6),
Text(label,
style:
const TextStyle(color: AppColors.textSecondary, fontSize: 12)),
],
);
String _formatDate(DateTime? date) {
if (date == null) return '—';
@@ -157,12 +157,9 @@ class FileFolderCard extends StatelessWidget {
// ════════════════════════════════════════
Widget _buildGridCard(BuildContext context) {
return GestureDetector(
onSecondaryTapDown: defaultTargetPlatform == TargetPlatform.windows ? (details) => _showContextMenu(context, details.globalPosition) : null,
onLongPressStart: (details) => _showContextMenu(context, details.globalPosition),
onSecondaryTapDown: (details) => _showContextMenu(context, details.globalPosition),
child: InkWell(
onLongPress: defaultTargetPlatform == TargetPlatform.android ? () {
final box = context.findRenderObject() as RenderBox;
_showContextMenu(context, box.localToGlobal(Offset.zero));
} : null,
onTap: isMultiSelectMode ? () => onSelectedChanged?.call(!isSelected) : onTap,
borderRadius: BorderRadius.circular(AppSizes.radiusLarge),
child: Container(
@@ -258,12 +255,9 @@ class FileFolderCard extends StatelessWidget {
// ════════════════════════════════════════
Widget _buildListRow(BuildContext context) {
return GestureDetector(
onSecondaryTapDown: defaultTargetPlatform == TargetPlatform.windows ? (details) => _showContextMenu(context, details.globalPosition) : null,
onLongPressStart: (details) => _showContextMenu(context, details.globalPosition),
onSecondaryTapDown: (details) => _showContextMenu(context, details.globalPosition),
child: InkWell(
onLongPress: defaultTargetPlatform == TargetPlatform.android ? () {
final box = context.findRenderObject() as RenderBox;
_showContextMenu(context, box.localToGlobal(Offset.zero));
} : null,
onTap: isMultiSelectMode ? () => onSelectedChanged?.call(!isSelected) : onTap,
child: Container(
color: isSelected ? AppColors.primaryGreen.withValues(alpha: 0.05) : null,
@@ -70,10 +70,12 @@ class CustomModal extends StatelessWidget {
Expanded(
child: Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 17,
fontWeight: FontWeight.bold,
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
),