173 lines
4.8 KiB
Dart
173 lines
4.8 KiB
Dart
import 'package:ente_auth/models/execution_states.dart';
|
|
import 'package:ente_auth/theme/ente_theme.dart';
|
|
import 'package:ente_auth/ui/common/loading_widget.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
class TrailingWidget extends StatefulWidget {
|
|
final ValueNotifier executionStateNotifier;
|
|
final IconData? trailingIcon;
|
|
final Color? trailingIconColor;
|
|
final Widget? trailingWidget;
|
|
final bool trailingIconIsMuted;
|
|
final double trailingExtraMargin;
|
|
final bool showExecutionStates;
|
|
const TrailingWidget({
|
|
Key? key,
|
|
required this.executionStateNotifier,
|
|
this.trailingIcon,
|
|
this.trailingIconColor,
|
|
this.trailingWidget,
|
|
required this.trailingIconIsMuted,
|
|
required this.trailingExtraMargin,
|
|
required this.showExecutionStates,
|
|
}) : super(key: key);
|
|
@override
|
|
State<TrailingWidget> createState() => _TrailingWidgetState();
|
|
}
|
|
|
|
class _TrailingWidgetState extends State<TrailingWidget> {
|
|
Widget? trailingWidget;
|
|
@override
|
|
void initState() {
|
|
widget.showExecutionStates
|
|
? widget.executionStateNotifier.addListener(_executionStateListener)
|
|
: null;
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
widget.executionStateNotifier.removeListener(_executionStateListener);
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (trailingWidget == null || !widget.showExecutionStates) {
|
|
_setTrailingIcon();
|
|
}
|
|
return AnimatedSwitcher(
|
|
duration: const Duration(milliseconds: 175),
|
|
switchInCurve: Curves.easeInExpo,
|
|
switchOutCurve: Curves.easeOutExpo,
|
|
child: trailingWidget,
|
|
);
|
|
}
|
|
|
|
void _executionStateListener() {
|
|
final colorScheme = getEnteColorScheme(context);
|
|
setState(() {
|
|
if (widget.executionStateNotifier.value == ExecutionState.idle) {
|
|
_setTrailingIcon();
|
|
} else if (widget.executionStateNotifier.value ==
|
|
ExecutionState.inProgress) {
|
|
trailingWidget = EnteLoadingWidget(
|
|
color: colorScheme.strokeMuted,
|
|
);
|
|
} else if (widget.executionStateNotifier.value ==
|
|
ExecutionState.successful) {
|
|
trailingWidget = Icon(
|
|
Icons.check_outlined,
|
|
size: 22,
|
|
color: colorScheme.primary500,
|
|
);
|
|
} else {
|
|
trailingWidget = const SizedBox.shrink();
|
|
}
|
|
});
|
|
}
|
|
|
|
void _setTrailingIcon() {
|
|
if (widget.trailingIcon != null) {
|
|
trailingWidget = Padding(
|
|
padding: EdgeInsets.only(
|
|
right: widget.trailingExtraMargin,
|
|
),
|
|
child: Icon(
|
|
widget.trailingIcon,
|
|
color: widget.trailingIconIsMuted
|
|
? getEnteColorScheme(context).strokeMuted
|
|
: widget.trailingIconColor,
|
|
),
|
|
);
|
|
} else {
|
|
trailingWidget = widget.trailingWidget ?? const SizedBox.shrink();
|
|
}
|
|
}
|
|
}
|
|
|
|
class ExpansionTrailingIcon extends StatelessWidget {
|
|
final bool isExpanded;
|
|
final IconData? trailingIcon;
|
|
final Color? trailingIconColor;
|
|
const ExpansionTrailingIcon({
|
|
Key? key,
|
|
required this.isExpanded,
|
|
this.trailingIcon,
|
|
this.trailingIconColor,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return AnimatedOpacity(
|
|
duration: const Duration(milliseconds: 100),
|
|
curve: Curves.easeInOut,
|
|
opacity: isExpanded ? 0 : 1,
|
|
child: AnimatedSwitcher(
|
|
transitionBuilder: (child, animation) {
|
|
return ScaleTransition(scale: animation, child: child);
|
|
},
|
|
duration: const Duration(milliseconds: 200),
|
|
switchInCurve: Curves.easeOut,
|
|
child: isExpanded
|
|
? const SizedBox.shrink()
|
|
: Icon(
|
|
trailingIcon,
|
|
color: trailingIconColor,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class LeadingWidget extends StatelessWidget {
|
|
final IconData? leadingIcon;
|
|
final Color? leadingIconColor;
|
|
|
|
final Widget? leadingIconWidget;
|
|
// leadIconSize deafult value is 20.
|
|
final double leadingIconSize;
|
|
const LeadingWidget({
|
|
Key? key,
|
|
required this.leadingIconSize,
|
|
this.leadingIcon,
|
|
this.leadingIconColor,
|
|
this.leadingIconWidget,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(right: 10),
|
|
child: SizedBox(
|
|
height: leadingIconSize,
|
|
width: leadingIconSize,
|
|
child: leadingIcon == null
|
|
? (leadingIconWidget != null
|
|
? FittedBox(
|
|
fit: BoxFit.contain,
|
|
child: leadingIconWidget,
|
|
)
|
|
: const SizedBox.shrink())
|
|
: FittedBox(
|
|
fit: BoxFit.contain,
|
|
child: Icon(
|
|
leadingIcon,
|
|
color: leadingIconColor ??
|
|
getEnteColorScheme(context).strokeBase,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|