import 'package:fl_clash/models/models.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class ScrollOverBuilder extends StatefulWidget { final Widget Function(bool isOver) builder; const ScrollOverBuilder({ super.key, required this.builder, }); @override State createState() => _ScrollOverBuilderState(); } class _ScrollOverBuilderState extends State { final isOverNotifier = ValueNotifier(false); @override void dispose() { isOverNotifier.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return NotificationListener( onNotification: (scrollNotification) { isOverNotifier.value = scrollNotification.metrics.maxScrollExtent > 0; return true; }, child: ValueListenableBuilder( valueListenable: isOverNotifier, builder: (_, isOver, __) { return widget.builder(isOver); }, ), ); } } class ProxiesActionsBuilder extends StatelessWidget { final Widget? child; final Widget Function( ProxiesActionsState state, Widget? child, ) builder; const ProxiesActionsBuilder({ super.key, required this.child, required this.builder, }); @override Widget build(BuildContext context) { return Selector( selector: (_, appState) => ProxiesActionsState( isCurrent: appState.currentLabel == "proxies", hasProvider: appState.providers.isNotEmpty, ), builder: (_, state, child) => builder(state, child), child: child, ); } } typedef StateWidgetBuilder = Widget Function(T state); typedef StateAndChildWidgetBuilder = Widget Function(T state, Widget? child); class LocaleBuilder extends StatelessWidget { final StateWidgetBuilder builder; const LocaleBuilder({ super.key, required this.builder, }); @override Widget build(BuildContext context) { return Selector( selector: (_, config) => config.appSetting.locale, builder: (_, state, __) { return builder(state); }, ); } } class ActiveBuilder extends StatelessWidget { final String label; final StateAndChildWidgetBuilder builder; final Widget? child; const ActiveBuilder({ super.key, required this.label, required this.builder, required this.child, }); @override Widget build(BuildContext context) { return Selector( selector: (_, appState) => appState.currentLabel == label, builder: (_, state, child) { return builder( state, child, ); }, child: child, ); } } class ThemeModeBuilder extends StatelessWidget { final StateWidgetBuilder builder; const ThemeModeBuilder({ super.key, required this.builder, }); @override Widget build(BuildContext context) { return Selector( selector: (_, config) => config.themeProps.themeMode, builder: (_, state, __) { return builder(state); }, ); } }