Compare commits

..

3 Commits

Author SHA1 Message Date
Kingkor Roy Tirtho
c709de6bf1 fix: language picker search broken 2025-03-10 20:44:52 +06:00
Kingkor Roy Tirtho
ccbac85171 chore: remove GeistMono 2025-03-10 20:15:28 +06:00
Kingkor Roy Tirtho
50123b235c fix: add to playlist not working in smaller screen devices 2025-03-10 20:07:51 +06:00
5 changed files with 36 additions and 211 deletions

View File

@ -1,126 +0,0 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class AnimateGradient extends HookWidget {
const AnimateGradient({
super.key,
required this.primaryColors,
required this.secondaryColors,
this.child,
this.primaryBegin,
this.primaryEnd,
this.secondaryBegin,
this.secondaryEnd,
AnimationController? controller,
this.duration = const Duration(seconds: 4),
this.animateAlignments = true,
this.reverse = true,
}) : assert(primaryColors.length >= 2),
assert(primaryColors.length == secondaryColors.length),
_controller = controller;
/// [controller]: pass this to have a fine control over the [Animation]
final AnimationController? _controller;
/// [duration]: Time to switch between [Gradient].
/// By default its value is [Duration(seconds:4)]
final Duration duration;
/// [primaryColors]: These will be the starting colors of the [Animation].
final List<Color> primaryColors;
/// [secondaryColors]: These Colors are those in which the [primaryColors] will transition into.
final List<Color> secondaryColors;
/// [primaryBegin]: This is begin [Alignment] for [primaryColors].
/// By default its value is [Alignment.topLeft]
final Alignment? primaryBegin;
/// [primaryBegin]: This is end [Alignment] for [primaryColors].
/// By default its value is [Alignment.topRight]
final Alignment? primaryEnd;
/// [secondaryBegin]: This is begin [Alignment] for [secondaryColors].
/// By default its value is [Alignment.bottomLeft]
final Alignment? secondaryBegin;
/// [secondaryEnd]: This is end [Alignment] for [secondaryColors].
/// By default its value is [Alignment.bottomRight]
final Alignment? secondaryEnd;
/// [animateAlignments]: set to false if you don't want to animate the alignments.
/// This can provide you way cooler animations
final bool animateAlignments;
/// [reverse]: set it to false if you don't want to reverse the animation.
/// using that it will go into one direction only
final bool reverse;
final Widget? child;
@override
Widget build(BuildContext context) {
// ignore: no_leading_underscores_for_local_identifiers
final __controller = useAnimationController(
duration: duration,
)..repeat(reverse: reverse);
final controller = _controller ?? __controller;
final animation = useMemoized(
() => CurvedAnimation(
parent: controller,
curve: Curves.easeInOut,
),
[controller]);
final colorTween = useMemoized(
() => primaryColors.map((color) {
return ColorTween(
begin: color,
end: color,
);
}).toList(),
[primaryColors]);
final colors = useMemoized(
() => colorTween.map((color) {
return color.evaluate(animation)!;
}).toList(),
[colorTween, animation]);
final begin = useMemoized(
() => AlignmentTween(
begin: primaryBegin ?? Alignment.topLeft,
end: primaryEnd ?? Alignment.topRight,
),
[primaryBegin, primaryEnd]);
final end = useMemoized(
() => AlignmentTween(
begin: secondaryBegin ?? Alignment.bottomLeft,
end: secondaryEnd ?? Alignment.bottomRight,
),
[secondaryBegin, secondaryEnd]);
return AnimatedBuilder(
animation: animation,
child: useMemoized(() => child, [child]),
builder: (BuildContext context, Widget? child) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: animateAlignments
? begin.evaluate(animation)
: (primaryBegin as Alignment),
end: animateAlignments
? end.evaluate(animation)
: primaryEnd as Alignment,
colors: colors,
),
),
child: child,
);
},
);
}
}

View File

@ -1,24 +0,0 @@
import 'package:shadcn_flutter/shadcn_flutter.dart';
class SpotubePage<T> extends MaterialPage<T> {
const SpotubePage({required super.child});
}
// class SpotubeSlidePage extends CustomTransitionPage {
// SpotubeSlidePage({
// required super.child,
// super.key,
// }) : super(
// reverseTransitionDuration: const Duration(milliseconds: 150),
// transitionDuration: const Duration(milliseconds: 150),
// transitionsBuilder: (context, animation, secondaryAnimation, child) {
// return SlideTransition(
// position: Tween<Offset>(
// begin: const Offset(1, 0),
// end: Offset.zero,
// ).animate(animation),
// child: child,
// );
// },
// );
// }

View File

@ -90,11 +90,25 @@ class TrackOptions extends HookConsumerWidget {
BuildContext context,
Track track,
) {
showDialog(
context: context,
builder: (context) => PlaylistAddTrackDialog(
tracks: [track],
openFromPlaylist: playlistId,
/// showDialog doesn't work for some reason. So we have to
/// manually push a Dialog Route in the Navigator to get it working
Navigator.push(
context,
DialogRoute(
alignment: Alignment.bottomCenter,
transitionBuilder: (context, animation, secondaryAnimation, child) {
return FadeTransition(opacity: animation, child: child);
},
context: context,
barrierColor: Colors.black.withValues(alpha: 0.5),
builder: (context) {
return Center(
child: PlaylistAddTrackDialog(
tracks: [track],
openFromPlaylist: playlistId,
),
);
},
),
);
}

View File

@ -133,37 +133,38 @@ class GettingStartedPageLanguageRegionSection extends HookConsumerWidget {
popup: SelectPopup.builder(
searchPlaceholder: Text(context.l10n.search),
builder: (context, searchQuery) {
final filteredLocale = searchQuery?.isNotEmpty != true
? L10n.all
final hasNotQueried =
searchQuery == null || searchQuery.trim().isEmpty;
final filteredLocale = hasNotQueried
? [
const Locale("system", "system"),
...L10n.all,
]
: L10n.all
.where(
(element) =>
filterLocale(element, searchQuery!),
(element) => filterLocale(
element,
searchQuery.trim(),
),
)
.toList();
return SelectItemBuilder(
childCount: filteredLocale.length + 1,
childCount: filteredLocale.length,
builder: (context, index) {
if (index == 0 &&
searchQuery?.isNotEmpty != true) {
final locale = filteredLocale[index];
if (locale == const Locale("system", "system")) {
return SelectItemButton(
value: const Locale("system", "system"),
value: locale,
child: Text(context.l10n.system_default),
);
}
final indexThen = searchQuery?.isNotEmpty != true
? index
: index - 1;
final locale = filteredLocale[indexThen];
return SelectItemButton(
value: locale,
child: Text(
LanguageLocals.getDisplayLanguage(
locale.languageCode)
.toString(),
locale.languageCode,
).toString(),
),
);
},

View File

@ -193,46 +193,6 @@ flutter:
- packages/flutter_undraw/assets/undraw/empty.svg
- packages/flutter_undraw/assets/undraw/no_data.svg
fonts:
- family: GeistSans
fonts:
- asset: packages/shadcn_flutter/fonts/Geist-Black.otf
weight: 800
- asset: packages/shadcn_flutter/fonts/Geist-Bold.otf
weight: 700
- asset: packages/shadcn_flutter/fonts/Geist-Light.otf
weight: 300
- asset: packages/shadcn_flutter/fonts/Geist-Medium.otf
weight: 500
- asset: packages/shadcn_flutter/fonts/Geist-SemiBold.otf
weight: 600
- asset: packages/shadcn_flutter/fonts/Geist-Thin.otf
weight: 100
- asset: packages/shadcn_flutter/fonts/Geist-UltraBlack.otf
weight: 900
- asset: packages/shadcn_flutter/fonts/Geist-UltraLight.otf
weight: 200
- asset: packages/shadcn_flutter/fonts/Geist-Regular.otf
weight: 400
- family: GeistMono
fonts:
- asset: packages/shadcn_flutter/fonts/GeistMono-Black.otf
weight: 800
- asset: packages/shadcn_flutter/fonts/GeistMono-Bold.otf
weight: 700
- asset: packages/shadcn_flutter/fonts/GeistMono-Light.otf
weight: 300
- asset: packages/shadcn_flutter/fonts/GeistMono-Medium.otf
weight: 500
- asset: packages/shadcn_flutter/fonts/GeistMono-Regular.otf
weight: 400
- asset: packages/shadcn_flutter/fonts/GeistMono-SemiBold.otf
weight: 600
- asset: packages/shadcn_flutter/fonts/GeistMono-Thin.otf
weight: 100
- asset: packages/shadcn_flutter/fonts/GeistMono-UltraBlack.otf
weight: 900
- asset: packages/shadcn_flutter/fonts/GeistMono-UltraLight.otf
weight: 200
- family: RadixIcons
fonts:
- asset: packages/shadcn_flutter/icons/RadixIcons.otf