diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a7892c8..81d373f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -28,19 +28,12 @@
-
-
-
-
-
-
-
diff --git a/lib/main.dart b/lib/main.dart
index ba79992..6f5d799 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,14 +1,13 @@
-import 'package:f0ckapp/providers/media_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
-
-import 'package:go_router/go_router.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:f0ckapp/screens/mediagrid_screen.dart';
import 'package:f0ckapp/screens/detailview_screen.dart';
+import 'package:f0ckapp/screens/settings_screen.dart';
import 'package:f0ckapp/utils/appversion_util.dart';
import 'package:f0ckapp/providers/theme_provider.dart';
+import 'package:f0ckapp/providers/media_provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
@@ -19,69 +18,61 @@ void main() async {
}
class F0ckApp extends ConsumerWidget {
- F0ckApp({super.key});
+ const F0ckApp({super.key});
- final GoRouter _router = GoRouter(
- initialLocation: '/',
- routes: [
- GoRoute(
- path: '/',
- builder: (BuildContext context, GoRouterState state) {
- return const MediaGrid();
- },
- ),
- GoRoute(
- path: '/:rest(.*)',
- builder: (context, state) {
- final bool isInternalLink = (state.extra is bool && state.extra == true);
- final String fullPath = state.matchedLocation;
+ @override
+ Widget build(BuildContext context, WidgetRef ref) {
+ final ThemeData theme = ref.watch(themeNotifierProvider);
- final regExp = RegExp(
- r'^(?:/tag/(?.+?))?(?:/(?image|audio|video))?(?:/(?\d+))?$',
+ return MaterialApp(
+ debugShowCheckedModeBanner: false,
+ theme: theme,
+ initialRoute: '/',
+ routes: {
+ '/': (context) => const MediaGrid(),
+ '/settings': (context) => const SettingsPage(),
+ },
+ onGenerateRoute: (RouteSettings settings) {
+ final String? name = settings.name;
+ if (name == null) {
+ return MaterialPageRoute(
+ builder: (_) =>
+ const Scaffold(body: Center(child: Text('Ungültiger Link'))),
+ settings: settings,
);
- final RegExpMatch? match = regExp.firstMatch(fullPath);
+ }
- if (match == null) {
- return const Scaffold(body: Center(child: Text('Ungültiger Link')));
- }
+ final RegExp regExp = RegExp(
+ r'^(?:/tag/(?[^/]+))?(?:/(?image|audio|video))?(?:/(?\d+))?$',
+ );
+ final RegExpMatch? match = regExp.firstMatch(name);
+ if (match != null) {
final String? tag = match.namedGroup('tag');
final String? mime = match.namedGroup('mime');
final String? idStr = match.namedGroup('itemid');
final int? itemId = idStr != null ? int.tryParse(idStr) : null;
const int preloadOffset = 50;
- return Consumer(
- builder: (BuildContext context, WidgetRef ref, Widget? child) {
- WidgetsBinding.instance.addPostFrameCallback((_) async {
- final MediaNotifier mediaNotifier = ref.read(mediaProvider.notifier);
- if (!isInternalLink) {
- mediaNotifier.setType(mime ?? "alles");
- mediaNotifier.setTag(tag);
- }
- if (itemId != null) {
- await mediaNotifier.loadMedia(id: itemId + preloadOffset);
- }
- });
- if (itemId != null) {
- return DetailView(initialItemId: itemId);
- } else {
- return MediaGrid();
- }
- },
- );
- },
- ),
- ],
- );
+ if (itemId != null) {
+ return MaterialPageRoute(
+ builder: (context) => DetailView(initialItemId: itemId),
+ settings: settings,
+ );
+ }
- @override
- Widget build(BuildContext context, WidgetRef ref) {
- final ThemeData theme = ref.watch(themeNotifierProvider);
- return MaterialApp.router(
- debugShowCheckedModeBanner: false,
- routerConfig: _router,
- theme: theme,
+ return MaterialPageRoute(
+ builder: (context) => const MediaGrid(),
+ settings: settings,
+ );
+ }
+
+ return MaterialPageRoute(
+ builder: (context) =>
+ const Scaffold(body: Center(child: Text('Ungültiger Link'))),
+ settings: settings,
+ );
+ },
);
}
}
diff --git a/lib/screens/detailview_screen.dart b/lib/screens/detailview_screen.dart
index 2f70886..a5eedd6 100644
--- a/lib/screens/detailview_screen.dart
+++ b/lib/screens/detailview_screen.dart
@@ -1,5 +1,4 @@
import 'dart:io';
-import 'dart:typed_data';
import 'package:f0ckapp/screens/fullscreen_screen.dart';
import 'package:f0ckapp/widgets/end_drawer.dart';
@@ -9,7 +8,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:cached_network_image/cached_network_image.dart';
-import 'package:go_router/go_router.dart';
import 'package:share_plus/share_plus.dart';
import 'package:f0ckapp/models/mediaitem_model.dart';
@@ -132,7 +130,8 @@ class _DetailViewState extends ConsumerState {
label: Text(mediaState.tag!),
onDeleted: () {
ref.read(mediaProvider.notifier).setTag(null);
- context.go('/', extra: true);
+ //context.push('/', extra: true);
+ Navigator.pushNamed(context, '/');
},
),
),
@@ -148,7 +147,8 @@ class _DetailViewState extends ConsumerState {
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
- context.canPop() ? context.pop() : context.go('/', extra: true);
+ Navigator.canPop(context) ? Navigator.pop(context) : Navigator.pushNamed(context, '/');
+ //context.canPop() ? context.pop() : context.go('/', extra: true);
},
),
actions: [
@@ -278,7 +278,7 @@ class _DetailViewState extends ConsumerState {
if (tag.tag == 'sfw' || tag.tag == 'nsfw') return;
setState(() {
mediaNotifier.setTag(tag.tag);
- context.go('/', extra: true);
+ Navigator.pushReplacementNamed(context, '/');
});
},
label: Text(tag.tag),
diff --git a/lib/screens/mediagrid_screen.dart b/lib/screens/mediagrid_screen.dart
index ff63582..f6ef25c 100644
--- a/lib/screens/mediagrid_screen.dart
+++ b/lib/screens/mediagrid_screen.dart
@@ -119,12 +119,19 @@ class _MediaGridState extends ConsumerState {
mediaState.mediaItems.length +
(mediaState.isLoading ? 1 : 0),
),
- gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
- maxCrossAxisExtent: 150,
- crossAxisSpacing: 5,
- mainAxisSpacing: 5,
- childAspectRatio: 1,
- ),
+ gridDelegate: mediaState.crossAxisCount == 0
+ ? const SliverGridDelegateWithMaxCrossAxisExtent(
+ maxCrossAxisExtent: 150,
+ crossAxisSpacing: 5,
+ mainAxisSpacing: 5,
+ childAspectRatio: 1,
+ )
+ : SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: mediaState.crossAxisCount,
+ crossAxisSpacing: 5,
+ mainAxisSpacing: 5,
+ childAspectRatio: 1,
+ ),
),
),
],
diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart
new file mode 100644
index 0000000..adca733
--- /dev/null
+++ b/lib/screens/settings_screen.dart
@@ -0,0 +1,106 @@
+import 'package:flutter/material.dart';
+
+import 'package:flutter_cache_manager/flutter_cache_manager.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+import 'package:f0ckapp/providers/media_provider.dart';
+import 'package:f0ckapp/widgets/end_drawer.dart';
+
+class SettingsPage extends ConsumerStatefulWidget {
+ const SettingsPage({super.key});
+
+ @override
+ ConsumerState createState() => _SettingsPageState();
+}
+
+class _SettingsPageState extends ConsumerState {
+ int _columns = 3;
+ bool _drawerSwipeEnabled = true;
+
+ @override
+ Widget build(BuildContext context) {
+ final MediaState mediaState = ref.watch(mediaProvider);
+ final MediaNotifier mediaNotifier = ref.read(mediaProvider.notifier);
+
+ return Scaffold(
+ endDrawerEnableOpenDragGesture: _drawerSwipeEnabled,
+ endDrawer: EndDrawer(ref: ref),
+ body: CustomScrollView(
+ slivers: [
+ SliverAppBar(
+ floating: false,
+ pinned: true,
+ title: const Text('Settings'),
+ leading: IconButton(
+ icon: const Icon(Icons.arrow_back),
+ onPressed: () {
+ Navigator.canPop(context) ? Navigator.pop(context) : Navigator.pushReplacementNamed(context, '/');
+ },
+ ),
+ ),
+ SliverList(
+ delegate: SliverChildListDelegate([
+ Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Text(
+ "Anzahl der Spalten",
+ style: Theme.of(context).textTheme.titleLarge,
+ ),
+ ),
+ ListTile(
+ title: const Text("Spaltenanzahl"),
+ trailing: DropdownButton(
+ value: mediaState.crossAxisCount,
+ dropdownColor: const Color.fromARGB(255, 43, 43, 43),
+ iconEnabledColor: Colors.white,
+ items: [0, 3, 4, 5].map((int value) {
+ return DropdownMenuItem(
+ value: value,
+ child: Text(value == 0 ? 'auto' : '$value Spalten'),
+ );
+ }).toList(),
+ onChanged: (int? newValue) {
+ if (newValue != null) {
+ setState(() {
+ _columns = newValue;
+ mediaNotifier.setCrossAxisCount(newValue);
+ });
+ }
+ },
+ ),
+ ),
+ const Divider(),
+ SwitchListTile(
+ title: const Text("Drawer per Geste öffnen"),
+ subtitle: const Text(
+ "Wähle, ob der Drawer mit einer Wischgeste geschlossen/ geöffnet werden kann.",
+ ),
+ value: _drawerSwipeEnabled,
+ onChanged: (bool value) {
+ setState(() {
+ _drawerSwipeEnabled = value;
+ });
+ },
+ ),
+ const Divider(),
+ ListTile(
+ title: const Text("Cache löschen"),
+ trailing: ElevatedButton(
+ onPressed: () async {
+ await DefaultCacheManager().emptyCache();
+ if (!mounted) return;
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(content: Text("Cache wurde geleert.")),
+ );
+ },
+ child: const Text("Löschen"),
+ ),
+ ),
+ const SizedBox(height: 20),
+ ]),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/widgets/end_drawer.dart b/lib/widgets/end_drawer.dart
index 0fd4c83..94ff3da 100644
--- a/lib/widgets/end_drawer.dart
+++ b/lib/widgets/end_drawer.dart
@@ -114,8 +114,8 @@ class EndDrawer extends StatelessWidget {
ListTile(
title: const Text('Einstellungen'),
onTap: () {
- Navigator.pop(context);
- _showMsg('wip', context);
+ //context.go('/settings');
+ Navigator.pushReplacementNamed(context, '/settings');
},
),
ListTile(
diff --git a/lib/widgets/media_tile.dart b/lib/widgets/media_tile.dart
index 0097783..c141718 100644
--- a/lib/widgets/media_tile.dart
+++ b/lib/widgets/media_tile.dart
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
-import 'package:go_router/go_router.dart';
import 'package:f0ckapp/models/mediaitem_model.dart';
@@ -14,7 +13,7 @@ class MediaTile extends StatelessWidget {
Widget build(BuildContext context) {
return InkWell(
onTap: () {
- context.push('/${item.id}', extra: true);
+ Navigator.pushNamed(context, '/${item.id}');
},
child: Stack(
fit: StackFit.expand,
diff --git a/pubspec.lock b/pubspec.lock
index d86de63..9fd5cef 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -240,14 +240,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.1"
- go_router:
- dependency: "direct main"
- description:
- name: go_router
- sha256: b453934c36e289cef06525734d1e676c1f91da9e22e2017d9dcab6ce0f999175
- url: "https://pub.dev"
- source: hosted
- version: "15.1.3"
html:
dependency: transitive
description:
@@ -312,14 +304,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.0.0"
- logging:
- dependency: transitive
- description:
- name: logging
- sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
- url: "https://pub.dev"
- source: hosted
- version: "1.3.0"
matcher:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index e6522b5..f1ed678 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -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
# 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.
-version: 1.1.22+52
+version: 1.1.23+53
environment:
sdk: ^3.9.0-100.2.beta
@@ -41,7 +41,6 @@ dependencies:
share_plus: ^11.0.0
flutter_secure_storage: ^9.2.4
flutter_riverpod: ^2.6.1
- go_router: ^15.1.3
dev_dependencies:
flutter_test: