aktueller Stand
This commit is contained in:
		@@ -2,17 +2,11 @@ import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:f0ckapp/mediagrid.dart';
 | 
			
		||||
//import 'package:media_kit/media_kit.dart';
 | 
			
		||||
 | 
			
		||||
void main() {
 | 
			
		||||
void main() async {
 | 
			
		||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
			
		||||
  //MediaKit.ensureInitialized();
 | 
			
		||||
  
 | 
			
		||||
  SystemChrome.setPreferredOrientations([
 | 
			
		||||
    DeviceOrientation.portraitUp
 | 
			
		||||
  ]).then((_) {
 | 
			
		||||
    runApp(const F0ckApp());
 | 
			
		||||
  });
 | 
			
		||||
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
 | 
			
		||||
  runApp(const F0ckApp());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class F0ckApp extends StatelessWidget {
 | 
			
		||||
@@ -25,13 +19,6 @@ class F0ckApp extends StatelessWidget {
 | 
			
		||||
        scaffoldBackgroundColor: const Color.fromARGB(255, 23, 23, 23),
 | 
			
		||||
      ),
 | 
			
		||||
      home: Scaffold(
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
          automaticallyImplyLeading: false,
 | 
			
		||||
          backgroundColor: const Color.fromARGB(255, 43, 43, 43),
 | 
			
		||||
          foregroundColor: const Color.fromARGB(255, 255, 255, 255),
 | 
			
		||||
          title: const Text('f0cks'),
 | 
			
		||||
          centerTitle: true,
 | 
			
		||||
        ),
 | 
			
		||||
        body: MediaGrid(),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:f0ckapp/services/api.dart';
 | 
			
		||||
import 'package:f0ckapp/models/mediaitem.dart';
 | 
			
		||||
import 'package:f0ckapp/screens/detail.dart';
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
class MediaGrid extends StatefulWidget {
 | 
			
		||||
  const MediaGrid({super.key});
 | 
			
		||||
@@ -15,64 +15,168 @@ class _MediaGridState extends State<MediaGrid> {
 | 
			
		||||
  final ScrollController _scrollController = ScrollController();
 | 
			
		||||
  List<MediaItem> mediaItems = [];
 | 
			
		||||
  bool isLoading = false;
 | 
			
		||||
  Timer? _debounceTimer;
 | 
			
		||||
  Completer<void>? _navigationCompleter;
 | 
			
		||||
  int _crossAxisCount = 3;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    _loadMedia();
 | 
			
		||||
    _scrollController.addListener(() {
 | 
			
		||||
      if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent - 100) {
 | 
			
		||||
        _loadMedia();
 | 
			
		||||
      if (_scrollController.position.pixels >=
 | 
			
		||||
          _scrollController.position.maxScrollExtent - 100) {
 | 
			
		||||
        _debounceLoadMedia();
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _debounceLoadMedia() {
 | 
			
		||||
    _debounceTimer?.cancel();
 | 
			
		||||
    _debounceTimer = Timer(const Duration(milliseconds: 500), _loadMedia);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _loadMedia() async {
 | 
			
		||||
    if (isLoading) return;
 | 
			
		||||
    setState(() => isLoading = true);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      List<MediaItem> newMedia = await fetchMedia(older: mediaItems.isNotEmpty ? mediaItems.last.id.toString() : null);
 | 
			
		||||
      setState(() {
 | 
			
		||||
        mediaItems.addAll(newMedia);
 | 
			
		||||
        isLoading = false;
 | 
			
		||||
      });
 | 
			
		||||
      final newMedia = await fetchMedia(
 | 
			
		||||
        older: mediaItems.isNotEmpty ? mediaItems.last.id.toString() : null,
 | 
			
		||||
      );
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        setState(() => mediaItems.addAll(newMedia));
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print('Fehler: $e');
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
          SnackBar(content: Text('Fehler beim Laden der Medien: $e')),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (mounted) setState(() => isLoading = false);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _refreshMedia() async {
 | 
			
		||||
    setState(() => isLoading = true);
 | 
			
		||||
    try {
 | 
			
		||||
      final freshMedia = await fetchMedia(older: null);
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        setState(() {
 | 
			
		||||
          mediaItems.clear();
 | 
			
		||||
          mediaItems.addAll(freshMedia);
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
          SnackBar(content: Text('Fehler beim Aktualisieren: $e')),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } finally {
 | 
			
		||||
      if (mounted) setState(() => isLoading = false);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _navigateToDetail(MediaItem item) async {
 | 
			
		||||
    print('Tapped item: ${item.id}');
 | 
			
		||||
 | 
			
		||||
    if (_navigationCompleter?.isCompleted == false) return;
 | 
			
		||||
 | 
			
		||||
    _navigationCompleter = Completer();
 | 
			
		||||
    try {
 | 
			
		||||
      final details = await fetchMediaDetail(item.id);
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        await Navigator.push(
 | 
			
		||||
          context,
 | 
			
		||||
          MaterialPageRoute(builder: (context) => DetailView(details: details)),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        ScaffoldMessenger.of(context).showSnackBar(
 | 
			
		||||
          SnackBar(content: Text('Fehler beim Laden der Details: $e')),
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    } finally {
 | 
			
		||||
      _navigationCompleter?.complete();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return GridView.builder(
 | 
			
		||||
      controller: _scrollController,
 | 
			
		||||
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
 | 
			
		||||
        crossAxisCount: 3,
 | 
			
		||||
        crossAxisSpacing: 8.0,
 | 
			
		||||
        mainAxisSpacing: 8.0,
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        backgroundColor: const Color.fromARGB(255, 43, 43, 43),
 | 
			
		||||
        foregroundColor: const Color.fromARGB(255, 255, 255, 255),
 | 
			
		||||
        title: Row(
 | 
			
		||||
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
			
		||||
          children: [
 | 
			
		||||
            const Text('f0cks'),
 | 
			
		||||
            DropdownButton<int>(
 | 
			
		||||
              value: _crossAxisCount,
 | 
			
		||||
              dropdownColor: const Color.fromARGB(255, 43, 43, 43),
 | 
			
		||||
              iconEnabledColor: const Color.fromARGB(255, 255, 255, 255),
 | 
			
		||||
              items: [3, 4].map((int value) {
 | 
			
		||||
                return DropdownMenuItem<int>(
 | 
			
		||||
                  value: value,
 | 
			
		||||
                  child: Text('$value Spalten', style: TextStyle(color: Colors.white)),
 | 
			
		||||
                );
 | 
			
		||||
              }).toList(),
 | 
			
		||||
              onChanged: (int? newValue) {
 | 
			
		||||
                if (newValue != null) {
 | 
			
		||||
                  setState(() {
 | 
			
		||||
                    _crossAxisCount = newValue;
 | 
			
		||||
                  });
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      itemCount: mediaItems.length + (isLoading ? 1 : 0),
 | 
			
		||||
      itemBuilder: (context, index) {
 | 
			
		||||
        if (index >= mediaItems.length) {
 | 
			
		||||
          return const Center(child: CircularProgressIndicator());
 | 
			
		||||
        }
 | 
			
		||||
        final item = mediaItems[index];
 | 
			
		||||
 | 
			
		||||
        return GestureDetector(
 | 
			
		||||
          onTap: () async {
 | 
			
		||||
            try {
 | 
			
		||||
              final details = await fetchMediaDetail(item.id);
 | 
			
		||||
              Navigator.push(
 | 
			
		||||
                context,
 | 
			
		||||
                MaterialPageRoute(builder: (context) => DetailView(details: details)),
 | 
			
		||||
              );
 | 
			
		||||
            } catch (e) {
 | 
			
		||||
              print('Fehler beim Laden der Details: $e');
 | 
			
		||||
      body: RefreshIndicator(
 | 
			
		||||
        onRefresh: _refreshMedia,
 | 
			
		||||
        child: GridView.builder(
 | 
			
		||||
          controller: _scrollController,
 | 
			
		||||
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
 | 
			
		||||
            crossAxisCount: _crossAxisCount,
 | 
			
		||||
            crossAxisSpacing: 5.0,
 | 
			
		||||
            mainAxisSpacing: 5.0,
 | 
			
		||||
          ),
 | 
			
		||||
          itemCount: mediaItems.length + (isLoading ? 1 : 0),
 | 
			
		||||
          itemBuilder: (context, index) {
 | 
			
		||||
            if (index >= mediaItems.length) {
 | 
			
		||||
              return const Center(child: CircularProgressIndicator());
 | 
			
		||||
            }
 | 
			
		||||
            final item = mediaItems[index];
 | 
			
		||||
 | 
			
		||||
            final mode =
 | 
			
		||||
                {1: Colors.green, 2: Colors.red}[item.tagid] ?? Colors.yellow;
 | 
			
		||||
 | 
			
		||||
            return InkWell(
 | 
			
		||||
              onTap: () => _navigateToDetail(item),
 | 
			
		||||
              child: Stack(
 | 
			
		||||
                fit: StackFit.expand,
 | 
			
		||||
                children: <Widget>[
 | 
			
		||||
                  Image.network(item.thumbnailUrl, fit: BoxFit.cover),
 | 
			
		||||
                  Align(
 | 
			
		||||
                    alignment: FractionalOffset.bottomRight,
 | 
			
		||||
                    child: Icon(Icons.square, color: mode, size: 15.0),
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            );
 | 
			
		||||
          },
 | 
			
		||||
          child: Image.network(item.thumbnailUrl, fit: BoxFit.cover),
 | 
			
		||||
        );
 | 
			
		||||
      },
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void dispose() {
 | 
			
		||||
    _scrollController.dispose();
 | 
			
		||||
    _debounceTimer?.cancel();
 | 
			
		||||
    super.dispose();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,8 @@ class MediaItemDetail {
 | 
			
		||||
  final String dest;
 | 
			
		||||
  final String username;
 | 
			
		||||
  final int stamp;
 | 
			
		||||
  final int next;
 | 
			
		||||
  final int prev;
 | 
			
		||||
  final int? next;
 | 
			
		||||
  final int? prev;
 | 
			
		||||
 | 
			
		||||
  MediaItemDetail({
 | 
			
		||||
    required this.id,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
import 'package:f0ckapp/services/api.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
 | 
			
		||||
import 'package:f0ckapp/models/mediaitem_detail.dart';
 | 
			
		||||
import 'package:f0ckapp/widgets/video_widget.dart';
 | 
			
		||||
 | 
			
		||||
class DetailScreen extends StatelessWidget {
 | 
			
		||||
  final MediaItemDetail details;
 | 
			
		||||
 | 
			
		||||
  const DetailScreen({super.key, required this.details});
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return GestureDetector(
 | 
			
		||||
      onHorizontalDragEnd: (details) {
 | 
			
		||||
        if (details.velocity.pixelsPerSecond.dx > 0) {
 | 
			
		||||
          _navigateToPrev(context);
 | 
			
		||||
        } else {
 | 
			
		||||
          _navigateToNext(context);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      child: VideoWidget(details: this.details)
 | 
			
		||||
    );
 | 
			
		||||
    //return VideoWidget(url: this.details.mediaUrl);
 | 
			
		||||
    /*return GestureDetector(
 | 
			
		||||
      onHorizontalDragEnd: (details) {
 | 
			
		||||
        if (details.velocity.pixelsPerSecond.dx > 0) {
 | 
			
		||||
          _navigateToPrev(context);
 | 
			
		||||
        } else {
 | 
			
		||||
          _navigateToNext(context);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
        body: Column(
 | 
			
		||||
          children: [
 | 
			
		||||
            if (this.details.mime.startsWith('image'))
 | 
			
		||||
              ClipRRect(
 | 
			
		||||
                child: Image.network(this.details.mediaUrl, fit: BoxFit.cover),
 | 
			
		||||
              )
 | 
			
		||||
            else
 | 
			
		||||
              VideoPost(
 | 
			
		||||
                url: this.details.mediaUrl,
 | 
			
		||||
                /*appBar: AppBar(
 | 
			
		||||
                  backgroundColor: const Color.fromARGB(255, 43, 43, 43),
 | 
			
		||||
                  foregroundColor: const Color.fromARGB(255, 255, 255, 255),
 | 
			
		||||
                  title: const Text('f0ck'),
 | 
			
		||||
                  centerTitle: true,
 | 
			
		||||
                )*/
 | 
			
		||||
              ),
 | 
			
		||||
 | 
			
		||||
            //const SizedBox(height: 10),
 | 
			
		||||
            //Text('f0cked by: ${this.details.username}', style: const TextStyle(fontSize: 16, color: Color.fromARGB(255, 255, 255, 255))),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );*/
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _navigateToNext(BuildContext context) async {
 | 
			
		||||
    try {
 | 
			
		||||
      final nextDetails = await fetchMediaDetail(details.next);
 | 
			
		||||
      Navigator.pushReplacement(
 | 
			
		||||
        context,
 | 
			
		||||
        MaterialPageRoute(builder: (context) => DetailScreen(details: nextDetails)),
 | 
			
		||||
      );
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print('Fehler beim Laden des nächsten Items: $e');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void _navigateToPrev(BuildContext context) async {
 | 
			
		||||
    try {
 | 
			
		||||
      final prevDetails = await fetchMediaDetail(details.prev);
 | 
			
		||||
      Navigator.pushReplacement(
 | 
			
		||||
        context,
 | 
			
		||||
        MaterialPageRoute(builder: (context) => DetailScreen(details: prevDetails)),
 | 
			
		||||
      );
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print('Fehler beim Laden des vorherigen Items: $e');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -84,10 +84,10 @@ class _DetailViewState extends State<DetailView> {
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return GestureDetector(
 | 
			
		||||
      onHorizontalDragEnd: (details) {
 | 
			
		||||
        if (details.velocity.pixelsPerSecond.dx > 0) {
 | 
			
		||||
          _loadNewMediaItem(widget.details.next, true);
 | 
			
		||||
        } else if (details.velocity.pixelsPerSecond.dx < 0) {
 | 
			
		||||
          _loadNewMediaItem(widget.details.prev, false);
 | 
			
		||||
        if (details.velocity.pixelsPerSecond.dx > 0 && widget.details.next != null) {
 | 
			
		||||
          _loadNewMediaItem(widget.details.next!, true);
 | 
			
		||||
        } else if (details.velocity.pixelsPerSecond.dx < 0 && widget.details.prev != null) {
 | 
			
		||||
          _loadNewMediaItem(widget.details.prev!, false);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ Future<List<MediaItem>> fetchMedia({String? older}) async {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Future<MediaItemDetail> fetchMediaDetail(int itemId) async {
 | 
			
		||||
  final Uri url = Uri.parse('https://f0ck.me/api/v2/item/$itemId');
 | 
			
		||||
  final Uri url = Uri.parse('https://f0ck.me/api/v2/item/${itemId.toString()}');
 | 
			
		||||
 | 
			
		||||
  final response = await http.get(url);
 | 
			
		||||
  if (response.statusCode == 200) {
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,10 @@
 | 
			
		||||
 | 
			
		||||
#include "generated_plugin_registrant.h"
 | 
			
		||||
 | 
			
		||||
#include <url_launcher_linux/url_launcher_plugin.h>
 | 
			
		||||
 | 
			
		||||
void fl_register_plugins(FlPluginRegistry* registry) {
 | 
			
		||||
  g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
 | 
			
		||||
      fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
 | 
			
		||||
  url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_PLUGIN_LIST
 | 
			
		||||
  url_launcher_linux
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
 | 
			
		||||
 
 | 
			
		||||
@@ -5,12 +5,20 @@
 | 
			
		||||
import FlutterMacOS
 | 
			
		||||
import Foundation
 | 
			
		||||
 | 
			
		||||
import device_info_plus
 | 
			
		||||
import package_info_plus
 | 
			
		||||
import path_provider_foundation
 | 
			
		||||
import shared_preferences_foundation
 | 
			
		||||
import sqflite_darwin
 | 
			
		||||
import url_launcher_macos
 | 
			
		||||
import video_player_avfoundation
 | 
			
		||||
 | 
			
		||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
 | 
			
		||||
  DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
 | 
			
		||||
  FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
 | 
			
		||||
  PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
 | 
			
		||||
  SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
 | 
			
		||||
  SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
 | 
			
		||||
  UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
 | 
			
		||||
  FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										208
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										208
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -89,6 +89,22 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.0.8"
 | 
			
		||||
  device_info_plus:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: device_info_plus
 | 
			
		||||
      sha256: "0c6396126421b590089447154c5f98a5de423b70cfb15b1578fd018843ee6f53"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "11.4.0"
 | 
			
		||||
  device_info_plus_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: device_info_plus_platform_interface
 | 
			
		||||
      sha256: "0b04e02b30791224b31969eb1b50d723498f402971bff3630bca2ba839bd1ed2"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "7.0.2"
 | 
			
		||||
  fake_async:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -240,6 +256,30 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.0"
 | 
			
		||||
  os_detect:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: os_detect
 | 
			
		||||
      sha256: "7d87c0dd98c6faf110d5aa498e9a6df02ffce4bb78cc9cfc8ad02929be9bb71f"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.0.3"
 | 
			
		||||
  package_info_plus:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    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:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -296,6 +336,14 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.0"
 | 
			
		||||
  petitparser:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: petitparser
 | 
			
		||||
      sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.1.0"
 | 
			
		||||
  platform:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -320,6 +368,62 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "0.28.0"
 | 
			
		||||
  shared_preferences:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences
 | 
			
		||||
      sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.5.3"
 | 
			
		||||
  shared_preferences_android:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_android
 | 
			
		||||
      sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.10"
 | 
			
		||||
  shared_preferences_foundation:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_foundation
 | 
			
		||||
      sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.5.4"
 | 
			
		||||
  shared_preferences_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_linux
 | 
			
		||||
      sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  shared_preferences_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_platform_interface
 | 
			
		||||
      sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  shared_preferences_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_web
 | 
			
		||||
      sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.3"
 | 
			
		||||
  shared_preferences_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: shared_preferences_windows
 | 
			
		||||
      sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  sky_engine:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description: flutter
 | 
			
		||||
@@ -437,6 +541,78 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.4.0"
 | 
			
		||||
  upgrader:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
      name: upgrader
 | 
			
		||||
      sha256: "60293b391f4146ce1e381ed6198b6374559a4aadf885d313e94e6c7d454d03ca"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "11.4.0"
 | 
			
		||||
  url_launcher:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher
 | 
			
		||||
      sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.3.1"
 | 
			
		||||
  url_launcher_android:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_android
 | 
			
		||||
      sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.3.16"
 | 
			
		||||
  url_launcher_ios:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_ios
 | 
			
		||||
      sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.3.3"
 | 
			
		||||
  url_launcher_linux:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_linux
 | 
			
		||||
      sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.2.1"
 | 
			
		||||
  url_launcher_macos:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_macos
 | 
			
		||||
      sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.2.2"
 | 
			
		||||
  url_launcher_platform_interface:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_platform_interface
 | 
			
		||||
      sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.3.2"
 | 
			
		||||
  url_launcher_web:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_web
 | 
			
		||||
      sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.4.1"
 | 
			
		||||
  url_launcher_windows:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: url_launcher_windows
 | 
			
		||||
      sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.1.4"
 | 
			
		||||
  uuid:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -453,6 +629,14 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.2.0"
 | 
			
		||||
  version:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: version
 | 
			
		||||
      sha256: "3d4140128e6ea10d83da32fef2fa4003fccbf6852217bb854845802f04191f94"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "3.0.2"
 | 
			
		||||
  video_player:
 | 
			
		||||
    dependency: "direct main"
 | 
			
		||||
    description:
 | 
			
		||||
@@ -509,6 +693,22 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.1.1"
 | 
			
		||||
  win32:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: win32
 | 
			
		||||
      sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "5.13.0"
 | 
			
		||||
  win32_registry:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: win32_registry
 | 
			
		||||
      sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "2.1.0"
 | 
			
		||||
  xdg_directories:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
@@ -517,6 +717,14 @@ packages:
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "1.1.0"
 | 
			
		||||
  xml:
 | 
			
		||||
    dependency: transitive
 | 
			
		||||
    description:
 | 
			
		||||
      name: xml
 | 
			
		||||
      sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
 | 
			
		||||
      url: "https://pub.dev"
 | 
			
		||||
    source: hosted
 | 
			
		||||
    version: "6.5.0"
 | 
			
		||||
sdks:
 | 
			
		||||
  dart: ">=3.9.0-172.0.dev <4.0.0"
 | 
			
		||||
  flutter: ">=3.29.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ dependencies:
 | 
			
		||||
  # The following adds the Cupertino Icons font to your application.
 | 
			
		||||
  # Use with the CupertinoIcons class for iOS style icons.
 | 
			
		||||
  cupertino_icons: ^1.0.8
 | 
			
		||||
  upgrader: ^11.4.0
 | 
			
		||||
 | 
			
		||||
dev_dependencies:
 | 
			
		||||
  flutter_test:
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,9 @@
 | 
			
		||||
 | 
			
		||||
#include "generated_plugin_registrant.h"
 | 
			
		||||
 | 
			
		||||
#include <url_launcher_windows/url_launcher_windows.h>
 | 
			
		||||
 | 
			
		||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
 | 
			
		||||
  UrlLauncherWindowsRegisterWithRegistrar(
 | 
			
		||||
      registry->GetRegistrarForPlugin("UrlLauncherWindows"));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_PLUGIN_LIST
 | 
			
		||||
  url_launcher_windows
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user