💄 Optimize file detail view styling

This commit is contained in:
2025-11-18 00:32:26 +08:00
parent 0303ef4a93
commit 94adecafbb
3 changed files with 89 additions and 98 deletions

View File

@@ -76,7 +76,7 @@ class FileDetailScreen extends HookConsumerWidget {
}, [animationController]); }, [animationController]);
return AppScaffold( return AppScaffold(
isNoBackground: true, isNoBackground: false,
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
leading: IconButton( leading: IconButton(
@@ -86,26 +86,47 @@ class FileDetailScreen extends HookConsumerWidget {
title: Text(item.name.isEmpty ? 'File Details' : item.name), title: Text(item.name.isEmpty ? 'File Details' : item.name),
actions: _buildAppBarActions(context, ref, showInfoSheet), actions: _buildAppBarActions(context, ref, showInfoSheet),
), ),
body: AnimatedBuilder( body: LayoutBuilder(
animation: animation, builder: (context, constraints) {
builder: (context, child) { return AnimatedBuilder(
return Row( animation: animation,
children: [ builder: (context, child) {
// Main content area return Stack(
Expanded(child: _buildContent(context, ref, serverUrl)), children: [
// Animated drawer panel // Main content area - resizes with animation
if (isWide) Positioned(
SizedBox( left: 0,
height: double.infinity, top: 0,
width: animation.value * 400, // Max width of 400px bottom: 0,
child: Container( width: constraints.maxWidth - animation.value * 400,
child: child: _buildContent(context, ref, serverUrl),
animation.value > 0.1
? FileInfoSheet(item: item, onClose: showInfoSheet)
: const SizedBox.shrink(),
), ),
), // Animated drawer panel - overlays
], if (isWide)
Positioned(
right: 0,
top: 0,
bottom: 0,
width: 400,
child: Transform.translate(
offset: Offset((1 - animation.value) * 400, 0),
child: SizedBox(
width: 400,
child: Material(
color:
Theme.of(context).colorScheme.surfaceContainer,
elevation: 8,
child: FileInfoSheet(
item: item,
onClose: showInfoSheet,
),
),
),
),
),
],
);
},
); );
}, },
), ),

View File

@@ -1,7 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'dart:math' as math; import 'dart:math' as math;
import 'dart:ui';
import 'package:easy_localization/easy_localization.dart';
import 'package:file_saver/file_saver.dart'; import 'package:file_saver/file_saver.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
@@ -266,68 +266,57 @@ class GenericFileContent extends HookConsumerWidget {
} }
return Center( return Center(
child: Container( child: Column(
margin: const EdgeInsets.all(32), mainAxisSize: MainAxisSize.min,
padding: const EdgeInsets.all(32), children: [
decoration: BoxDecoration( Icon(
border: Border.all( Symbols.insert_drive_file,
color: Theme.of(context).colorScheme.outline, size: 64,
width: 1, color: Theme.of(context).colorScheme.onSurfaceVariant,
), ),
borderRadius: BorderRadius.circular(16), const Gap(16),
), Text(
child: Column( item.name,
mainAxisSize: MainAxisSize.min, style: TextStyle(
children: [ fontSize: 20,
Icon( fontWeight: FontWeight.bold,
Symbols.insert_drive_file, color: Theme.of(context).colorScheme.onSurface,
size: 64, ),
textAlign: TextAlign.center,
),
const Gap(8),
Text(
formatFileSize(item.size),
style: TextStyle(
fontSize: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant, color: Theme.of(context).colorScheme.onSurfaceVariant,
), ),
const Gap(16), ),
Text( const Gap(24),
item.name, Row(
style: TextStyle( mainAxisSize: MainAxisSize.min,
fontSize: 20, children: [
fontWeight: FontWeight.bold, FilledButton.icon(
color: Theme.of(context).colorScheme.onSurface, onPressed: downloadFile,
icon: const Icon(Symbols.download),
label: Text('download').tr(),
), ),
textAlign: TextAlign.center, const Gap(16),
), OutlinedButton.icon(
const Gap(8), onPressed: () {
Text( showModalBottomSheet(
formatFileSize(item.size), useRootNavigator: true,
style: TextStyle( context: context,
fontSize: 16, isScrollControlled: true,
color: Theme.of(context).colorScheme.onSurfaceVariant, builder: (context) => FileInfoSheet(item: item),
);
},
icon: const Icon(Symbols.info),
label: Text('info').tr(),
), ),
), ],
const Gap(24), ),
Row( ],
mainAxisSize: MainAxisSize.min,
children: [
FilledButton.icon(
onPressed: downloadFile,
icon: const Icon(Symbols.download),
label: Text('download'),
),
const Gap(16),
OutlinedButton.icon(
onPressed: () {
showModalBottomSheet(
useRootNavigator: true,
context: context,
isScrollControlled: true,
builder: (context) => FileInfoSheet(item: item),
);
},
icon: const Icon(Symbols.info),
label: Text('info'),
),
],
),
],
),
), ),
); );
} }

View File

@@ -1,10 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:island/pods/network.dart';
import 'package:island/talker.dart';
import 'package:media_kit/media_kit.dart'; import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart'; import 'package:media_kit_video/media_kit_video.dart';
@@ -28,28 +25,12 @@ class _UniversalVideoState extends ConsumerState<UniversalVideo> {
VideoController? _videoController; VideoController? _videoController;
void _openVideo() async { void _openVideo() async {
final url = widget.uri;
MediaKit.ensureInitialized(); MediaKit.ensureInitialized();
_player = Player(); _player = Player();
_videoController = VideoController(_player!); _videoController = VideoController(_player!);
String? uri; _player!.open(Media(widget.uri), play: widget.autoplay);
final inCacheInfo = await DefaultCacheManager().getFileFromCache(url);
if (inCacheInfo == null) {
talker.info('[MediaPlayer] Miss cache: $url');
final token = ref.watch(tokenProvider)?.token;
DefaultCacheManager().downloadFile(
url,
authHeaders: {'Authorization': 'AtField $token'},
);
uri = url;
} else {
uri = inCacheInfo.file.path;
talker.info('[MediaPlayer] Hit cache: $url');
}
_player!.open(Media(uri), play: widget.autoplay);
} }
@override @override