Update project

This commit is contained in:
2026-07-23 15:36:11 +05:30
parent 1197cfc161
commit 14fffa40c6
84 changed files with 20918 additions and 2761 deletions

View File

@@ -0,0 +1,120 @@
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
/// Manages all scroll, cart-bar visibility, back-to-top, and
/// network-retry logic for StoreViewPage.
class StoreViewController extends GetxController {
// ── Scroll ──────────────────────────────────────────────
final ScrollController scrollController = ScrollController();
double scrollOffset = 0.0;
bool showBackToTop = false;
bool hideCartBar = false;
Timer? _cartTimer;
// ── Mini-cart ────────────────────────────────────────────
RxBool showMiniCart = false.obs;
// ── Search ───────────────────────────────────────────────
final TextEditingController searchController = TextEditingController();
// ── Misc ─────────────────────────────────────────────────
var selectedCategoryId = 0.obs;
@override
void onInit() {
super.onInit();
scrollController.addListener(_onScroll);
}
@override
void onClose() {
scrollController.removeListener(_onScroll);
scrollController.dispose();
searchController.dispose();
_cartTimer?.cancel();
super.onClose();
}
// ── Scroll handler (used by the ScrollController listener) ──
void _onScroll() {
scrollOffset = scrollController.offset;
showBackToTop = scrollController.offset > 300;
update(['scroll']);
}
// ── Notification-based handler (NestedScrollView body) ──────
bool handleScrollNotification(ScrollNotification notification) {
if (notification is ScrollUpdateNotification &&
notification.metrics.axis == Axis.vertical) {
final double pixels = notification.metrics.pixels;
final bool isScrollingUp = pixels < scrollOffset;
scrollOffset = pixels;
if (isScrollingUp && pixels > 300) {
showBackToTop = true;
} else if (pixels <= 300 || !isScrollingUp) {
showBackToTop = false;
}
// Hide cart bar immediately on scroll
if (!hideCartBar) {
hideCartBar = true;
showMiniCart.value = false;
update(['cartBar']);
}
// Re-show cart bar after scroll stops
_cartTimer?.cancel();
_cartTimer = Timer(const Duration(milliseconds: 250), () {
if (hideCartBar) {
hideCartBar = false;
update(['cartBar']);
}
});
update(['scroll']);
}
return false;
}
// ── Background colour based on scroll position ───────────────
Color backgroundColorFor(List<Color> colors) {
if (colors.isEmpty) return Colors.white;
return colors[(scrollOffset ~/ 300) % colors.length];
}
// ── Scroll to top ─────────────────────────────────────────────
void scrollToTop() {
scrollController.animateTo(
0,
duration: const Duration(milliseconds: 400),
curve: Curves.easeOut,
);
}
// ── Network retry ─────────────────────────────────────────────
Future<void> retryNetworkCall(Future<void> Function() onSuccess) async {
final connectivityResult = await Connectivity().checkConnectivity();
if (connectivityResult == ConnectivityResult.mobile ||
connectivityResult == ConnectivityResult.wifi) {
debugPrint('✅ Internet available, retrying...');
await onSuccess();
} else {
debugPrint('❌ Still no internet connection');
Get.snackbar(
'No Internet',
'Please check your connection and try again.',
backgroundColor: Colors.grey[200],
colorText: Colors.black,
snackPosition: SnackPosition.TOP,
);
}
}
}