Skip to content

Commit

Permalink
Merge pull request #411 from EgidioCaprino/search-filters
Browse files Browse the repository at this point in the history
More search filters and channel videos sorting options
  • Loading branch information
lamarios authored Jan 15, 2024
2 parents 4357e71 + ea78696 commit adc6606
Show file tree
Hide file tree
Showing 19 changed files with 632 additions and 142 deletions.
15 changes: 15 additions & 0 deletions lib/channels/models/channel_sort_by.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

enum ChannelSortBy {
newest,
oldest,
popular;

String getLabel(AppLocalizations locals) {
return switch (this) {
(ChannelSortBy.newest) => locals.channelSortByNewest,
(ChannelSortBy.oldest) => locals.channelSortByOldest,
(ChannelSortBy.popular) => locals.channelSortByPopular,
};
}
}
23 changes: 15 additions & 8 deletions lib/channels/states/channel.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:invidious/channels/models/channel_sort_by.dart';

import '../../globals.dart';
import '../models/channel.dart';
Expand Down Expand Up @@ -46,17 +47,23 @@ class ChannelCubit extends Cubit<ChannelController> {
emit(state.copyWith(isSubscribed: isSubscribed));
}
}

void onSortByChanged(ChannelSortBy newValue) {
emit(state.copyWith(sortBy: newValue));
}
}

@freezed
class ChannelController with _$ChannelController {
const factory ChannelController(
{required String channelId,
@Default(false) bool isSubscribed,
@Default(0) selectedIndex,
Channel? channel,
@Default(true) bool loading,
@Default(false) bool smallHeader,
@Default(200) double barHeight,
@Default(1) double barOpacity}) = _ChannelController;
{required String channelId,
@Default(false) bool isSubscribed,
@Default(0) selectedIndex,
Channel? channel,
@Default(true) bool loading,
@Default(false) bool smallHeader,
@Default(200) double barHeight,
@Default(1) double barOpacity,
@Default(ChannelSortBy.newest) ChannelSortBy sortBy}) =
_ChannelController;
}
36 changes: 29 additions & 7 deletions lib/channels/states/channel.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mixin _$ChannelController {
bool get smallHeader => throw _privateConstructorUsedError;
double get barHeight => throw _privateConstructorUsedError;
double get barOpacity => throw _privateConstructorUsedError;
ChannelSortBy get sortBy => throw _privateConstructorUsedError;

@JsonKey(ignore: true)
$ChannelControllerCopyWith<ChannelController> get copyWith =>
Expand All @@ -44,7 +45,8 @@ abstract class $ChannelControllerCopyWith<$Res> {
bool loading,
bool smallHeader,
double barHeight,
double barOpacity});
double barOpacity,
ChannelSortBy sortBy});
}

/// @nodoc
Expand All @@ -68,6 +70,7 @@ class _$ChannelControllerCopyWithImpl<$Res, $Val extends ChannelController>
Object? smallHeader = null,
Object? barHeight = null,
Object? barOpacity = null,
Object? sortBy = null,
}) {
return _then(_value.copyWith(
channelId: null == channelId
Expand Down Expand Up @@ -102,6 +105,10 @@ class _$ChannelControllerCopyWithImpl<$Res, $Val extends ChannelController>
? _value.barOpacity
: barOpacity // ignore: cast_nullable_to_non_nullable
as double,
sortBy: null == sortBy
? _value.sortBy
: sortBy // ignore: cast_nullable_to_non_nullable
as ChannelSortBy,
) as $Val);
}
}
Expand All @@ -122,7 +129,8 @@ abstract class _$$ChannelControllerImplCopyWith<$Res>
bool loading,
bool smallHeader,
double barHeight,
double barOpacity});
double barOpacity,
ChannelSortBy sortBy});
}

/// @nodoc
Expand All @@ -144,6 +152,7 @@ class __$$ChannelControllerImplCopyWithImpl<$Res>
Object? smallHeader = null,
Object? barHeight = null,
Object? barOpacity = null,
Object? sortBy = null,
}) {
return _then(_$ChannelControllerImpl(
channelId: null == channelId
Expand Down Expand Up @@ -176,6 +185,10 @@ class __$$ChannelControllerImplCopyWithImpl<$Res>
? _value.barOpacity
: barOpacity // ignore: cast_nullable_to_non_nullable
as double,
sortBy: null == sortBy
? _value.sortBy
: sortBy // ignore: cast_nullable_to_non_nullable
as ChannelSortBy,
));
}
}
Expand All @@ -191,7 +204,8 @@ class _$ChannelControllerImpl implements _ChannelController {
this.loading = true,
this.smallHeader = false,
this.barHeight = 200,
this.barOpacity = 1});
this.barOpacity = 1,
this.sortBy = ChannelSortBy.newest});

@override
final String channelId;
Expand All @@ -215,10 +229,13 @@ class _$ChannelControllerImpl implements _ChannelController {
@override
@JsonKey()
final double barOpacity;
@override
@JsonKey()
final ChannelSortBy sortBy;

@override
String toString() {
return 'ChannelController(channelId: $channelId, isSubscribed: $isSubscribed, selectedIndex: $selectedIndex, channel: $channel, loading: $loading, smallHeader: $smallHeader, barHeight: $barHeight, barOpacity: $barOpacity)';
return 'ChannelController(channelId: $channelId, isSubscribed: $isSubscribed, selectedIndex: $selectedIndex, channel: $channel, loading: $loading, smallHeader: $smallHeader, barHeight: $barHeight, barOpacity: $barOpacity, sortBy: $sortBy)';
}

@override
Expand All @@ -239,7 +256,8 @@ class _$ChannelControllerImpl implements _ChannelController {
(identical(other.barHeight, barHeight) ||
other.barHeight == barHeight) &&
(identical(other.barOpacity, barOpacity) ||
other.barOpacity == barOpacity));
other.barOpacity == barOpacity) &&
(identical(other.sortBy, sortBy) || other.sortBy == sortBy));
}

@override
Expand All @@ -252,7 +270,8 @@ class _$ChannelControllerImpl implements _ChannelController {
loading,
smallHeader,
barHeight,
barOpacity);
barOpacity,
sortBy);

@JsonKey(ignore: true)
@override
Expand All @@ -271,7 +290,8 @@ abstract class _ChannelController implements ChannelController {
final bool loading,
final bool smallHeader,
final double barHeight,
final double barOpacity}) = _$ChannelControllerImpl;
final double barOpacity,
final ChannelSortBy sortBy}) = _$ChannelControllerImpl;

@override
String get channelId;
Expand All @@ -290,6 +310,8 @@ abstract class _ChannelController implements ChannelController {
@override
double get barOpacity;
@override
ChannelSortBy get sortBy;
@override
@JsonKey(ignore: true)
_$$ChannelControllerImplCopyWith<_$ChannelControllerImpl> get copyWith =>
throw _privateConstructorUsedError;
Expand Down
31 changes: 31 additions & 0 deletions lib/channels/views/components/sort_dropdown_button.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:invidious/channels/models/channel_sort_by.dart';

class SortDropdownButton extends StatelessWidget {
final ChannelSortBy selectedSortingOption;
final Function(ChannelSortBy) onChanged;

const SortDropdownButton({
super.key,
required this.selectedSortingOption,
required this.onChanged,
});

@override
Widget build(BuildContext context) {
final locals = AppLocalizations.of(context)!;
return DropdownButton<ChannelSortBy>(
value: selectedSortingOption,
items: ChannelSortBy.values
.map((value) => DropdownMenuItem<ChannelSortBy>(
value: value,
child: Text(value.getLabel(locals)),
))
.toList(),
onChanged: (ChannelSortBy? newValue) {
onChanged(newValue ?? ChannelSortBy.newest);
},
);
}
}
1 change: 0 additions & 1 deletion lib/channels/views/components/videos.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class ChannelVideosView extends StatelessWidget {
child: Container(
color: colorScheme.background,
child: VideoList(
key: const ValueKey('channel-videos'),
paginatedVideoList: ContinuationList<VideoInList>(
(continuation) => getVideos(channel.authorId, continuation)),
// tags: 'channel-video-list-${(key as ValueKey<String>).value}'
Expand Down
44 changes: 35 additions & 9 deletions lib/channels/views/screens/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_fadein/flutter_fadein.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:invidious/channels/models/channel_sort_by.dart';
import 'package:invidious/channels/views/components/sort_dropdown_button.dart';
import 'package:invidious/channels/states/channel.dart';
import 'package:invidious/channels/views/components/info.dart';
import 'package:invidious/channels/views/components/playlists.dart';
Expand Down Expand Up @@ -40,10 +42,14 @@ class ChannelScreen extends StatelessWidget {
: [
Visibility(
visible: channelState.channel != null,
child: IconButton(
onPressed: () =>
showSharingSheet(context, channelState.channel!),
icon: const Icon(Icons.share),
child: Row(
children: <Widget>[
IconButton(
onPressed: () => showSharingSheet(
context, channelState.channel!),
icon: const Icon(Icons.share),
),
],
),
),
],
Expand Down Expand Up @@ -73,7 +79,6 @@ class ChannelScreen extends StatelessWidget {
],
),
),
//.animate().slideY(duration: animationDuration, begin: 1, curve: Curves.easeInOutQuad),
body: SafeArea(
bottom: false,
child: NavigationSwitcher(
Expand All @@ -84,10 +89,31 @@ class ChannelScreen extends StatelessWidget {
key: const ValueKey('info'),
channel: channelState.channel!),
if (!channelState.loading)
ChannelVideosView(
key: const ValueKey('videos'),
channel: channelState.channel!,
getVideos: service.getChannelVideos,
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(
right: innerHorizontalPadding),
child: SortDropdownButton(
selectedSortingOption: channelState.sortBy,
onChanged: (ChannelSortBy newValue) =>
cubit.onSortByChanged(newValue),
),
),
Expanded(
child: ChannelVideosView(
key: UniqueKey(),
channel: channelState.channel!,
getVideos:
(String channelId, String? continuation) {
return service.getChannelVideos(
channelId, continuation,
sortBy: channelState.sortBy);
},
),
),
],
),
if (!channelState.loading)
ChannelVideosView(
Expand Down
62 changes: 61 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,54 @@
"@shorts": {
"description": "Youtube shorts"
},
"searchUploadDate": "Upload date",
"@searchUploadDate": {
"description": "Filter search result by upload date"
},
"searchUploadDateAny": "Any date",
"@searchUploadDateAny": {
"description": "Do not filter search result by upload date"
},
"searchUploadDateHour": "Last Hour",
"@searchUploadDateHour": {
"description": "Search for uploaded in last hour"
},
"searchUploadDateToday": "Today",
"@searchUploadDateToday": {
"description": "Search for uploaded today"
},
"searchUploadDateWeek": "This week",
"@searchUploadDateToday": {
"description": "Search for uploaded this week"
},
"searchUploadDateMonth": "This month",
"@searchUploadDateMonth": {
"description": "Search for uploaded this month"
},
"searchUploadDateYear": "This year",
"@searchUploadDateYear": {
"description": "Search for uploaded this year"
},
"searchDuration": "Duration",
"@searchDuration": {
"description": "Filter search result by duration"
},
"searchDurationAny": "Any duration",
"@searchDurationAny": {
"description": "Do not filter search result by duration"
},
"searchDurationShort": "Short (<4 minutes)",
"@searchDurationShort": {
"description": "Search for short videos only"
},
"searchDurationLong": "Long (>20 minutes)",
"@searchDurationLong": {
"description": "Search for long videos only"
},
"searchDurationMedium": "Medium (4-20 minutes)",
"@searchDurationMedium": {
"description": "Search for medium videos only"
},
"searchSortBy": "Sort by",
"@searchSortBy": {
"description": "Search sorting option"
Expand Down Expand Up @@ -1262,5 +1310,17 @@
"enabled": "Enabled",
"@enabled": {
"description": "Text to show something is enabled"
},
"channelSortByNewest": "Newest",
"@enabled": {
"description": "Sort channel videos from newest to oldest"
},
"channelSortByOldest": "Oldest",
"@enabled": {
"description": "Sort channel videos from oldest to newest"
},
"channelSortByPopular": "Popular",
"@enabled": {
"description": "Sort channel videos by popularity"
}
}
}
21 changes: 21 additions & 0 deletions lib/search/models/search_date.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

enum SearchDate {
any,
hour,
today,
week,
month,
year;

String getLabel(AppLocalizations locals) {
return switch (this) {
(SearchDate.any) => locals.searchUploadDateAny,
(SearchDate.hour) => locals.searchUploadDateHour,
(SearchDate.today) => locals.searchUploadDateToday,
(SearchDate.week) => locals.searchUploadDateWeek,
(SearchDate.month) => locals.searchUploadDateMonth,
(SearchDate.year) => locals.searchUploadDateYear,
};
}
}
Loading

0 comments on commit adc6606

Please sign in to comment.