195 lines
5.2 KiB
Dart
195 lines
5.2 KiB
Dart
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<String> mediaTypes = ["alles", "image", "video", "audio"];
|
|
const List<String> mediaModes = ["sfw", "nsfw", "untagged", "all"];
|
|
|
|
class MediaController extends GetxController {
|
|
final ApiService _api = Get.find<ApiService>();
|
|
final EncryptedSharedPreferencesAsync storage =
|
|
EncryptedSharedPreferencesAsync.getInstance();
|
|
|
|
RxList<MediaItem> items = <MediaItem>[].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<String> tag = Rxn<String>(null);
|
|
RxBool muted = false.obs;
|
|
Rx<PageTransition> transitionType = PageTransition.opacity.obs;
|
|
RxBool drawerSwipeEnabled = true.obs;
|
|
RxInt crossAxisCount = 0.obs;
|
|
RxInt videoControlsTimerNotifier = 0.obs;
|
|
RxInt hideControlsNotifier = 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();
|
|
}
|
|
}
|
|
|
|
Future<List<Favorite>?> toggleFavorite(
|
|
MediaItem item,
|
|
bool isFavorite,
|
|
) async {
|
|
try {
|
|
return await _api.toggleFavorite(item, isFavorite);
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
Future<Feed?> _fetchItems({int? older, int? newer}) async {
|
|
if (loading.value) return null;
|
|
loading.value = true;
|
|
try {
|
|
return await _api.fetchItems(
|
|
older: older,
|
|
newer: newer,
|
|
type: typeIndex.value,
|
|
mode: modeIndex.value,
|
|
random: random.value,
|
|
tag: tag.value,
|
|
);
|
|
} catch (e) {
|
|
Get.snackbar(
|
|
'Fehler beim Laden',
|
|
'Die Daten konnten nicht abgerufen werden. Wo Internet?',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
return null;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
Future<void> fetchInitial({int? id}) async {
|
|
final result = await _fetchItems(older: id);
|
|
if (result != null) {
|
|
items.assignAll(result.items);
|
|
atEnd.value = result.atEnd;
|
|
atStart.value = result.atStart;
|
|
}
|
|
}
|
|
|
|
Future<void> fetchMore() async {
|
|
if (items.isEmpty || atEnd.value) return;
|
|
final result = await _fetchItems(older: items.last.id);
|
|
if (result != null) {
|
|
final Set<int> existingIds = items.map((e) => e.id).toSet();
|
|
final List<MediaItem> newItems = result.items
|
|
.where((item) => !existingIds.contains(item.id))
|
|
.toList();
|
|
items.addAll(newItems);
|
|
items.refresh();
|
|
atEnd.value = result.atEnd;
|
|
}
|
|
}
|
|
|
|
Future<int> fetchNewer() async {
|
|
if (items.isEmpty || atStart.value) return 0;
|
|
final oldLength = items.length;
|
|
final result = await _fetchItems(newer: items.first.id);
|
|
if (result != null) {
|
|
final Set<int> existingIds = items.map((e) => e.id).toSet();
|
|
final List<MediaItem> newItems = result.items
|
|
.where((item) => !existingIds.contains(item.id))
|
|
.toList();
|
|
items.insertAll(0, newItems);
|
|
items.refresh();
|
|
atStart.value = result.atStart;
|
|
return items.length - oldLength;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
Future<void> handleRefresh() async {
|
|
if (loading.value) return;
|
|
if (!atStart.value) {
|
|
await fetchNewer();
|
|
} else {
|
|
await fetchInitial();
|
|
}
|
|
}
|
|
|
|
Future<void> handleLoading() async {
|
|
if (!loading.value && !atEnd.value) {
|
|
await fetchMore();
|
|
}
|
|
}
|
|
|
|
void toggleMuted() {
|
|
muted.value = !muted.value;
|
|
}
|
|
|
|
void setMuted(bool value) {
|
|
muted.value = value;
|
|
}
|
|
|
|
Future<void> setTransitionType(PageTransition type) async {
|
|
transitionType.value = type;
|
|
await saveSettings();
|
|
}
|
|
|
|
Future<void> setCrossAxisCount(int value) async {
|
|
crossAxisCount.value = value;
|
|
await saveSettings();
|
|
}
|
|
|
|
Future<void> setDrawerSwipeEnabled(bool enabled) async {
|
|
drawerSwipeEnabled.value = enabled;
|
|
await saveSettings();
|
|
}
|
|
|
|
void toggleRandom() {
|
|
random.value = random.value == 1 ? 0 : 1;
|
|
fetchInitial();
|
|
}
|
|
|
|
void resetVideoControlsTimer() => videoControlsTimerNotifier.value++;
|
|
void hideVideoControls() => hideControlsNotifier.value++;
|
|
|
|
@override
|
|
void onInit() async {
|
|
super.onInit();
|
|
await loadSettings();
|
|
}
|
|
|
|
Future<void> 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<void> 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);
|
|
}
|
|
|
|
bool get isRandomEnabled => random.value == 1;
|
|
}
|