Skip to content

Commit

Permalink
feat: Implement zune mode for the search page
Browse files Browse the repository at this point in the history
  • Loading branch information
Losses committed Oct 10, 2024
1 parent 3afc211 commit 3742068
Show file tree
Hide file tree
Showing 13 changed files with 451 additions and 231 deletions.
55 changes: 43 additions & 12 deletions lib/screens/search/search.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import 'dart:async';

import 'package:player/screens/search/widgets/small_screen_search_track_list.dart';
import 'package:player/widgets/navigation_bar/navigation_bar_placeholder.dart';
import 'package:provider/provider.dart';
import 'package:fluent_ui/fluent_ui.dart';

import '../../utils/api/search_for.dart';
import '../../utils/api/fetch_collection_by_ids.dart';
import '../../utils/api/fetch_media_file_by_ids.dart';
import '../../screens/search/widgets/small_screen_track_list.dart';
import '../../widgets/start_screen/utils/internal_collection.dart';
import '../../widgets/playback_controller/playback_placeholder.dart';
import '../../widgets/start_screen/providers/start_screen_layout_manager.dart';
Expand All @@ -21,6 +22,7 @@ import 'widgets/search_suggest_box.dart';
import 'widgets/collection_search_item.dart';
import 'widgets/large_screen_search_sidebar.dart';
import 'widgets/large_screen_search_track_list.dart';
import 'widgets/medium_screen_search_track_list.dart';

class SearchPage extends StatefulWidget {
const SearchPage({super.key});
Expand All @@ -32,18 +34,20 @@ class SearchPage extends StatefulWidget {
class _SearchPageState extends State<SearchPage> {
@override
Widget build(BuildContext context) {
final isMini = Provider.of<ResponsiveProvider>(context)
.smallerOrEqualTo(DeviceType.tablet);

return SearchPageImplementation(
isMini: isMini,
return BreakpointBuilder(
breakpoints: const [DeviceType.zune, DeviceType.tablet, DeviceType.tv],
builder: (context, deviceType) {
return SearchPageImplementation(
deviceType: deviceType,
);
},
);
}
}

class SearchPageImplementation extends StatefulWidget {
final bool isMini;
const SearchPageImplementation({super.key, required this.isMini});
final DeviceType deviceType;
const SearchPageImplementation({super.key, required this.deviceType});

@override
State<SearchPageImplementation> createState() =>
Expand All @@ -63,6 +67,7 @@ class _SearchPageImplementationState extends State<SearchPageImplementation> {
String _lastSearched = '';

final largeScreenLayoutManager = StartScreenLayoutManager();
final mediumScreenLayoutManager = StartScreenLayoutManager();
final smallScreenLayoutManager = StartScreenLayoutManager();

@override
Expand All @@ -78,17 +83,20 @@ class _SearchPageImplementationState extends State<SearchPageImplementation> {
_debounce?.cancel();
searchController.dispose();
largeScreenLayoutManager.dispose();
mediumScreenLayoutManager.dispose();
smallScreenLayoutManager.dispose();
}

void resetAnimations() {
largeScreenLayoutManager.resetAnimations();
mediumScreenLayoutManager.resetAnimations();
smallScreenLayoutManager.resetAnimations();
}

void playAnimations() {
WidgetsBinding.instance.addPostFrameCallback((_) {
largeScreenLayoutManager.playAnimations();
mediumScreenLayoutManager.playAnimations();
smallScreenLayoutManager.playAnimations();
});
}
Expand All @@ -97,7 +105,7 @@ class _SearchPageImplementationState extends State<SearchPageImplementation> {
void didUpdateWidget(covariant SearchPageImplementation oldWidget) {
super.didUpdateWidget(oldWidget);

if (oldWidget.isMini != widget.isMini) {
if (oldWidget.deviceType != widget.deviceType) {
resetAnimations();
playAnimations();
}
Expand Down Expand Up @@ -192,18 +200,41 @@ class _SearchPageImplementationState extends State<SearchPageImplementation> {
controller: searchController,
searchResults: _searchResults,
registerSearchTask: _registerSearchTask,
isMini: widget.isMini,
deviceType: widget.deviceType,
);

if (widget.isMini) {
if (widget.deviceType == DeviceType.tablet) {
return ChangeNotifierProvider<StartScreenLayoutManager>.value(
value: smallScreenLayoutManager,
value: mediumScreenLayoutManager,
child: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(32, 18, 64, 20),
child: autoSuggestBox,
),
Expanded(
child: SingleChildScrollView(
child: MediumScreenSearchTrackList(
items: items,
),
),
),
const PlaybackPlaceholder(),
],
),
);
}

if (widget.deviceType == DeviceType.zune) {
return ChangeNotifierProvider<StartScreenLayoutManager>.value(
value: smallScreenLayoutManager,
child: Column(
children: [
const NavigationBarPlaceholder(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 12),
child: autoSuggestBox,
),
Expanded(
child: SingleChildScrollView(
child: SmallScreenSearchTrackList(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:fluent_ui/fluent_ui.dart';

import '../../../screens/search/widgets/search_card.dart';
import '../../../screens/search/widgets/search_track_list.dart';
import 'large_screen_search_track_list_implementation.dart';
import '../../../messages/collection.pb.dart';

class LargeScreenSearchTrackList extends StatelessWidget {
Expand Down Expand Up @@ -42,7 +42,7 @@ class LargeScreenSearchTrackList extends StatelessWidget {

final List<SearchCard> itemGroup = items[selectedItem] ?? [];

return SearchTrackList(
return LargeScreenSearchTrackListImplementation(
key: Key(selectedItem.toString()),
rows: rows,
ratio: ratio,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import './search_card.dart';

const List<SearchCard> defaultList = [];

class SearchTrackList extends StatelessWidget {
class LargeScreenSearchTrackListImplementation extends StatelessWidget {
final int rows;
final double ratio;
final double gapSize;
Expand All @@ -16,7 +16,7 @@ class SearchTrackList extends StatelessWidget {
final List<SearchCard>? items;
final int groupId;

const SearchTrackList({
const LargeScreenSearchTrackListImplementation({
super.key,
required this.rows,
required this.ratio,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'package:fluent_ui/fluent_ui.dart';

import '../../../screens/search/widgets/search_card.dart';
import '../../../screens/search/widgets/search_track_list.dart';
import 'large_screen_search_track_list_implementation.dart';
import '../../../messages/collection.pb.dart';

class SmallScreenSearchTrackList extends StatelessWidget {
class MediumScreenSearchTrackList extends StatelessWidget {
final Map<CollectionType, List<SearchCard>> items;

const SmallScreenSearchTrackList({
const MediumScreenSearchTrackList({
super.key,
required this.items,
});
Expand Down Expand Up @@ -37,7 +37,7 @@ class SmallScreenSearchTrackList extends StatelessWidget {
children: [
if (items[CollectionType.Artist]?.isNotEmpty ?? false)
const SearchListSectionTitle(text: "Artists"),
SearchTrackList(
LargeScreenSearchTrackListImplementation(
rows: rows,
ratio: ratio,
gapSize: gapSize,
Expand All @@ -48,7 +48,7 @@ class SmallScreenSearchTrackList extends StatelessWidget {
),
if (items[CollectionType.Album]?.isNotEmpty ?? false)
const SearchListSectionTitle(text: "Albums"),
SearchTrackList(
LargeScreenSearchTrackListImplementation(
rows: rows,
ratio: ratio,
gapSize: gapSize,
Expand All @@ -59,7 +59,7 @@ class SmallScreenSearchTrackList extends StatelessWidget {
),
if (items[CollectionType.Playlist]?.isNotEmpty ?? false)
const SearchListSectionTitle(text: "Playlists"),
SearchTrackList(
LargeScreenSearchTrackListImplementation(
rows: rows,
ratio: ratio,
gapSize: gapSize,
Expand All @@ -70,7 +70,7 @@ class SmallScreenSearchTrackList extends StatelessWidget {
),
if (items[CollectionType.Track]?.isNotEmpty ?? false)
const SearchListSectionTitle(text: "Tracks"),
SearchTrackList(
LargeScreenSearchTrackListImplementation(
rows: rows,
ratio: ratio,
gapSize: gapSize,
Expand Down
86 changes: 61 additions & 25 deletions lib/screens/search/widgets/search_card.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:math';

import 'package:fluent_ui/fluent_ui.dart';
import 'package:player/providers/responsive_providers.dart';
import 'package:player/widgets/hover_opacity.dart';

import '../../../widgets/context_menu_wrapper.dart';

Expand All @@ -23,39 +25,73 @@ abstract class SearchCard extends StatelessWidget {
contextAttachKey: contextAttachKey,
contextController: contextController,
onContextMenu: (position) => onContextMenu(context, position),
child: Button(
style: const ButtonStyle(
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
),
onPressed: () => onPressed(context),
child: ClipRRect(
borderRadius: BorderRadius.circular(3),
child: LayoutBuilder(
builder: (context, constraints) {
final size = min(constraints.maxWidth, constraints.maxHeight);
return Row(
child: SmallerOrEqualTo(
breakpoint: DeviceType.zune,
builder: (context, isZune) {
if (isZune) {
final typography = FluentTheme.of(context).typography;

return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
buildLeadingWidget(size),
SizedBox(
width: 40,
height: 40,
child: buildLeadingWidget(40),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
getItemTitle(),
overflow: TextOverflow.ellipsis,
),
],
child: HoverOpacity(
child: Text(
getItemTitle(),
style: typography.bodyLarge?.apply(fontSizeFactor: 0.9),
overflow: TextOverflow.ellipsis,
),
),
),
),
],
);
},
),
),
),
);
}

return Button(
style: const ButtonStyle(
padding: WidgetStatePropertyAll(EdgeInsets.all(0)),
),
onPressed: () => onPressed(context),
child: ClipRRect(
borderRadius: BorderRadius.circular(3),
child: LayoutBuilder(
builder: (context, constraints) {
final size = min(constraints.maxWidth, constraints.maxHeight);
return Row(
children: [
buildLeadingWidget(size),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
getItemTitle(),
overflow: TextOverflow.ellipsis,
),
],
),
),
),
],
);
},
),
),
);
},
),
);
}
Expand Down
11 changes: 6 additions & 5 deletions lib/screens/search/widgets/search_suggest_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import 'dart:async';
import 'package:fluent_ui/fluent_ui.dart';
import 'package:get_storage/get_storage.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:player/providers/responsive_providers.dart';

import '../../../messages/search.pb.dart';

class SearchSuggestBox extends StatefulWidget {
final bool isMini;
final DeviceType deviceType;
final TextEditingController controller;
final SearchForResponse? searchResults;
final void Function() registerSearchTask;

const SearchSuggestBox({
super.key,
required this.isMini,
required this.deviceType,
required this.controller,
required this.searchResults,
required this.registerSearchTask,
Expand Down Expand Up @@ -103,9 +104,9 @@ class SearchSuggestBoxState extends State<SearchSuggestBox> {
},
);
}).toList(),
clearButtonEnabled: !widget.isMini,
leadingIcon: !widget.isMini ? null : icon,
trailingIcon: widget.isMini ? null : icon,
clearButtonEnabled: widget.deviceType != DeviceType.tablet,
leadingIcon: widget.deviceType != DeviceType.tablet ? null : icon,
trailingIcon: widget.deviceType == DeviceType.tablet ? null : icon,
);
}
}
Loading

0 comments on commit 3742068

Please sign in to comment.