- worst update eu west
This commit is contained in:
		@@ -1,5 +1,6 @@
 | 
				
			|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 | 
					<manifest xmlns:android="http://schemas.android.com/apk/res/android">
 | 
				
			||||||
    <uses-permission android:name="android.permission.INTERNET"/>
 | 
					    <uses-permission android:name="android.permission.INTERNET"/>
 | 
				
			||||||
 | 
					    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <application
 | 
					    <application
 | 
				
			||||||
        android:label="f0ckapp"
 | 
					        android:label="f0ckapp"
 | 
				
			||||||
@@ -28,12 +29,26 @@
 | 
				
			|||||||
                <action android:name="android.intent.action.MAIN"/>
 | 
					                <action android:name="android.intent.action.MAIN"/>
 | 
				
			||||||
                <category android:name="android.intent.category.LAUNCHER"/>
 | 
					                <category android:name="android.intent.category.LAUNCHER"/>
 | 
				
			||||||
            </intent-filter>
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					            <meta-data android:name="flutter_deeplinking_enabled" android:value="false"/>
 | 
				
			||||||
 | 
					            <intent-filter android:autoVerify="true">
 | 
				
			||||||
 | 
					                <action android:name="android.intent.action.VIEW"/>
 | 
				
			||||||
 | 
					                <category android:name="android.intent.category.DEFAULT"/>
 | 
				
			||||||
 | 
					                <category android:name="android.intent.category.BROWSABLE"/>
 | 
				
			||||||
 | 
					                <data android:scheme="https" android:host="f0ck.me"/>
 | 
				
			||||||
 | 
					            </intent-filter>
 | 
				
			||||||
 | 
					            <intent-filter>
 | 
				
			||||||
 | 
					                <action android:name="android.intent.action.VIEW"/>
 | 
				
			||||||
 | 
					                <category android:name="android.intent.category.DEFAULT"/>
 | 
				
			||||||
 | 
					                <category android:name="android.intent.category.BROWSABLE"/>
 | 
				
			||||||
 | 
					                <data android:scheme="f0ck" android:host="com.f0ck.f0ckapp"/>
 | 
				
			||||||
 | 
					            </intent-filter>
 | 
				
			||||||
        </activity>
 | 
					        </activity>
 | 
				
			||||||
        <!-- Don't delete the meta-data below.
 | 
					        <!-- Don't delete the meta-data below.
 | 
				
			||||||
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
 | 
					             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
 | 
				
			||||||
        <meta-data
 | 
					        <meta-data
 | 
				
			||||||
            android:name="flutterEmbedding"
 | 
					            android:name="flutterEmbedding"
 | 
				
			||||||
            android:value="2" />
 | 
					            android:value="2" />
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    </application>
 | 
					    </application>
 | 
				
			||||||
    <!-- Required to query activities that can process text, see:
 | 
					    <!-- Required to query activities that can process text, see:
 | 
				
			||||||
         https://developer.android.com/training/package-visibility and
 | 
					         https://developer.android.com/training/package-visibility and
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import 'package:app_links/app_links.dart';
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter/services.dart';
 | 
					import 'package:flutter/services.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,12 +12,14 @@ void main() async {
 | 
				
			|||||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
					  WidgetsFlutterBinding.ensureInitialized();
 | 
				
			||||||
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
 | 
					  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
 | 
				
			||||||
  await AppVersion.init();
 | 
					  await AppVersion.init();
 | 
				
			||||||
 | 
					  final Uri? initialUri = await AppLinks().getInitialLink();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  runApp(ProviderScope(child: const F0ckApp()));
 | 
					  runApp(ProviderScope(child: F0ckApp(initialUri: initialUri)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class F0ckApp extends ConsumerWidget {
 | 
					class F0ckApp extends ConsumerWidget {
 | 
				
			||||||
  const F0ckApp({super.key});
 | 
					  final Uri? initialUri;
 | 
				
			||||||
 | 
					  const F0ckApp({super.key, this.initialUri});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context, WidgetRef ref) {
 | 
					  Widget build(BuildContext context, WidgetRef ref) {
 | 
				
			||||||
@@ -25,7 +28,7 @@ class F0ckApp extends ConsumerWidget {
 | 
				
			|||||||
        return MaterialApp(
 | 
					        return MaterialApp(
 | 
				
			||||||
          debugShowCheckedModeBanner: false,
 | 
					          debugShowCheckedModeBanner: false,
 | 
				
			||||||
          theme: ref.watch(themeNotifierProvider),
 | 
					          theme: ref.watch(themeNotifierProvider),
 | 
				
			||||||
          home: const MediaGrid(),
 | 
					          home: MediaGrid(initialUri: initialUri),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -106,14 +106,16 @@ class MediaNotifier extends StateNotifier<MediaState> {
 | 
				
			|||||||
    state = state.replace(mediaItems: updated);
 | 
					    state = state.replace(mediaItems: updated);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> loadMedia() async {
 | 
					  Future<void> loadMedia({int? id}) async {
 | 
				
			||||||
    if (state.isLoading) return;
 | 
					    //if (state.isLoading) return;
 | 
				
			||||||
 | 
					    if (id != null) {
 | 
				
			||||||
 | 
					      print('requested id: ${id.toString()}');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state = state.replace(isLoading: true);
 | 
					    state = state.replace(isLoading: true);
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      final older = state.mediaItems.isNotEmpty
 | 
					      final older =
 | 
				
			||||||
          ? state.mediaItems.last.id
 | 
					          id ?? (state.mediaItems.isNotEmpty ? state.mediaItems.last.id : null);
 | 
				
			||||||
          : null;
 | 
					 | 
				
			||||||
      final newMedia = await fetchMedia(
 | 
					      final newMedia = await fetchMedia(
 | 
				
			||||||
        older: older,
 | 
					        older: older,
 | 
				
			||||||
        type: mediaTypes[state.typeIndex],
 | 
					        type: mediaTypes[state.typeIndex],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -102,6 +102,12 @@ class _DetailViewState extends ConsumerState<DetailView> {
 | 
				
			|||||||
        centerTitle: true,
 | 
					        centerTitle: true,
 | 
				
			||||||
        title: Text('f0ck #${mediaState.mediaItems[_currentIndex].id}'),
 | 
					        title: Text('f0ck #${mediaState.mediaItems[_currentIndex].id}'),
 | 
				
			||||||
        actions: [
 | 
					        actions: [
 | 
				
			||||||
 | 
					          IconButton(
 | 
				
			||||||
 | 
					            icon: Icon(Icons.fullscreen),
 | 
				
			||||||
 | 
					            onPressed: () {
 | 
				
			||||||
 | 
					              // wip
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
          IconButton(
 | 
					          IconButton(
 | 
				
			||||||
            icon: Icon(Icons.download),
 | 
					            icon: Icon(Icons.download),
 | 
				
			||||||
            onPressed: () {
 | 
					            onPressed: () {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,18 +1,21 @@
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'package:app_links/app_links.dart';
 | 
				
			||||||
import 'package:cached_network_image/cached_network_image.dart';
 | 
					import 'package:cached_network_image/cached_network_image.dart';
 | 
				
			||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
					import 'package:flutter_riverpod/flutter_riverpod.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';
 | 
					import 'package:f0ckapp/utils/AppVersion.dart';
 | 
				
			||||||
 | 
					import 'package:f0ckapp/utils/ParseDeepLink.dart';
 | 
				
			||||||
import 'package:f0ckapp/providers/ThemeProvider.dart';
 | 
					import 'package:f0ckapp/providers/ThemeProvider.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const List<String> mediaTypes = ["alles", "image", "video", "audio"];
 | 
					const List<String> mediaTypes = ["alles", "image", "video", "audio"];
 | 
				
			||||||
const List<String> mediaModes = ["sfw", "nsfw", "untagged", "all"];
 | 
					const List<String> mediaModes = ["sfw", "nsfw", "untagged", "all"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MediaGrid extends ConsumerStatefulWidget {
 | 
					class MediaGrid extends ConsumerStatefulWidget {
 | 
				
			||||||
  const MediaGrid({super.key});
 | 
					  final Uri? initialUri = null;
 | 
				
			||||||
 | 
					  const MediaGrid({super.key, required initialUri});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  ConsumerState<MediaGrid> createState() => _MediaGridState();
 | 
					  ConsumerState<MediaGrid> createState() => _MediaGridState();
 | 
				
			||||||
@@ -25,6 +28,8 @@ class _MediaGridState extends ConsumerState<MediaGrid> {
 | 
				
			|||||||
  final TextEditingController _usernameController = TextEditingController();
 | 
					  final TextEditingController _usernameController = TextEditingController();
 | 
				
			||||||
  final TextEditingController _passwordController = TextEditingController();
 | 
					  final TextEditingController _passwordController = TextEditingController();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final appLinks = AppLinks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int _calculateCrossAxisCount(BuildContext context, int defaultCount) {
 | 
					  int _calculateCrossAxisCount(BuildContext context, int defaultCount) {
 | 
				
			||||||
    return defaultCount == 0
 | 
					    return defaultCount == 0
 | 
				
			||||||
        ? (MediaQuery.of(context).size.width / 110).clamp(3, 5).toInt()
 | 
					        ? (MediaQuery.of(context).size.width / 110).clamp(3, 5).toInt()
 | 
				
			||||||
@@ -43,6 +48,23 @@ class _MediaGridState extends ConsumerState<MediaGrid> {
 | 
				
			|||||||
        ref.read(mediaProvider.notifier).loadMedia();
 | 
					        ref.read(mediaProvider.notifier).loadMedia();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    appLinks.uriLinkStream.listen((Uri uri) async {
 | 
				
			||||||
 | 
					      final parsedResult = parseDeepLink(uri);
 | 
				
			||||||
 | 
					      if (parsedResult == null) return;
 | 
				
			||||||
 | 
					      if (parsedResult['route'] != 'complex') return;
 | 
				
			||||||
 | 
					      final params = parsedResult['params'] as Map<String, String>;
 | 
				
			||||||
 | 
					      await handleComplexDeepLink(params, context, ref, _scrollController);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //print('initial: ${parseDeepLink(widget.initialUri)}');
 | 
				
			||||||
 | 
					    Future.microtask(() async {
 | 
				
			||||||
 | 
					      final initparsedResult = parseDeepLink(widget.initialUri);
 | 
				
			||||||
 | 
					      if (initparsedResult == null) return;
 | 
				
			||||||
 | 
					      if (initparsedResult['route'] != 'complex') return;
 | 
				
			||||||
 | 
					      final initparams = initparsedResult['params'] as Map<String, String>;
 | 
				
			||||||
 | 
					      await handleComplexDeepLink(initparams, context, ref, _scrollController);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										83
									
								
								lib/utils/ParseDeepLink.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								lib/utils/ParseDeepLink.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					import 'package:f0ckapp/providers/MediaProvider.dart';
 | 
				
			||||||
 | 
					import 'package:f0ckapp/screens/DetailView.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_riverpod/flutter_riverpod.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Map<String, RegExp> routes = {
 | 
				
			||||||
 | 
					  //'login': RegExp(r'^/login/?$'),
 | 
				
			||||||
 | 
					  //'user': RegExp(r'^/user/(?<user>.*)$'),
 | 
				
			||||||
 | 
					  'complex': RegExp(
 | 
				
			||||||
 | 
					    r'^/?'
 | 
				
			||||||
 | 
					    r'(?:tag/(?<tag>.+?))?'
 | 
				
			||||||
 | 
					    r'(?:/user/(?<username>.+?)/(?<set>f0cks|favs))?'
 | 
				
			||||||
 | 
					    r'(?:/(?<media>image|audio|video))?'
 | 
				
			||||||
 | 
					    r'(?:/(?<id>\d+))?'
 | 
				
			||||||
 | 
					    r'$',
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  //'random': RegExp(r'^/random$'),
 | 
				
			||||||
 | 
					  //'search': RegExp(r'^/search/?$'),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Map<String, dynamic> parseDeepLink(Uri? uri) {
 | 
				
			||||||
 | 
					  if (uri == null) {
 | 
				
			||||||
 | 
					    return {};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  String url = uri.toString().replaceAll("https://f0ck.me", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (final MapEntry<String, RegExp> entry in routes.entries) {
 | 
				
			||||||
 | 
					    final String routeName = entry.key;
 | 
				
			||||||
 | 
					    final RegExp pattern = entry.value;
 | 
				
			||||||
 | 
					    final RegExpMatch? match = pattern.firstMatch(url.toString());
 | 
				
			||||||
 | 
					    if (match != null) {
 | 
				
			||||||
 | 
					      Map<String, String> params = <String, String>{};
 | 
				
			||||||
 | 
					      for (String name in match.groupNames) {
 | 
				
			||||||
 | 
					        params[name] = match.namedGroup(name) ?? '';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return {'route': routeName, 'params': params};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return {};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Future<void> handleComplexDeepLink(
 | 
				
			||||||
 | 
					  Map<String, String> params,
 | 
				
			||||||
 | 
					  BuildContext context,
 | 
				
			||||||
 | 
					  WidgetRef ref,
 | 
				
			||||||
 | 
					  ScrollController scrollController,
 | 
				
			||||||
 | 
					) async {
 | 
				
			||||||
 | 
					  final media = params['media'];
 | 
				
			||||||
 | 
					  const validMediaTypes = {'audio', 'video', 'image'};
 | 
				
			||||||
 | 
					  if (media != null && validMediaTypes.contains(media)) {
 | 
				
			||||||
 | 
					    ref.read(mediaProvider.notifier).setType(media);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final idParam = params['id'];
 | 
				
			||||||
 | 
					  if (idParam == null || idParam.isEmpty) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final int? id = int.tryParse(idParam);
 | 
				
			||||||
 | 
					  if (id == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final mediaState = ref.read(mediaProvider);
 | 
				
			||||||
 | 
					  final index = mediaState.mediaItems.indexWhere((item) => item.id == id);
 | 
				
			||||||
 | 
					  if (index == -1) {
 | 
				
			||||||
 | 
					    await ref.read(mediaProvider.notifier).loadMedia(id: id + 50);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final updatedState = ref.read(mediaProvider);
 | 
				
			||||||
 | 
					    final updatedIndex = updatedState.mediaItems.indexWhere(
 | 
				
			||||||
 | 
					      (item) => item.id == id,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    print(updatedIndex.toString());
 | 
				
			||||||
 | 
					    if (updatedIndex == -1) {
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bool? navigationResult = await Navigator.push(
 | 
				
			||||||
 | 
					    context,
 | 
				
			||||||
 | 
					    MaterialPageRoute(builder: (_) => DetailView(initialItemId: id)),
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (navigationResult == true) {
 | 
				
			||||||
 | 
					    scrollController.jumpTo(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,7 +25,7 @@ class VideoControlsOverlay extends ConsumerWidget {
 | 
				
			|||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
        Positioned(
 | 
					        Positioned(
 | 
				
			||||||
          right: 12,
 | 
					          right: 12,
 | 
				
			||||||
          top: 12,
 | 
					          bottom: 12,
 | 
				
			||||||
          child: _ControlButton(
 | 
					          child: _ControlButton(
 | 
				
			||||||
            mediaState.muted ? Icons.volume_off : Icons.volume_up,
 | 
					            mediaState.muted ? Icons.volume_off : Icons.volume_up,
 | 
				
			||||||
            () {
 | 
					            () {
 | 
				
			||||||
@@ -35,13 +35,6 @@ class VideoControlsOverlay extends ConsumerWidget {
 | 
				
			|||||||
            size: 16,
 | 
					            size: 16,
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ),
 | 
				
			||||||
        Positioned(
 | 
					 | 
				
			||||||
          right: 12,
 | 
					 | 
				
			||||||
          bottom: 12,
 | 
					 | 
				
			||||||
          child: _ControlButton(Icons.fullscreen, () {
 | 
					 | 
				
			||||||
            button();
 | 
					 | 
				
			||||||
          }, size: 16),
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
        Center(
 | 
					        Center(
 | 
				
			||||||
          child: Row(
 | 
					          child: Row(
 | 
				
			||||||
            mainAxisAlignment: MainAxisAlignment.center,
 | 
					            mainAxisAlignment: MainAxisAlignment.center,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								pubspec.lock
									
									
									
									
									
								
							@@ -1,6 +1,38 @@
 | 
				
			|||||||
# Generated by pub
 | 
					# Generated by pub
 | 
				
			||||||
# See https://dart.dev/tools/pub/glossary#lockfile
 | 
					# See https://dart.dev/tools/pub/glossary#lockfile
 | 
				
			||||||
packages:
 | 
					packages:
 | 
				
			||||||
 | 
					  app_links:
 | 
				
			||||||
 | 
					    dependency: "direct main"
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: app_links
 | 
				
			||||||
 | 
					      sha256: "85ed8fc1d25a76475914fff28cc994653bd900bc2c26e4b57a49e097febb54ba"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "6.4.0"
 | 
				
			||||||
 | 
					  app_links_linux:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: app_links_linux
 | 
				
			||||||
 | 
					      sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.0.3"
 | 
				
			||||||
 | 
					  app_links_platform_interface:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: app_links_platform_interface
 | 
				
			||||||
 | 
					      sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "2.0.2"
 | 
				
			||||||
 | 
					  app_links_web:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: app_links_web
 | 
				
			||||||
 | 
					      sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "1.0.4"
 | 
				
			||||||
  async:
 | 
					  async:
 | 
				
			||||||
    dependency: transitive
 | 
					    dependency: transitive
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
@@ -240,6 +272,14 @@ packages:
 | 
				
			|||||||
      url: "https://pub.dev"
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
    source: hosted
 | 
					    source: hosted
 | 
				
			||||||
    version: "2.1.1"
 | 
					    version: "2.1.1"
 | 
				
			||||||
 | 
					  gtk:
 | 
				
			||||||
 | 
					    dependency: transitive
 | 
				
			||||||
 | 
					    description:
 | 
				
			||||||
 | 
					      name: gtk
 | 
				
			||||||
 | 
					      sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
 | 
				
			||||||
 | 
					      url: "https://pub.dev"
 | 
				
			||||||
 | 
					    source: hosted
 | 
				
			||||||
 | 
					    version: "2.1.0"
 | 
				
			||||||
  html:
 | 
					  html:
 | 
				
			||||||
    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.1.6+36
 | 
					version: 1.1.7+37
 | 
				
			||||||
 | 
					
 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ^3.9.0-100.2.beta
 | 
					  sdk: ^3.9.0-100.2.beta
 | 
				
			||||||
@@ -41,6 +41,7 @@ dependencies:
 | 
				
			|||||||
  share_plus: ^11.0.0
 | 
					  share_plus: ^11.0.0
 | 
				
			||||||
  flutter_secure_storage: ^9.2.4
 | 
					  flutter_secure_storage: ^9.2.4
 | 
				
			||||||
  flutter_riverpod: ^2.6.1
 | 
					  flutter_riverpod: ^2.6.1
 | 
				
			||||||
 | 
					  app_links: ^6.4.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dev_dependencies:
 | 
					dev_dependencies:
 | 
				
			||||||
  flutter_test:
 | 
					  flutter_test:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user