Skip to content

Commit

Permalink
Always render follow, menu and episode controls rather than once data…
Browse files Browse the repository at this point in the history
… is loaded to prevent jerky UI upon podcast load.
  • Loading branch information
amugofjava committed Apr 16, 2024
1 parent 7f76162 commit ed52876
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 82 deletions.
160 changes: 85 additions & 75 deletions lib/ui/podcast/podcast_details.dart
Original file line number Diff line number Diff line change
Expand Up @@ -626,77 +626,85 @@ class FollowButton extends StatelessWidget {
return StreamBuilder<BlocState<Podcast>>(
stream: bloc.details,
builder: (context, snapshot) {
var ready = false;
var subscribed = false;

// To prevent jumpy UI, we always need to display the follow/unfollow button.
// Display a disabled follow button until the full state it loaded.
if (snapshot.hasData) {
final state = snapshot.data;

if (state is BlocPopulatedState<Podcast>) {
var p = state.results!;

return Semantics(
liveRegion: true,
child: p.subscribed
? OutlinedButton.icon(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
),
icon: const Icon(
Icons.delete_outline,
),
label: Text(L.of(context)!.unsubscribe_label),
onPressed: () {
showPlatformDialog<void>(
context: context,
useRootNavigator: false,
builder: (_) => BasicDialogAlert(
title: Text(L.of(context)!.unsubscribe_label),
content: Text(L.of(context)!.unsubscribe_message),
actions: <Widget>[
BasicDialogAction(
title: ExcludeSemantics(
child: ActionText(
L.of(context)!.cancel_button_label,
ready = true;
subscribed = state.results!.subscribed;
}
}
return Semantics(
liveRegion: true,
child: subscribed
? OutlinedButton.icon(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
),
icon: const Icon(
Icons.delete_outline,
),
label: Text(L.of(context)!.unsubscribe_label),
onPressed: ready
? () {
showPlatformDialog<void>(
context: context,
useRootNavigator: false,
builder: (_) => BasicDialogAlert(
title: Text(L.of(context)!.unsubscribe_label),
content: Text(L.of(context)!.unsubscribe_message),
actions: <Widget>[
BasicDialogAction(
title: ExcludeSemantics(
child: ActionText(
L.of(context)!.cancel_button_label,
),
),
onPressed: () {
Navigator.pop(context);
},
),
onPressed: () {
Navigator.pop(context);
},
),
BasicDialogAction(
title: ExcludeSemantics(
child: ActionText(
L.of(context)!.unsubscribe_button_label,
BasicDialogAction(
title: ExcludeSemantics(
child: ActionText(
L.of(context)!.unsubscribe_button_label,
),
),
iosIsDefaultAction: true,
iosIsDestructiveAction: true,
onPressed: () {
bloc.podcastEvent(PodcastEvent.unsubscribe);

Navigator.pop(context);
Navigator.pop(context);
},
),
iosIsDefaultAction: true,
iosIsDestructiveAction: true,
onPressed: () {
bloc.podcastEvent(PodcastEvent.unsubscribe);

Navigator.pop(context);
Navigator.pop(context);
},
),
],
),
);
},
)
: OutlinedButton.icon(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
),
icon: const Icon(
Icons.add,
),
label: Text(L.of(context)!.subscribe_label),
onPressed: () {
bloc.podcastEvent(PodcastEvent.subscribe);
},
),
);
}
}
return Container();
],
),
);
}
: null,
)
: OutlinedButton.icon(
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
),
icon: const Icon(
Icons.add,
),
label: Text(L.of(context)!.subscribe_label),
onPressed: ready
? () {
bloc.podcastEvent(PodcastEvent.subscribe);
}
: null,
),
);
});
}
}
Expand All @@ -713,18 +721,19 @@ class FilterButton extends StatelessWidget {
return StreamBuilder<BlocState<Podcast>>(
stream: bloc.details,
builder: (context, snapshot) {
Podcast? podcast;

if (snapshot.hasData) {
final state = snapshot.data;

if (state is BlocPopulatedState<Podcast>) {
var p = state.results!;

return EpisodeFilterSelectorWidget(
podcast: p,
);
podcast = state.results!;
}
}
return Container();

return EpisodeFilterSelectorWidget(
podcast: podcast,
);
});
}
}
Expand All @@ -741,18 +750,19 @@ class SortButton extends StatelessWidget {
return StreamBuilder<BlocState<Podcast>>(
stream: bloc.details,
builder: (context, snapshot) {
Podcast? podcast;

if (snapshot.hasData) {
final state = snapshot.data;

if (state is BlocPopulatedState<Podcast>) {
var p = state.results!;

return EpisodeSortSelectorWidget(
podcast: p,
);
podcast = state.results!;
}
}
return Container();

return EpisodeSortSelectorWidget(
podcast: podcast,
);
});
}
}
8 changes: 4 additions & 4 deletions lib/ui/widgets/episode_filter_selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'package:provider/provider.dart';

/// This widget allows the user to filter the episodes.
class EpisodeFilterSelectorWidget extends StatefulWidget {
final Podcast podcast;
final Podcast? podcast;

const EpisodeFilterSelectorWidget({
required this.podcast,
Expand Down Expand Up @@ -44,12 +44,12 @@ class _EpisodeFilterSelectorWidgetState extends State<EpisodeFilterSelectorWidge
child: Center(
child: IconButton(
icon: Icon(
widget.podcast.filter == PodcastEpisodeFilter.none
widget.podcast == null || widget.podcast!.filter == PodcastEpisodeFilter.none
? Icons.filter_alt_outlined
: Icons.filter_alt_off_outlined,
semanticLabel: L.of(context)!.episode_filter_semantic_label,
),
onPressed: widget.podcast.subscribed
onPressed: widget.podcast != null && widget.podcast!.subscribed
? () {
showModalBottomSheet<void>(
isScrollControlled: true,
Expand All @@ -63,7 +63,7 @@ class _EpisodeFilterSelectorWidgetState extends State<EpisodeFilterSelectorWidge
),
builder: (context) {
return EpisodeFilterSlider(
podcast: widget.podcast,
podcast: widget.podcast!,
);
});
}
Expand Down
6 changes: 3 additions & 3 deletions lib/ui/widgets/episode_sort_selector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'package:provider/provider.dart';

/// This widget allows the user to filter the episodes.
class EpisodeSortSelectorWidget extends StatefulWidget {
final Podcast podcast;
final Podcast? podcast;

const EpisodeSortSelectorWidget({
required this.podcast,
Expand Down Expand Up @@ -47,7 +47,7 @@ class _EpisodeSortSelectorWidgetState extends State<EpisodeSortSelectorWidget> {
Icons.sort,
semanticLabel: L.of(context)!.episode_sort_semantic_label,
),
onPressed: widget.podcast.subscribed
onPressed: widget.podcast != null && widget.podcast!.subscribed
? () {
showModalBottomSheet<void>(
isScrollControlled: true,
Expand All @@ -61,7 +61,7 @@ class _EpisodeSortSelectorWidgetState extends State<EpisodeSortSelectorWidget> {
),
builder: (context) {
return EpisodeSortSlider(
podcast: widget.podcast,
podcast: widget.podcast!,
);
});
}
Expand Down

0 comments on commit ed52876

Please sign in to comment.