v1.2.1+55
All checks were successful
Flutter Schmutter / build (push) Successful in 3m42s

- fix deeplink
- add mute button
This commit is contained in:
Flummi 2025-06-13 15:01:48 +02:00
parent 9655f15927
commit 2a500144f5
7 changed files with 46 additions and 14 deletions

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
// Definiere deine Themes wie gehabt:
final ThemeData f0ckTheme = ThemeData( final ThemeData f0ckTheme = ThemeData(
brightness: Brightness.dark, brightness: Brightness.dark,
primaryColor: const Color(0xFF9FFF00), primaryColor: const Color(0xFF9FFF00),

View File

@ -44,7 +44,9 @@ class _DetailViewState extends State<DetailView> {
Future<void> _fetchAndPreloadMedia(int targetId) async { Future<void> _fetchAndPreloadMedia(int targetId) async {
try { try {
await apiService.setTag(null); WidgetsBinding.instance.addPostFrameCallback((_) async {
await apiService.setTag(null);
});
await apiService.fetchMedia(id: targetId + 50, reset: false); await apiService.fetchMedia(id: targetId + 50, reset: false);
_initializePageController(); _initializePageController();
} catch (e) { } catch (e) {

View File

@ -125,10 +125,6 @@ class _MediaGrid extends State<MediaGrid> {
], ],
), ),
bottomNavigationBar: FilterBar(scrollController: _scrollController), bottomNavigationBar: FilterBar(scrollController: _scrollController),
floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),
); );
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:f0ckapp/models/mediaitem_model.dart'; import 'package:f0ckapp/models/mediaitem_model.dart';
@ -8,11 +9,15 @@ 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 ApiService extends GetConnect { class ApiService extends GetConnect {
final _storage = const FlutterSecureStorage(
aOptions: AndroidOptions(encryptedSharedPreferences: true),
);
RxList<MediaItem> mediaItems = <MediaItem>[].obs; RxList<MediaItem> mediaItems = <MediaItem>[].obs;
RxnString tag = RxnString(); RxnString tag = RxnString();
RxInt type = 0.obs; RxInt type = 0.obs;
RxInt mode = 0.obs; RxInt mode = 0.obs;
RxBool random = false.obs; RxBool random = false.obs;
RxBool muted = false.obs;
bool _isFetching = false; bool _isFetching = false;
DateTime? _lastFetchTime; DateTime? _lastFetchTime;
@ -21,9 +26,20 @@ class ApiService extends GetConnect {
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
loadMutedState();
everAll([tag, type, mode, random], (_) => fetchMedia(reset: true)); everAll([tag, type, mode, random], (_) => fetchMedia(reset: true));
} }
Future<void> loadMutedState() async {
String? value = await _storage.read(key: 'muted');
muted.value = value == 'true';
}
Future<void> toggleMuted() async {
muted.value = !muted.value;
await _storage.write(key: 'muted', value: muted.value.toString());
}
Future<void> setTag(String? newTag) async { Future<void> setTag(String? newTag) async {
tag.value = newTag; tag.value = newTag;
return await fetchMedia(reset: true); return await fetchMedia(reset: true);

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:f0ckapp/services/api_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cached_video_player_plus/cached_video_player_plus.dart'; import 'package:cached_video_player_plus/cached_video_player_plus.dart';
@ -7,6 +8,7 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:f0ckapp/models/mediaitem_model.dart'; import 'package:f0ckapp/models/mediaitem_model.dart';
import 'package:f0ckapp/widgets/videooverlay_widget.dart'; import 'package:f0ckapp/widgets/videooverlay_widget.dart';
import 'package:get/get.dart';
class VideoWidget extends StatefulWidget { class VideoWidget extends StatefulWidget {
final MediaItem details; final MediaItem details;
@ -25,6 +27,7 @@ class VideoWidget extends StatefulWidget {
} }
class _VideoWidgetState extends State<VideoWidget> { class _VideoWidgetState extends State<VideoWidget> {
final ApiService apiService = Get.find<ApiService>();
late CachedVideoPlayerPlusController _controller; late CachedVideoPlayerPlusController _controller;
bool _showControls = false; bool _showControls = false;
Timer? _hideControlsTimer; Timer? _hideControlsTimer;
@ -49,8 +52,7 @@ class _VideoWidgetState extends State<VideoWidget> {
} }
_controller.setLooping(true); _controller.setLooping(true);
//final bool muted = ref.read(mediaProvider).muted; _controller.setVolume(apiService.muted.value ? 0.0 : 1.0);
//_controller.setVolume(muted ? 0.0 : 1.0);
} }
@override @override
@ -86,11 +88,11 @@ class _VideoWidgetState extends State<VideoWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//final bool muted = ref.watch(mediaProvider).muted; final bool muted = apiService.muted.value;
//if (_controller.value.isInitialized && if (_controller.value.isInitialized &&
// _controller.value.volume != (muted ? 0.0 : 1.0)) { _controller.value.volume != (muted ? 0.0 : 1.0)) {
// _controller.setVolume(muted ? 0.0 : 1.0); _controller.setVolume(muted ? 0.0 : 1.0);
//} }
bool isAudio = widget.details.mime.startsWith('audio'); bool isAudio = widget.details.mime.startsWith('audio');

View File

@ -1,6 +1,8 @@
import 'package:f0ckapp/services/api_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cached_video_player_plus/cached_video_player_plus.dart'; import 'package:cached_video_player_plus/cached_video_player_plus.dart';
import 'package:get/get.dart';
class VideoControlsOverlay extends StatelessWidget { class VideoControlsOverlay extends StatelessWidget {
final CachedVideoPlayerPlusController controller; final CachedVideoPlayerPlusController controller;
@ -14,10 +16,25 @@ class VideoControlsOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ApiService apiService = Get.find<ApiService>();
return Stack( return Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
Positioned(
right: 12,
bottom: 12,
child: Obx(
() => _ControlButton(
apiService.muted.value ? Icons.volume_off : Icons.volume_up,
() async {
button();
await apiService.toggleMuted();
},
size: 16,
),
),
),
Center( Center(
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,

View File

@ -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.2.0+54 version: 1.2.1+55
environment: environment:
sdk: ^3.9.0-100.2.beta sdk: ^3.9.0-100.2.beta