This commit is contained in:
		@@ -7,6 +7,7 @@ import 'package:flutter_cache_manager/flutter_cache_manager.dart';
 | 
			
		||||
import 'package:get/get.dart';
 | 
			
		||||
import 'package:pullex/pullex.dart';
 | 
			
		||||
import 'package:share_plus/share_plus.dart';
 | 
			
		||||
import 'package:timeago/timeago.dart' as timeago;
 | 
			
		||||
 | 
			
		||||
import 'package:f0ckapp/services/api.dart';
 | 
			
		||||
import 'package:f0ckapp/widgets/tagfooter.dart';
 | 
			
		||||
@@ -43,8 +44,8 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
 | 
			
		||||
  bool _isLoading = true;
 | 
			
		||||
  bool _itemNotFound = false;
 | 
			
		||||
  final Set<int> _readyItemIds = {};
 | 
			
		||||
  final Map<int, bool> _showFavoriteAnimation = {};
 | 
			
		||||
  final RxSet<int> _readyItemIds = <int>{}.obs;
 | 
			
		||||
  final Rxn<int> _animatingFavoriteId = Rxn<int>();
 | 
			
		||||
 | 
			
		||||
  final List<PopupMenuEntry<ShareAction>> _shareMenuItems = const [
 | 
			
		||||
    PopupMenuItem(
 | 
			
		||||
@@ -67,6 +68,7 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    timeago.setLocaleMessages('de', timeago.DeMessages());
 | 
			
		||||
    _loadInitialItem();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -139,7 +141,7 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
      _currentIndex.value = idx;
 | 
			
		||||
      final MediaItem item = mediaController.items[idx];
 | 
			
		||||
      if (item.mime.startsWith('image/') && !_readyItemIds.contains(item.id)) {
 | 
			
		||||
        setState(() => _readyItemIds.add(item.id));
 | 
			
		||||
        _readyItemIds.add(item.id);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -271,11 +273,10 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
      mediaController.items.refresh();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!mounted) return;
 | 
			
		||||
    setState(() => _showFavoriteAnimation[item.id] = true);
 | 
			
		||||
    _animatingFavoriteId.value = item.id;
 | 
			
		||||
    Future.delayed(const Duration(milliseconds: 700), () {
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        setState(() => _showFavoriteAnimation[item.id] = false);
 | 
			
		||||
      if (_animatingFavoriteId.value == item.id) {
 | 
			
		||||
        _animatingFavoriteId.value = null;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
@@ -284,18 +285,15 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
    Widget mediaWidget;
 | 
			
		||||
    final bool isFavorite =
 | 
			
		||||
        item.favorites?.any((f) => f.userId == authController.user.value?.id) ??
 | 
			
		||||
            false;
 | 
			
		||||
        false;
 | 
			
		||||
 | 
			
		||||
    if (item.mime.startsWith('image/')) {
 | 
			
		||||
      mediaWidget = GestureDetector(
 | 
			
		||||
        onDoubleTap: () => _handleFavoriteToggle(item, isFavorite),
 | 
			
		||||
        child: CachedNetworkImage(
 | 
			
		||||
          imageUrl: item.mediaUrl,
 | 
			
		||||
          fit: BoxFit.contain,
 | 
			
		||||
          placeholder: (context, url) =>
 | 
			
		||||
              const Center(child: CircularProgressIndicator()),
 | 
			
		||||
          errorWidget: (c, e, s) => const Icon(Icons.broken_image, size: 100),
 | 
			
		||||
        ),
 | 
			
		||||
      mediaWidget = CachedNetworkImage(
 | 
			
		||||
        imageUrl: item.mediaUrl,
 | 
			
		||||
        fit: BoxFit.contain,
 | 
			
		||||
        placeholder: (context, url) =>
 | 
			
		||||
            const Center(child: CircularProgressIndicator()),
 | 
			
		||||
        errorWidget: (c, e, s) => const Icon(Icons.broken_image, size: 100),
 | 
			
		||||
      );
 | 
			
		||||
    } else if (item.mime.startsWith('video/') ||
 | 
			
		||||
        item.mime.startsWith('audio/')) {
 | 
			
		||||
@@ -309,10 +307,9 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
        isActive: isActive,
 | 
			
		||||
        onInitialized: () {
 | 
			
		||||
          if (mounted && !_readyItemIds.contains(item.id)) {
 | 
			
		||||
            setState(() => _readyItemIds.add(item.id));
 | 
			
		||||
            _readyItemIds.add(item.id);
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        onDoubleTap: () => _handleFavoriteToggle(item, isFavorite),
 | 
			
		||||
      );
 | 
			
		||||
    } else {
 | 
			
		||||
      mediaWidget = const Icon(Icons.help_outline, size: 100);
 | 
			
		||||
@@ -323,187 +320,207 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> {
 | 
			
		||||
      child: Stack(
 | 
			
		||||
        alignment: Alignment.center,
 | 
			
		||||
        children: [
 | 
			
		||||
          mediaWidget,
 | 
			
		||||
          AnimatedOpacity(
 | 
			
		||||
            opacity: _showFavoriteAnimation[item.id] ?? false ? 1.0 : 0.0,
 | 
			
		||||
            duration: const Duration(milliseconds: 200),
 | 
			
		||||
            child: AnimatedScale(
 | 
			
		||||
              scale: _showFavoriteAnimation[item.id] ?? false ? 1.0 : 0.5,
 | 
			
		||||
              duration: const Duration(milliseconds: 400),
 | 
			
		||||
              curve: Curves.easeOutBack,
 | 
			
		||||
              child: Icon(
 | 
			
		||||
                isFavorite ? Icons.favorite : Icons.favorite_outline,
 | 
			
		||||
                color: Colors.red,
 | 
			
		||||
                size: 100,
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          GestureDetector(
 | 
			
		||||
            onDoubleTap: () => _handleFavoriteToggle(item, isFavorite),
 | 
			
		||||
            child: mediaWidget,
 | 
			
		||||
          ),
 | 
			
		||||
          Obx(() {
 | 
			
		||||
            final showAnimation = _animatingFavoriteId.value == item.id;
 | 
			
		||||
            return AnimatedOpacity(
 | 
			
		||||
              opacity: showAnimation ? 1.0 : 0.0,
 | 
			
		||||
              duration: const Duration(milliseconds: 200),
 | 
			
		||||
              child: AnimatedScale(
 | 
			
		||||
                scale: showAnimation ? 1.0 : 0.5,
 | 
			
		||||
                duration: const Duration(milliseconds: 400),
 | 
			
		||||
                curve: Curves.easeOutBack,
 | 
			
		||||
                child: Icon(
 | 
			
		||||
                  isFavorite ? Icons.favorite : Icons.favorite_outline,
 | 
			
		||||
                  color: Colors.red,
 | 
			
		||||
                  size: 100,
 | 
			
		||||
                ),
 | 
			
		||||
              ),
 | 
			
		||||
            );
 | 
			
		||||
          }),
 | 
			
		||||
        ],
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
  PreferredSizeWidget _buildAppBar(BuildContext context) {
 | 
			
		||||
    return AppBar(
 | 
			
		||||
      title: Obx(() {
 | 
			
		||||
        if (_isLoading) {
 | 
			
		||||
          return Text('Lade f0ck #${widget.initialId}...');
 | 
			
		||||
        }
 | 
			
		||||
        if (_itemNotFound ||
 | 
			
		||||
            mediaController.items.isEmpty ||
 | 
			
		||||
            _currentIndex.value >= mediaController.items.length) {
 | 
			
		||||
          return const Text('Fehler');
 | 
			
		||||
        }
 | 
			
		||||
        final MediaItem currentItem =
 | 
			
		||||
            mediaController.items[_currentIndex.value];
 | 
			
		||||
        return Text('f0ck #${currentItem.id}');
 | 
			
		||||
      }),
 | 
			
		||||
      actions: [
 | 
			
		||||
        Obx(() {
 | 
			
		||||
          final bool showActions =
 | 
			
		||||
              !_isLoading &&
 | 
			
		||||
              !_itemNotFound &&
 | 
			
		||||
              mediaController.items.isNotEmpty &&
 | 
			
		||||
              _currentIndex.value < mediaController.items.length;
 | 
			
		||||
 | 
			
		||||
          if (!showActions) {
 | 
			
		||||
            return const SizedBox.shrink();
 | 
			
		||||
          }
 | 
			
		||||
          final MediaItem currentItem =
 | 
			
		||||
              mediaController.items[_currentIndex.value];
 | 
			
		||||
          return Row(
 | 
			
		||||
            mainAxisSize: MainAxisSize.min,
 | 
			
		||||
            children: [
 | 
			
		||||
              IconButton(
 | 
			
		||||
                icon: const Icon(Icons.fullscreen),
 | 
			
		||||
                onPressed: () => _handleFullScreen(currentItem),
 | 
			
		||||
              ),
 | 
			
		||||
              IconButton(
 | 
			
		||||
                icon: const Icon(Icons.download),
 | 
			
		||||
                onPressed: () async => await _downloadMedia(currentItem),
 | 
			
		||||
              ),
 | 
			
		||||
              PopupMenuButton<ShareAction>(
 | 
			
		||||
                onSelected: (value) => _handleShareAction(value, currentItem),
 | 
			
		||||
                itemBuilder: (context) => _shareMenuItems,
 | 
			
		||||
                icon: const Icon(Icons.share),
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          );
 | 
			
		||||
        }),
 | 
			
		||||
        Builder(
 | 
			
		||||
          builder: (context) => IconButton(
 | 
			
		||||
            icon: const Icon(Icons.menu),
 | 
			
		||||
            onPressed: () => Scaffold.of(context).openEndDrawer(),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Widget _buildBody(BuildContext context) {
 | 
			
		||||
    if (_isLoading) {
 | 
			
		||||
      return Scaffold(
 | 
			
		||||
        appBar: AppBar(title: Text('Lade f0ck #${widget.initialId}...')),
 | 
			
		||||
        body: const Center(child: CircularProgressIndicator()),
 | 
			
		||||
      );
 | 
			
		||||
      return const Center(child: CircularProgressIndicator());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (_itemNotFound) {
 | 
			
		||||
      return Scaffold(
 | 
			
		||||
        appBar: AppBar(title: const Text('Fehler')),
 | 
			
		||||
        body: const Center(child: Text('f0ck nicht gefunden.')),
 | 
			
		||||
      );
 | 
			
		||||
      return const Center(child: Text('f0ck nicht gefunden.'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return Obx(() {
 | 
			
		||||
      if (mediaController.items.isEmpty ||
 | 
			
		||||
          _currentIndex.value >= mediaController.items.length) {
 | 
			
		||||
        return Scaffold(
 | 
			
		||||
          appBar: AppBar(title: const Text('Fehler')),
 | 
			
		||||
          body: const Center(child: Text('Keine Items zum Anzeigen.')),
 | 
			
		||||
        );
 | 
			
		||||
      if (mediaController.items.isEmpty) {
 | 
			
		||||
        return const Center(child: Text('Keine Items zum Anzeigen.'));
 | 
			
		||||
      }
 | 
			
		||||
      final MediaItem currentItem = mediaController.items[_currentIndex.value];
 | 
			
		||||
      return Scaffold(
 | 
			
		||||
        endDrawer: const EndDrawer(),
 | 
			
		||||
        endDrawerEnableOpenDragGesture:
 | 
			
		||||
            settingsController.drawerSwipeEnabled.value,
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
          title: Text('f0ck #${currentItem.id}'),
 | 
			
		||||
          actions: [
 | 
			
		||||
            IconButton(
 | 
			
		||||
              icon: const Icon(Icons.fullscreen),
 | 
			
		||||
              onPressed: () => _handleFullScreen(currentItem),
 | 
			
		||||
            ),
 | 
			
		||||
            IconButton(
 | 
			
		||||
              icon: const Icon(Icons.download),
 | 
			
		||||
              onPressed: () async => await _downloadMedia(currentItem),
 | 
			
		||||
            ),
 | 
			
		||||
            PopupMenuButton<ShareAction>(
 | 
			
		||||
              onSelected: (value) => _handleShareAction(value, currentItem),
 | 
			
		||||
              itemBuilder: (context) => _shareMenuItems,
 | 
			
		||||
              icon: const Icon(Icons.share),
 | 
			
		||||
            ),
 | 
			
		||||
            Builder(
 | 
			
		||||
              builder: (context) => IconButton(
 | 
			
		||||
                icon: const Icon(Icons.menu),
 | 
			
		||||
                onPressed: () => Scaffold.of(context).openEndDrawer(),
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
        body: Stack(
 | 
			
		||||
          children: [
 | 
			
		||||
            PageView.builder(
 | 
			
		||||
              controller: _pageController!,
 | 
			
		||||
              itemCount: mediaController.items.length,
 | 
			
		||||
              onPageChanged: _onPageChanged,
 | 
			
		||||
              itemBuilder: (context, index) {
 | 
			
		||||
                final MediaItem item = mediaController.items[index];
 | 
			
		||||
                final bool isReady = _readyItemIds.contains(item.id);
 | 
			
		||||
                final PullexRefreshController refreshController =
 | 
			
		||||
                    _refreshControllers.putIfAbsent(
 | 
			
		||||
                      item.id,
 | 
			
		||||
                      () => PullexRefreshController(),
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
                return PullexRefresh(
 | 
			
		||||
                  onRefresh: () => _onRefresh(item.id, refreshController),
 | 
			
		||||
                  header: const WaterDropHeader(),
 | 
			
		||||
                  controller: refreshController,
 | 
			
		||||
                  child: CustomScrollView(
 | 
			
		||||
                    slivers: [
 | 
			
		||||
                      SliverToBoxAdapter(
 | 
			
		||||
                        child: AnimatedBuilder(
 | 
			
		||||
                          animation: _pageController!,
 | 
			
		||||
                          builder: (context, child) {
 | 
			
		||||
                            return buildAnimatedTransition(
 | 
			
		||||
                              context: context,
 | 
			
		||||
                              pageController: _pageController!,
 | 
			
		||||
                              index: index,
 | 
			
		||||
                              child: child!,
 | 
			
		||||
                            );
 | 
			
		||||
                          },
 | 
			
		||||
                          child: Obx(
 | 
			
		||||
                            () =>
 | 
			
		||||
                                _buildMedia(item, index == _currentIndex.value),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
      return PageView.builder(
 | 
			
		||||
        controller: _pageController!,
 | 
			
		||||
        itemCount: mediaController.items.length,
 | 
			
		||||
        onPageChanged: _onPageChanged,
 | 
			
		||||
        itemBuilder: (context, index) {
 | 
			
		||||
          if (index >= mediaController.items.length) {
 | 
			
		||||
            return const SizedBox.shrink();
 | 
			
		||||
          }
 | 
			
		||||
          final MediaItem item = mediaController.items[index];
 | 
			
		||||
          final PullexRefreshController refreshController = _refreshControllers
 | 
			
		||||
              .putIfAbsent(item.id, () => PullexRefreshController());
 | 
			
		||||
 | 
			
		||||
          return Obx(() {
 | 
			
		||||
            final bool isReady = _readyItemIds.contains(item.id);
 | 
			
		||||
            return PullexRefresh(
 | 
			
		||||
              onRefresh: () => _onRefresh(item.id, refreshController),
 | 
			
		||||
              header: const WaterDropHeader(),
 | 
			
		||||
              controller: refreshController,
 | 
			
		||||
              child: CustomScrollView(
 | 
			
		||||
                slivers: [
 | 
			
		||||
                  SliverToBoxAdapter(
 | 
			
		||||
                    child: AnimatedBuilder(
 | 
			
		||||
                      animation: _pageController!,
 | 
			
		||||
                      builder: (context, child) {
 | 
			
		||||
                        return buildAnimatedTransition(
 | 
			
		||||
                          context: context,
 | 
			
		||||
                          pageController: _pageController!,
 | 
			
		||||
                          index: index,
 | 
			
		||||
                          child: child!,
 | 
			
		||||
                        );
 | 
			
		||||
                      },
 | 
			
		||||
                      child: Obx(
 | 
			
		||||
                        () => _buildMedia(item, index == _currentIndex.value),
 | 
			
		||||
                      ),
 | 
			
		||||
                      if (isReady)
 | 
			
		||||
                        SliverFillRemaining(
 | 
			
		||||
                          hasScrollBody: false,
 | 
			
		||||
                          fillOverscroll: true,
 | 
			
		||||
                          child: Padding(
 | 
			
		||||
                            padding: const EdgeInsets.all(16.0),
 | 
			
		||||
                            child: Column(
 | 
			
		||||
                              crossAxisAlignment: CrossAxisAlignment.center,
 | 
			
		||||
                              children: [TagSection(tags: item.tags ?? [])],
 | 
			
		||||
                            ),
 | 
			
		||||
                          ),
 | 
			
		||||
                        ),
 | 
			
		||||
                      const SliverToBoxAdapter(
 | 
			
		||||
                        child: SafeArea(child: SizedBox.shrink()),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ],
 | 
			
		||||
                    ),
 | 
			
		||||
                  ),
 | 
			
		||||
                );
 | 
			
		||||
              },
 | 
			
		||||
            ),
 | 
			
		||||
            Obx(() {
 | 
			
		||||
              if (!authController.isLoggedIn) {
 | 
			
		||||
                return const SizedBox.shrink();
 | 
			
		||||
              }
 | 
			
		||||
              final MediaItem currentItem =
 | 
			
		||||
                  mediaController.items[_currentIndex.value];
 | 
			
		||||
 | 
			
		||||
              final bool hasSoftButtons =
 | 
			
		||||
                  MediaQuery.of(context).padding.bottom > 24.0;
 | 
			
		||||
 | 
			
		||||
              return DraggableScrollableSheet(
 | 
			
		||||
                initialChildSize: hasSoftButtons ? 0.11 : 0.2,
 | 
			
		||||
                minChildSize: hasSoftButtons ? 0.11 : 0.2,
 | 
			
		||||
                maxChildSize: hasSoftButtons ? 0.245 : 0.2,
 | 
			
		||||
                snap: true,
 | 
			
		||||
                builder: (context, scrollController) => ListView(
 | 
			
		||||
                  controller: scrollController,
 | 
			
		||||
                  padding: const EdgeInsets.only(left: 16, right: 16),
 | 
			
		||||
                  children: [
 | 
			
		||||
                    FavoriteSection(
 | 
			
		||||
                      item: currentItem,
 | 
			
		||||
                      index: _currentIndex.value,
 | 
			
		||||
                  if (isReady)
 | 
			
		||||
                    SliverToBoxAdapter(
 | 
			
		||||
                      child: Padding(
 | 
			
		||||
                        padding: const EdgeInsets.all(16.0),
 | 
			
		||||
                        child: Column(
 | 
			
		||||
                          crossAxisAlignment: CrossAxisAlignment.center,
 | 
			
		||||
                          children: [
 | 
			
		||||
                            TagSection(tags: item.tags ?? []),
 | 
			
		||||
                            Obx(() {
 | 
			
		||||
                              if (!authController.isLoggedIn) {
 | 
			
		||||
                                return const SizedBox.shrink();
 | 
			
		||||
                              }
 | 
			
		||||
                              final TextStyle? infoTextStyle = Theme.of(
 | 
			
		||||
                                context,
 | 
			
		||||
                              ).textTheme.bodySmall;
 | 
			
		||||
                              return Padding(
 | 
			
		||||
                                padding: const EdgeInsets.only(top: 24.0),
 | 
			
		||||
                                child: Column(
 | 
			
		||||
                                  children: [
 | 
			
		||||
                                    FavoriteSection(item: item, index: index),
 | 
			
		||||
                                    const SizedBox(height: 16),
 | 
			
		||||
                                    Text(
 | 
			
		||||
                                      "Dateigröße: ${(item.size / 1024).toStringAsFixed(1)} KB",
 | 
			
		||||
                                      style: infoTextStyle,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    Text(
 | 
			
		||||
                                      "Typ: ${item.mime}",
 | 
			
		||||
                                      style: infoTextStyle,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    Text(
 | 
			
		||||
                                      "ID: ${item.id}",
 | 
			
		||||
                                      style: infoTextStyle,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                    Text(
 | 
			
		||||
                                      "Hochgeladen: ${timeago.format(DateTime.fromMillisecondsSinceEpoch(item.stamp * 1000), locale: 'de')}",
 | 
			
		||||
                                      style: infoTextStyle,
 | 
			
		||||
                                    ),
 | 
			
		||||
                                  ],
 | 
			
		||||
                                ),
 | 
			
		||||
                              );
 | 
			
		||||
                            }),
 | 
			
		||||
                          ],
 | 
			
		||||
                        ),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    const SizedBox(height: 16),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "Dateigröße: ${(currentItem.size / 1024).toStringAsFixed(1)} KB",
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodySmall,
 | 
			
		||||
                    ),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "Typ: ${currentItem.mime}",
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodySmall,
 | 
			
		||||
                    ),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "ID: ${currentItem.id}",
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodySmall,
 | 
			
		||||
                    ),
 | 
			
		||||
                    Text(
 | 
			
		||||
                      "Hochgeladen am: ${DateTime.fromMillisecondsSinceEpoch(currentItem.stamp * 1000)}",
 | 
			
		||||
                      style: Theme.of(context).textTheme.bodySmall,
 | 
			
		||||
                    ),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              );
 | 
			
		||||
            }),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
        persistentFooterButtons: mediaController.tag.value != null
 | 
			
		||||
            ? [TagFooter()]
 | 
			
		||||
            : null,
 | 
			
		||||
                  const SliverToBoxAdapter(
 | 
			
		||||
                    child: SafeArea(child: SizedBox.shrink()),
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            );
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      endDrawer: const EndDrawer(),
 | 
			
		||||
      endDrawerEnableOpenDragGesture:
 | 
			
		||||
          settingsController.drawerSwipeEnabled.value,
 | 
			
		||||
      appBar: _buildAppBar(context),
 | 
			
		||||
      body: _buildBody(context),
 | 
			
		||||
      persistentFooterButtons: mediaController.tag.value != null
 | 
			
		||||
          ? [TagFooter()]
 | 
			
		||||
          : null,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user