This commit is contained in:
		@@ -4,12 +4,14 @@ import 'package:flutter/services.dart';
 | 
				
			|||||||
import 'package:f0ckapp/providers/MediaProvider.dart';
 | 
					import 'package:f0ckapp/providers/MediaProvider.dart';
 | 
				
			||||||
import 'package:f0ckapp/providers/ThemeProvider.dart';
 | 
					import 'package:f0ckapp/providers/ThemeProvider.dart';
 | 
				
			||||||
import 'package:f0ckapp/screens/MediaGrid.dart';
 | 
					import 'package:f0ckapp/screens/MediaGrid.dart';
 | 
				
			||||||
 | 
					import 'package:f0ckapp/utils/AppVersion.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() async {
 | 
					void main() async {
 | 
				
			||||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
					  WidgetsFlutterBinding.ensureInitialized();
 | 
				
			||||||
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
 | 
					  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
 | 
				
			||||||
 | 
					  await AppVersion.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  runApp(
 | 
					  runApp(
 | 
				
			||||||
    MultiProvider(
 | 
					    MultiProvider(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,8 +49,10 @@ class MediaProvider extends ChangeNotifier {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void setMediaItems(List<MediaItem> mediaItems) {
 | 
					  void setMediaItems(List<MediaItem> mediaItems) {
 | 
				
			||||||
    _mediaItems = mediaItems;
 | 
					    if (_mediaItems != mediaItems) {
 | 
				
			||||||
    notifyListeners();
 | 
					      _mediaItems = mediaItems;
 | 
				
			||||||
 | 
					      notifyListeners();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void addMediaItems(List<MediaItem> newItems) {
 | 
					  void addMediaItems(List<MediaItem> newItems) {
 | 
				
			||||||
@@ -58,10 +60,10 @@ class MediaProvider extends ChangeNotifier {
 | 
				
			|||||||
    notifyListeners();
 | 
					    notifyListeners();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> loadMedia({bool reload = false}) async {
 | 
					  Future<void> loadMedia({bool reload = false, bool notify = true}) async {
 | 
				
			||||||
    if (_isLoading) return;
 | 
					    if (_isLoading) return;
 | 
				
			||||||
    _isLoading = true;
 | 
					    _isLoading = true;
 | 
				
			||||||
    notifyListeners();
 | 
					    if (notify) notifyListeners();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      final newMedia = await fetchMedia(
 | 
					      final newMedia = await fetchMedia(
 | 
				
			||||||
@@ -81,7 +83,7 @@ class MediaProvider extends ChangeNotifier {
 | 
				
			|||||||
      debugPrint('Fehler beim Laden der Medien: $e');
 | 
					      debugPrint('Fehler beim Laden der Medien: $e');
 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
      _isLoading = false;
 | 
					      _isLoading = false;
 | 
				
			||||||
      notifyListeners();
 | 
					      if(notify) notifyListeners();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ class DetailView extends StatefulWidget {
 | 
				
			|||||||
class _DetailViewState extends State<DetailView> {
 | 
					class _DetailViewState extends State<DetailView> {
 | 
				
			||||||
  late PageController _pageController;
 | 
					  late PageController _pageController;
 | 
				
			||||||
  bool isLoading = false;
 | 
					  bool isLoading = false;
 | 
				
			||||||
 | 
					  int _currentIndex = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
@@ -30,8 +31,16 @@ class _DetailViewState extends State<DetailView> {
 | 
				
			|||||||
    final initialIndex = provider.mediaItems.indexWhere(
 | 
					    final initialIndex = provider.mediaItems.indexWhere(
 | 
				
			||||||
      (item) => item.id == widget.initialItemId,
 | 
					      (item) => item.id == widget.initialItemId,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    _pageController = PageController(initialPage: initialIndex);
 | 
					    _pageController = PageController(initialPage: initialIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _currentIndex = initialIndex;
 | 
				
			||||||
 | 
					    _pageController.addListener(() {
 | 
				
			||||||
 | 
					      setState(() {
 | 
				
			||||||
 | 
					        _currentIndex = _pageController.page?.round() ?? 0;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _preloadAdjacentMedia(initialIndex);
 | 
					    _preloadAdjacentMedia(initialIndex);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -97,10 +106,12 @@ class _DetailViewState extends State<DetailView> {
 | 
				
			|||||||
          PageTransformer(
 | 
					          PageTransformer(
 | 
				
			||||||
            controller: _pageController,
 | 
					            controller: _pageController,
 | 
				
			||||||
            pages: provider.mediaItems.map((item) {
 | 
					            pages: provider.mediaItems.map((item) {
 | 
				
			||||||
 | 
					              int itemIndex = provider.mediaItems.indexOf(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              return SafeArea(
 | 
					              return SafeArea(
 | 
				
			||||||
                child: SmartRefreshIndicator(
 | 
					                child: SmartRefreshIndicator(
 | 
				
			||||||
                  onRefresh: _loadMoreMedia,
 | 
					                  onRefresh: _loadMoreMedia,
 | 
				
			||||||
                  child: _buildMediaItem(item),
 | 
					                  child: _buildMediaItem(item, _currentIndex == itemIndex),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
              );
 | 
					              );
 | 
				
			||||||
            }).toList(),
 | 
					            }).toList(),
 | 
				
			||||||
@@ -129,7 +140,7 @@ class _DetailViewState extends State<DetailView> {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget _buildMediaItem(MediaItem item) {
 | 
					  Widget _buildMediaItem(MediaItem item, bool isActive) {
 | 
				
			||||||
    final provider = Provider.of<MediaProvider>(context);
 | 
					    final provider = Provider.of<MediaProvider>(context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return SingleChildScrollView(
 | 
					    return SingleChildScrollView(
 | 
				
			||||||
@@ -143,7 +154,7 @@ class _DetailViewState extends State<DetailView> {
 | 
				
			|||||||
              errorWidget: (context, url, error) => Icon(Icons.error),
 | 
					              errorWidget: (context, url, error) => Icon(Icons.error),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            VideoWidget(details: item, isActive: true),
 | 
					            VideoWidget(details: item, isActive: isActive),
 | 
				
			||||||
          const SizedBox(height: 20),
 | 
					          const SizedBox(height: 20),
 | 
				
			||||||
          Text(
 | 
					          Text(
 | 
				
			||||||
            item.mime,
 | 
					            item.mime,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@ import 'package:cached_network_image/cached_network_image.dart';
 | 
				
			|||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
import 'package:f0ckapp/screens/DetailView.dart';
 | 
					import 'package:f0ckapp/screens/DetailView.dart';
 | 
				
			||||||
import 'package:f0ckapp/providers/MediaProvider.dart';
 | 
					import 'package:f0ckapp/providers/MediaProvider.dart';
 | 
				
			||||||
 | 
					import 'package:f0ckapp/utils/AppVersion.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaGrid extends StatefulWidget {
 | 
					class MediaGrid extends StatefulWidget {
 | 
				
			||||||
  const MediaGrid({super.key});
 | 
					  const MediaGrid({super.key});
 | 
				
			||||||
@@ -27,7 +28,7 @@ class _MediaGridState extends State<MediaGrid> {
 | 
				
			|||||||
    _scrollController.addListener(() {
 | 
					    _scrollController.addListener(() {
 | 
				
			||||||
      if (_scrollController.position.pixels >=
 | 
					      if (_scrollController.position.pixels >=
 | 
				
			||||||
          _scrollController.position.maxScrollExtent - 100) {
 | 
					          _scrollController.position.maxScrollExtent - 100) {
 | 
				
			||||||
        provider.loadMedia();
 | 
					        provider.loadMedia(notify: false);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -41,8 +42,12 @@ class _MediaGridState extends State<MediaGrid> {
 | 
				
			|||||||
      key: scaffoldKey,
 | 
					      key: scaffoldKey,
 | 
				
			||||||
      appBar: AppBar(
 | 
					      appBar: AppBar(
 | 
				
			||||||
        //centerTitle: true,
 | 
					        //centerTitle: true,
 | 
				
			||||||
        title: Text('f0ck v1.0.27+27'),
 | 
					        title: Text('fApp v${AppVersion.version}'),
 | 
				
			||||||
        actions: [
 | 
					        actions: [
 | 
				
			||||||
 | 
					          IconButton(
 | 
				
			||||||
 | 
					            icon: Icon(provider.random ? Icons.shuffle_on_outlined : Icons.shuffle),
 | 
				
			||||||
 | 
					            onPressed: () => provider.toggleRandom(),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
          IconButton(
 | 
					          IconButton(
 | 
				
			||||||
            icon: const Icon(Icons.menu),
 | 
					            icon: const Icon(Icons.menu),
 | 
				
			||||||
            onPressed: () {
 | 
					            onPressed: () {
 | 
				
			||||||
@@ -103,62 +108,6 @@ class _MediaGridState extends State<MediaGrid> {
 | 
				
			|||||||
              padding: EdgeInsets.all(0),
 | 
					              padding: EdgeInsets.all(0),
 | 
				
			||||||
              child: Image.asset('assets/images/menu.webp', fit: BoxFit.cover),
 | 
					              child: Image.asset('assets/images/menu.webp', fit: BoxFit.cover),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            /*ListTile(
 | 
					 | 
				
			||||||
              title: Text(
 | 
					 | 
				
			||||||
                'All',
 | 
					 | 
				
			||||||
                style: TextStyle(
 | 
					 | 
				
			||||||
                  fontWeight: provider.type == 'alles'
 | 
					 | 
				
			||||||
                      ? FontWeight.bold
 | 
					 | 
				
			||||||
                      : FontWeight.normal,
 | 
					 | 
				
			||||||
                  color: provider.type == 'alles' ? Colors.blue : Colors.white,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              onTap: () {
 | 
					 | 
				
			||||||
                provider.setType('all');
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            ListTile(
 | 
					 | 
				
			||||||
              title: Text(
 | 
					 | 
				
			||||||
                'Images',
 | 
					 | 
				
			||||||
                style: TextStyle(
 | 
					 | 
				
			||||||
                  fontWeight: provider.type == 'image'
 | 
					 | 
				
			||||||
                      ? FontWeight.bold
 | 
					 | 
				
			||||||
                      : FontWeight.normal,
 | 
					 | 
				
			||||||
                  color: provider.type == 'image' ? Colors.blue : Colors.white,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              onTap: () {
 | 
					 | 
				
			||||||
                provider.setType('image');
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            ListTile(
 | 
					 | 
				
			||||||
              title: Text(
 | 
					 | 
				
			||||||
                'Videos',
 | 
					 | 
				
			||||||
                style: TextStyle(
 | 
					 | 
				
			||||||
                  fontWeight: provider.type == 'video'
 | 
					 | 
				
			||||||
                      ? FontWeight.bold
 | 
					 | 
				
			||||||
                      : FontWeight.normal,
 | 
					 | 
				
			||||||
                  color: provider.type == 'video' ? Colors.blue : Colors.white,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              onTap: () {
 | 
					 | 
				
			||||||
                provider.setType('video');
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            ListTile(
 | 
					 | 
				
			||||||
              title: Text(
 | 
					 | 
				
			||||||
                'Audio',
 | 
					 | 
				
			||||||
                style: TextStyle(
 | 
					 | 
				
			||||||
                  fontWeight: provider.type == 'audio'
 | 
					 | 
				
			||||||
                      ? FontWeight.bold
 | 
					 | 
				
			||||||
                      : FontWeight.normal,
 | 
					 | 
				
			||||||
                  color: provider.type == 'audio' ? Colors.blue : Colors.white,
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
              ),
 | 
					 | 
				
			||||||
              onTap: () {
 | 
					 | 
				
			||||||
                provider.setType('audio');
 | 
					 | 
				
			||||||
              },
 | 
					 | 
				
			||||||
            ),*/
 | 
					 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
@@ -187,6 +136,7 @@ class _MediaGridState extends State<MediaGrid> {
 | 
				
			|||||||
        child: Consumer<MediaProvider>(
 | 
					        child: Consumer<MediaProvider>(
 | 
				
			||||||
          builder: (context, mediaProvider, child) {
 | 
					          builder: (context, mediaProvider, child) {
 | 
				
			||||||
            return GridView.builder(
 | 
					            return GridView.builder(
 | 
				
			||||||
 | 
					              key: PageStorageKey('mediaGrid'),
 | 
				
			||||||
              controller: _scrollController,
 | 
					              controller: _scrollController,
 | 
				
			||||||
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
					              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
				
			||||||
                crossAxisCount: mediaProvider.crossAxisCount == 0
 | 
					                crossAxisCount: mediaProvider.crossAxisCount == 0
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								lib/utils/AppVersion.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/utils/AppVersion.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					import 'package:package_info_plus/package_info_plus.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AppVersion {
 | 
				
			||||||
 | 
					  static String version = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static Future<void> init() async {
 | 
				
			||||||
 | 
					    PackageInfo packageInfo = await PackageInfo.fromPlatform();
 | 
				
			||||||
 | 
					    version = '${packageInfo.version}+${packageInfo.buildNumber}';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -5,11 +5,13 @@
 | 
				
			|||||||
import FlutterMacOS
 | 
					import FlutterMacOS
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import package_info_plus
 | 
				
			||||||
import path_provider_foundation
 | 
					import path_provider_foundation
 | 
				
			||||||
import sqflite_darwin
 | 
					import sqflite_darwin
 | 
				
			||||||
import video_player_avfoundation
 | 
					import video_player_avfoundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
 | 
					func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
 | 
				
			||||||
 | 
					  FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
 | 
				
			||||||
  PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
 | 
					  PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
 | 
				
			||||||
  SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
 | 
					  SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
 | 
				
			||||||
  FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
 | 
					  FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -272,6 +272,22 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.1.0"
 | 
					    version: "2.1.0"
 | 
				
			||||||
 | 
					  package_info_plus:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: package_info_plus
 | 
				
			||||||
 | 
					      sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "8.3.0"
 | 
				
			||||||
 | 
					  package_info_plus_platform_interface:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: package_info_plus_platform_interface
 | 
				
			||||||
 | 
					      sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "3.2.0"
 | 
				
			||||||
  path:
 | 
					  path:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
@@ -541,6 +557,14 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "1.1.1"
 | 
					    version: "1.1.1"
 | 
				
			||||||
 | 
					  win32:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: win32
 | 
				
			||||||
 | 
					      sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "5.13.0"
 | 
				
			||||||
  xdg_directories:
 | 
					  xdg_directories:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 | 
				
			|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 | 
					# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 | 
				
			||||||
# In Windows, build-name is used as the major, minor, and patch parts
 | 
					# In Windows, build-name is used as the major, minor, and patch parts
 | 
				
			||||||
# of the product and file versions while build-number is used as the build suffix.
 | 
					# of the product and file versions while build-number is used as the build suffix.
 | 
				
			||||||
version: 1.0.27+27
 | 
					version: 1.0.28+28
 | 
				
			||||||
 | 
					
 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ^3.9.0-100.2.beta
 | 
					  sdk: ^3.9.0-100.2.beta
 | 
				
			||||||
@@ -38,6 +38,7 @@ dependencies:
 | 
				
			|||||||
  cached_network_image: ^3.4.1
 | 
					  cached_network_image: ^3.4.1
 | 
				
			||||||
  cached_video_player_plus: ^3.0.3
 | 
					  cached_video_player_plus: ^3.0.3
 | 
				
			||||||
  provider: ^6.1.5
 | 
					  provider: ^6.1.5
 | 
				
			||||||
 | 
					  package_info_plus: ^8.3.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user