import 'package:get/get.dart'; import 'package:encrypt_shared_preferences/provider.dart'; import 'package:f0ckapp/models/feed.dart'; import 'package:f0ckapp/models/item.dart'; import 'package:f0ckapp/services/api.dart'; import 'package:f0ckapp/utils/animatedtransition.dart'; const List mediaTypes = ["alles", "image", "video", "audio"]; const List mediaModes = ["sfw", "nsfw", "untagged", "all"]; class MediaController extends GetxController { final ApiService _api = ApiService(); final EncryptedSharedPreferencesAsync storage = EncryptedSharedPreferencesAsync.getInstance(); RxList items = [].obs; RxBool loading = false.obs; RxBool atEnd = false.obs; RxBool atStart = false.obs; RxInt typeIndex = 0.obs; RxInt modeIndex = 0.obs; RxInt random = 0.obs; Rxn tag = Rxn(); RxBool muted = false.obs; Rx transitionType = PageTransition.opacity.obs; RxBool drawerSwipeEnabled = true.obs; RxInt crossAxisCount = 0.obs; void setTypeIndex(int idx) { typeIndex.value = idx; fetchInitial(); } void setModeIndex(int idx) { modeIndex.value = idx; fetchInitial(); } void setTag(String? newTag, {bool reload = true}) { tag.value = newTag; if (reload) { fetchInitial(); } } List get filteredItems { final String typeStr = mediaTypes[typeIndex.value]; return items.where((item) { final bool typeOk = typeStr == "alles" || item.mime.startsWith(typeStr); return typeOk; }).toList(); } Future?> toggleFavorite( MediaItem item, bool isFavorite, ) async { try { return await _api.toggleFavorite(item, isFavorite); } catch (e) { return []; } } Future fetchInitial({int? id}) async { loading.value = true; try { final Feed result = await _api.fetchItems( type: typeIndex.value, mode: modeIndex.value, random: random.value, tag: tag.value, older: id, ); items.assignAll(result.items); atEnd.value = result.atEnd; atStart.value = result.atStart; } finally { loading.value = false; } } Future fetchMore() async { if (items.isEmpty || atEnd.value) return; loading.value = true; try { final Feed result = await _api.fetchItems( older: items.last.id, type: typeIndex.value, mode: modeIndex.value, random: random.value, tag: tag.value, ); final List newItems = result.items .where((item) => !items.any((existing) => existing.id == item.id)) .toList(); items.addAll(newItems); items.refresh(); atEnd.value = result.atEnd; } finally { loading.value = false; } } Future fetchNewer() async { if (items.isEmpty || atStart.value) return 0; loading.value = true; try { final Feed result = await _api.fetchItems( newer: items.first.id, type: typeIndex.value, mode: modeIndex.value, random: random.value, tag: tag.value, ); int oldLength = filteredItems.length; final List newItems = result.items .where((item) => !items.any((existing) => existing.id == item.id)) .toList(); items.insertAll(0, newItems); items.refresh(); atStart.value = result.atStart; int newLength = filteredItems.length; return newLength - oldLength; } finally { loading.value = false; } } void toggleMuted() { muted.value = !muted.value; } void setMuted(bool value) { muted.value = value; } Future setTransitionType(PageTransition type) async { transitionType.value = type; await saveSettings(); } Future setCrossAxisCount(int value) async { crossAxisCount.value = value; await saveSettings(); } Future setDrawerSwipeEnabled(bool enabled) async { drawerSwipeEnabled.value = enabled; await saveSettings(); } void toggleRandom() { random.value = random.value == 1 ? 0 : 1; fetchInitial(); } @override void onInit() async { super.onInit(); await loadSettings(); } Future loadSettings() async { muted.value = await storage.getBoolean('muted') ?? false; crossAxisCount.value = await storage.getInt('crossAxisCount') ?? 0; drawerSwipeEnabled.value = await storage.getBoolean('drawerSwipeEnabled') ?? true; transitionType.value = PageTransition.values[await storage.getInt('transitionType') ?? 0]; } Future saveSettings() async { await storage.setBoolean('muted', muted.value); await storage.setInt('crossAxisCount', crossAxisCount.value); await storage.setBoolean('drawerSwipeEnabled', drawerSwipeEnabled.value); await storage.setInt('transitionType', transitionType.value.index); } }