Skip to content

Commit

Permalink
feat(yt): list user history
Browse files Browse the repository at this point in the history
(horizontal list in playlists page & dedicated vertical page)
this includes improvements for lazy list & changes for main fetcher page
ref #227
  • Loading branch information
MSOB7YY committed Jul 15, 2024
1 parent 34a10fe commit 0addb27
Show file tree
Hide file tree
Showing 14 changed files with 684 additions and 150 deletions.
52 changes: 41 additions & 11 deletions lib/base/pull_to_refresh.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,51 @@ import 'package:namida/core/utils.dart';
typedef PullToRefreshCallback = Future<void> Function();
const double _defaultMaxDistance = 128.0;

class PullToRefreshWidget extends StatelessWidget {
final Widget child;
final ScrollController controller;
final PullToRefreshCallback onRefresh;
final PullToRefreshMixin state;

const PullToRefreshWidget({
super.key,
required this.child,
required this.controller,
required this.onRefresh,
required this.state,
});

@override
Widget build(BuildContext context) {
return Listener(
onPointerMove: (event) => state.onPointerMove(controller, event),
onPointerUp: (_) => state.onRefresh(onRefresh),
onPointerCancel: (_) => state.onVerticalDragFinish(),
child: Stack(
alignment: Alignment.topCenter,
children: [
child,
state.pullToRefreshWidget,
],
),
);
}
}

class PullToRefresh extends StatefulWidget {
final Widget child;
final ScrollController controller;
final PullToRefreshCallback onRefresh;
final double maxDistance;
final bool Function()? enablePullToRefresh;

const PullToRefresh({
super.key,
required this.child,
required this.controller,
required this.onRefresh,
this.maxDistance = _defaultMaxDistance,
this.enablePullToRefresh,
});

@override
Expand All @@ -28,19 +61,16 @@ class _PullToRefreshState extends State<PullToRefresh> with TickerProviderStateM
@override
double get maxDistance => widget.maxDistance;

@override
bool get enablePullToRefresh => widget.enablePullToRefresh == null ? true : widget.enablePullToRefresh!();

@override
Widget build(BuildContext context) {
return Listener(
onPointerMove: (event) => onPointerMove(widget.controller, event),
onPointerUp: (_) => onRefresh(widget.onRefresh),
onPointerCancel: (_) => onVerticalDragFinish(),
child: Stack(
alignment: Alignment.topCenter,
children: [
widget.child,
pullToRefreshWidget,
],
),
return PullToRefreshWidget(
state: this,
controller: widget.controller,
onRefresh: widget.onRefresh,
child: widget.child,
);
}
}
Expand Down
12 changes: 7 additions & 5 deletions lib/base/youtube_streams_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,22 +151,24 @@ mixin YoutubeStreamsManager<W extends YoutiPieListWrapper<StreamInfoItem>> {
}
}

Future<void> fetchStreamsNextPage() async {
if (isLoadingMoreUploads.value) return;
Future<bool> fetchStreamsNextPage() async {
bool didFetch = false;
if (isLoadingMoreUploads.value) return didFetch;

final result = this.listWrapper;
if (result == null) return;
if (!result.canFetchNext) return;
if (result == null) return didFetch;
if (!result.canFetchNext) return didFetch;

isLoadingMoreUploads.value = true;
final didFetch = await result.fetchNext();
didFetch = await result.fetchNext();
isLoadingMoreUploads.value = false;

if (didFetch) {
if (canRefreshList(result)) {
onListChange(trySortStreams); // refresh state even if will not sort
}
}
return didFetch;
}

Future<YoutiPieFetchAllResType?> fetchAllStreams(void Function(YoutiPieFetchAllRes fetchAllRes) controller) async {
Expand Down
2 changes: 2 additions & 0 deletions lib/core/enums.dart
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ enum RouteType {
YOUTUBE_USER_MANAGE_ACCOUNT_SUBPAGE,
YOUTUBE_USER_MANAGE_SUBSCRIPTION_SUBPAGE,

YOUTUBE_HISTORY_HOSTED_SUBPAGE,

/// others
UNKNOWN,
}
Expand Down
25 changes: 17 additions & 8 deletions lib/ui/widgets/custom_widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3152,16 +3152,25 @@ class LazyLoadListView extends StatefulWidget {

class _LazyLoadListViewState extends State<LazyLoadListView> {
late final ScrollController controller;
bool isExecuting = false;
bool _isExecuting = false;

void _scrollListener() async {
if (isExecuting) return;
bool? _lastWasSuccess;
bool _isInExtendRange = false; // prevent re-execution if latest failed & still in range.

if (controller.offset >= controller.position.maxScrollExtent - widget.extend && !controller.position.outOfRange) {
if (widget.requiresNetwork && !ConnectivityController.inst.hasConnection) return;
isExecuting = true;
await widget.onReachingEnd();
isExecuting = false;
void _scrollListener() async {
if (_isExecuting) return;

if (controller.offset >= controller.position.maxScrollExtent - widget.extend) {
if (!controller.position.outOfRange) {
if (_lastWasSuccess == false && _isInExtendRange) return;
_isInExtendRange = true;
if (widget.requiresNetwork && !ConnectivityController.inst.hasConnection) return;
_isExecuting = true;
_lastWasSuccess = await widget.onReachingEnd();
_isExecuting = false;
}
} else {
_isInExtendRange = false;
}
}

Expand Down
2 changes: 1 addition & 1 deletion lib/youtube/pages/youtube_home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class YouTubeHomeView extends StatelessWidget with NamidaRouteWidget {
YoutubeNotificationsPage(),
YoutubeChannelsPage(),
YoutubePlaylistsView(),
YoutubePlaylistsPage(),
YoutubeUserPlaylistsPage(),
YTDownloadsPage(),
],
),
Expand Down
Loading

0 comments on commit 0addb27

Please sign in to comment.