mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-21 06:52:18 +02:00
140 lines
4.5 KiB
Dart
140 lines
4.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:material_3_expressive/material_3_expressive.dart';
|
|
import 'package:spotiflac_android/theme/material_expressive.dart';
|
|
|
|
/// Task progress (downloads, scans, updates), determinate or not.
|
|
///
|
|
/// The Material theme draws the expressive wavy indicators. Mornye and
|
|
/// reduced motion keep Flutter's flat indicators with the same parameters.
|
|
class AppProgressIndicator extends StatelessWidget {
|
|
const AppProgressIndicator.linear({
|
|
super.key,
|
|
this.value,
|
|
this.color,
|
|
this.trackColor,
|
|
this.minHeight,
|
|
this.borderRadius,
|
|
this.semanticsLabel,
|
|
this.semanticsValue,
|
|
this.wavy = true,
|
|
}) : strokeWidth = null,
|
|
strokeCap = null,
|
|
_circular = false;
|
|
|
|
/// Fills the smaller side of its parent, or 48dp when unbounded.
|
|
const AppProgressIndicator.circular({
|
|
super.key,
|
|
this.value,
|
|
this.color,
|
|
this.trackColor,
|
|
this.strokeWidth,
|
|
this.strokeCap,
|
|
this.semanticsLabel,
|
|
this.semanticsValue,
|
|
this.wavy = true,
|
|
}) : minHeight = null,
|
|
borderRadius = null,
|
|
_circular = true;
|
|
|
|
/// Progress in `0..1`, or null for indeterminate.
|
|
final double? value;
|
|
final Color? color;
|
|
final Color? trackColor;
|
|
|
|
/// Height of the flat linear fallback; the wavy track keeps its own height.
|
|
final double? minHeight;
|
|
final BorderRadiusGeometry? borderRadius;
|
|
final double? strokeWidth;
|
|
|
|
/// Cap of the flat circular fallback; the wavy stroke is always round.
|
|
final StrokeCap? strokeCap;
|
|
final String? semanticsLabel;
|
|
final String? semanticsValue;
|
|
|
|
/// Whether determinate progress waves. Values that only change on a new
|
|
/// step or refresh, such as goals, use the flat expressive track at the
|
|
/// caller's thickness instead.
|
|
final bool wavy;
|
|
final bool _circular;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final value = this.value?.clamp(0.0, 1.0);
|
|
if (!materialExpressiveEnabled(context)) {
|
|
return _circular
|
|
? CircularProgressIndicator(
|
|
value: value,
|
|
color: color,
|
|
backgroundColor: trackColor,
|
|
strokeWidth: strokeWidth,
|
|
strokeCap: strokeCap,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
)
|
|
: LinearProgressIndicator(
|
|
value: value,
|
|
color: color,
|
|
backgroundColor: trackColor,
|
|
minHeight: minHeight,
|
|
borderRadius: borderRadius,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
);
|
|
}
|
|
final scheme = Theme.of(context).colorScheme;
|
|
// Indeterminate progress always waves.
|
|
final wavy = this.wavy || value == null;
|
|
if (!_circular) {
|
|
return MaterialExpressiveScope(
|
|
child: wavy
|
|
? M3EProgressIndicator.linearWavy(
|
|
value: value,
|
|
color: color ?? scheme.primary,
|
|
trackColor: trackColor,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
)
|
|
: M3EProgressIndicator.linear(
|
|
value: value,
|
|
linearSize: M3EProgressIndicatorSize.s,
|
|
strokeWidth: minHeight,
|
|
trackStrokeWidth: minHeight,
|
|
color: color ?? scheme.primary,
|
|
trackColor: trackColor,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
),
|
|
);
|
|
}
|
|
return LayoutBuilder(
|
|
builder: (context, constraints) {
|
|
final side = constraints.biggest.shortestSide;
|
|
final size = side.isFinite ? side : null;
|
|
return MaterialExpressiveScope(
|
|
child: wavy
|
|
? M3EProgressIndicator.circularWavy(
|
|
value: value,
|
|
size: size,
|
|
color: color ?? scheme.primary,
|
|
trackColor: trackColor,
|
|
strokeWidth: strokeWidth,
|
|
trackStrokeWidth: strokeWidth,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
)
|
|
: M3EProgressIndicator.circular(
|
|
value: value,
|
|
size: size,
|
|
color: color ?? scheme.primary,
|
|
trackColor: trackColor,
|
|
strokeWidth: strokeWidth,
|
|
trackStrokeWidth: strokeWidth,
|
|
semanticsLabel: semanticsLabel,
|
|
semanticsValue: semanticsValue,
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|