updates
This commit is contained in:
parent
d558aba246
commit
3bd713d667
17 changed files with 1566 additions and 132 deletions
|
|
@ -73,6 +73,18 @@ class SettingsScreen extends ConsumerWidget {
|
|||
labelFor: AppSettings.formatLabel,
|
||||
onSelect: controller.setDownloadFormat,
|
||||
),
|
||||
const SizedBox(height: TimbreSpacing.lg),
|
||||
const _Caption(
|
||||
'How many tracks download at once. Higher is faster on '
|
||||
'a strong connection; lower is gentler on the server.'),
|
||||
const SizedBox(height: TimbreSpacing.md),
|
||||
_Stepper(
|
||||
label: 'Simultaneous downloads',
|
||||
value: settings.maxConcurrentDownloads,
|
||||
min: AppSettings.minConcurrentDownloads,
|
||||
max: AppSettings.maxConcurrentDownloadsCap,
|
||||
onChanged: controller.setMaxConcurrentDownloads,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -380,6 +392,101 @@ class _Chip extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
/// A labelled −/value/+ stepper bounded to [[min], [max]], styled to match the
|
||||
/// bordered-chip language of [_ChoiceChips].
|
||||
class _Stepper extends StatelessWidget {
|
||||
const _Stepper({
|
||||
required this.label,
|
||||
required this.value,
|
||||
required this.min,
|
||||
required this.max,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
final String label;
|
||||
final int value;
|
||||
final int min;
|
||||
final int max;
|
||||
final ValueChanged<int> onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final accent = Theme.of(context).colorScheme.primary;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(label, style: const TextStyle(color: TimbreColors.foreground)),
|
||||
const SizedBox(height: TimbreSpacing.sm),
|
||||
Row(
|
||||
children: [
|
||||
_StepButton(
|
||||
icon: Icons.remove,
|
||||
accent: accent,
|
||||
enabled: value > min,
|
||||
onTap: () => onChanged(value - 1),
|
||||
),
|
||||
Container(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: TimbreSpacing.minTouchTarget,
|
||||
minHeight: TimbreSpacing.minTouchTarget),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'$value',
|
||||
style: const TextStyle(
|
||||
color: TimbreColors.foreground,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
_StepButton(
|
||||
icon: Icons.add,
|
||||
accent: accent,
|
||||
enabled: value < max,
|
||||
onTap: () => onChanged(value + 1),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _StepButton extends StatelessWidget {
|
||||
const _StepButton({
|
||||
required this.icon,
|
||||
required this.accent,
|
||||
required this.enabled,
|
||||
required this.onTap,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final Color accent;
|
||||
final bool enabled;
|
||||
final VoidCallback onTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: enabled ? onTap : null,
|
||||
child: Container(
|
||||
constraints: const BoxConstraints(
|
||||
minWidth: TimbreSpacing.minTouchTarget,
|
||||
minHeight: TimbreSpacing.minTouchTarget),
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: TimbreColors.border),
|
||||
color: TimbreColors.surface,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 18,
|
||||
color: enabled ? accent : TimbreColors.dimmed,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// A row of accent-color chips — like [_ChoiceChips] but each chip shows a
|
||||
/// color swatch and the color's own hue drives the active border/fill.
|
||||
class _ColorChips extends StatelessWidget {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue