Skip to content

Commit

Permalink
feat: add mobile home page
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier committed Dec 7, 2024
1 parent cf7bb4f commit c831745
Show file tree
Hide file tree
Showing 18 changed files with 339 additions and 599 deletions.
156 changes: 156 additions & 0 deletions lib/app/view/home_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:watch_it/watch_it.dart';

import '../../common/data/audio_type.dart';
import '../../common/view/adaptive_container.dart';
import '../../common/view/header_bar.dart';
import '../../common/view/icons.dart';
import '../../common/view/search_button.dart';
import '../../common/view/theme.dart';
import '../../common/view/ui_constants.dart';
import '../../constants.dart';
import '../../extensions/build_context_x.dart';
import '../../extensions/country_x.dart';
import '../../l10n/l10n.dart';
import '../../library/library_model.dart';
import '../../local_audio/view/playlists_view.dart';
import '../../search/search_model.dart';
import '../../search/search_type.dart';
import '../../search/view/sliver_podcast_search_results.dart';
import '../../search/view/sliver_radio_country_grid.dart';

class HomePage extends StatelessWidget with WatchItMixin {
const HomePage({super.key});

@override
Widget build(BuildContext context) {
final textTheme = context.textTheme;
final l10n = context.l10n;
final playlists = watchPropertyValue(
(LibraryModel m) => m.playlists.keys.toList(),
);
final style = textTheme.headlineSmall;
const textPadding = EdgeInsets.only(
left: kSmallestSpace,
bottom: kSmallestSpace,
);

final country =
watchPropertyValue((SearchModel m) => m.country?.localize(l10n));

return Scaffold(
appBar: HeaderBar(
title: Text(l10n.home),
adaptive: false,
actions: [
const SearchButton(),
IconButton(
selectedIcon: Icon(Iconz.settingsFilled),
icon: Icon(Iconz.settings),
tooltip: l10n.settings,
onPressed: () => di<LibraryModel>().push(pageId: kSettingsPageId),
),
const SizedBox(
width: kSmallestSpace,
),
],
),
body: LayoutBuilder(
builder: (context, constraints) {
final padding = getAdaptiveHorizontalPadding(
constraints: constraints,
);
return CustomScrollView(
slivers: [
SliverPadding(
padding: padding,
sliver: SliverToBoxAdapter(
child: Padding(
padding: textPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${l10n.podcast} ${l10n.charts} ${country ?? ''}',
style: style,
),
IconButton(
onPressed: () {
di<LibraryModel>().push(pageId: kSearchPageId);
di<SearchModel>()
..setAudioType(AudioType.podcast)
..setSearchType(SearchType.podcastTitle)
..search();
},
icon: Icon(Iconz.goNext),
),
],
),
),
),
),
SliverPadding(
padding: padding,
sliver: const SliverPodcastSearchResults(
take: 3,
),
),
SliverPadding(
padding: padding,
sliver: SliverToBoxAdapter(
child: Padding(
padding: textPadding,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'${l10n.radio} ${l10n.charts} ${country ?? ''}',
style: style,
),
IconButton(
onPressed: () {
di<LibraryModel>().push(pageId: kSearchPageId);
di<SearchModel>()
..setAudioType(AudioType.radio)
..setSearchType(SearchType.radioCountry)
..search();
},
icon: Icon(Iconz.goNext),
),
],
),
),
),
),
SliverPadding(
padding: padding,
sliver: const SliverRadioCountryGrid(),
),
SliverPadding(
padding: padding,
sliver: SliverToBoxAdapter(
child: Padding(
padding: textPadding,
child: Text(
'${l10n.playlists} ',
style: style,
),
),
),
),
SliverPadding(
padding: padding.copyWith(
bottom: bottomPlayerPageGap,
),
sliver: PlaylistsView(
playlists: playlists,
take: 2,
),
),
],
);
},
),
);
}
}
9 changes: 9 additions & 0 deletions lib/app/view/master_items.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import '../../radio/view/station_page.dart';
import '../../radio/view/station_page_icon.dart';
import '../../search/view/search_page.dart';
import '../../settings/view/settings_page.dart';
import 'home_page.dart';
import 'main_page_icon.dart';

class MasterItem {
Expand Down Expand Up @@ -83,6 +84,14 @@ List<MasterItem> createMasterItems({required LibraryModel libraryModel}) {
pageBuilder: (context) => const SettingsPage(),
pageId: kSettingsPageId,
),
if (isMobilePlatform)
MasterItem(
titleBuilder: (context) => Text(context.l10n.home),
iconBuilder: (selected) =>
Icon(selected ? Iconz.homeFilled : Iconz.home),
pageBuilder: (context) => const HomePage(),
pageId: kHomePageId,
),
MasterItem(
iconBuilder: (selected) => Icon(Iconz.plus),
titleBuilder: (context) => Text(context.l10n.add),
Expand Down
18 changes: 5 additions & 13 deletions lib/app/view/mobile_navigation_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,11 @@ class MobileNavigationBar extends StatelessWidget with WatchItMixin {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
isSelected: selectedPageId == kLikedAudiosPageId,
selectedIcon: Icon(Iconz.heartFilled),
icon: Icon(Iconz.heart),
tooltip: l10n.local,
onPressed: () =>
di<LibraryModel>().push(pageId: kLikedAudiosPageId),
isSelected: selectedPageId == kHomePageId,
selectedIcon: Icon(Iconz.homeFilled),
icon: Icon(Iconz.home),
tooltip: l10n.home,
onPressed: () => di<LibraryModel>().push(pageId: kHomePageId),
),
IconButton(
isSelected: selectedPageId == kLocalAudioPageId,
Expand Down Expand Up @@ -74,13 +73,6 @@ class MobileNavigationBar extends StatelessWidget with WatchItMixin {
tooltip: l10n.podcasts,
onPressed: () => di<LibraryModel>().push(pageId: kPodcastsPageId),
),
IconButton(
isSelected: selectedPageId == kSettingsPageId,
selectedIcon: Icon(Iconz.settingsFilled),
icon: Icon(Iconz.settings),
tooltip: l10n.settings,
onPressed: () => di<LibraryModel>().push(pageId: kSettingsPageId),
),
],
),
),
Expand Down
1 change: 1 addition & 0 deletions lib/app/view/mobile_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class MobilePage extends StatelessWidget with WatchItMixin {
);

return Scaffold(
resizeToAvoidBottomInset: false,
extendBody: true,
extendBodyBehindAppBar: true,
body: Stack(
Expand Down
11 changes: 11 additions & 0 deletions lib/common/view/icons.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ import 'package:yaru/yaru.dart';
import '../../app_config.dart';

class Iconz {
static IconData get home => yaruStyled
? YaruIcons.home
: appleStyled
? CupertinoIcons.home
: Icons.home_outlined;
static IconData get homeFilled => yaruStyled
? YaruIcons.home_filled
: appleStyled
? CupertinoIcons.home
: Icons.home_filled;

static IconData get image => yaruStyled
? YaruIcons.image
: appleStyled
Expand Down
10 changes: 8 additions & 2 deletions lib/common/view/search_button.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import 'package:flutter/material.dart';
import 'package:watch_it/watch_it.dart';
import 'package:yaru/yaru.dart';

import '../../app_config.dart';
import '../../constants.dart';
import '../../extensions/build_context_x.dart';
import '../../library/library_model.dart';
import 'icons.dart';
import 'theme.dart';

Expand All @@ -15,16 +18,19 @@ class SearchButton extends StatelessWidget {

@override
Widget build(BuildContext context) {
final onTap =
onPressed ?? () => di<LibraryModel>().push(pageId: kSearchPageId);

return yaruStyled
? YaruSearchButton(
searchActive: active,
onPressed: onPressed,
onPressed: onTap,
icon: icon,
selectedIcon: icon,
)
: IconButton(
isSelected: active,
onPressed: onPressed,
onPressed: onTap,
selectedIcon: icon ??
Icon(
Iconz.search,
Expand Down
1 change: 1 addition & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,4 @@ const kCloseBtnAction = 'closeBtnAction';
const kUseMoreAnimations = 'useMoreAnimations';
const kShowPositionDuration = 'showPositionDuration';
const kSettingsPageId = 'settings';
const kHomePageId = 'homePage';
1 change: 1 addition & 0 deletions lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"@@locale": "de",
"home": "Home",
"play": "Wiedergabe",
"pause": "Pause",
"stop": "Stop",
Expand Down
1 change: 1 addition & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"@@locale": "en",
"home": "Home",
"play": "Play",
"pause": "Pause",
"stop": "Stop",
Expand Down
1 change: 1 addition & 0 deletions lib/library/library_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ class LibraryService {
isPodcastSubscribed(pageId));

final _mainPages = [
kHomePageId,
kSearchPageId,
kLikedAudiosPageId,
kLocalAudioPageId,
Expand Down
4 changes: 3 additions & 1 deletion lib/local_audio/view/playlists_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,19 @@ class PlaylistsView extends StatelessWidget {
this.noResultMessage,
this.noResultIcon,
required this.playlists,
this.take,
});

final List<String>? playlists;
final Widget? noResultMessage, noResultIcon;
final int? take;

@override
Widget build(BuildContext context) {
final lists = [
kNewPlaylistPageId,
kLikedAudiosPageId,
...(playlists ?? []),
...(take != null ? playlists!.take(take!).toList() : playlists ?? []),
];

return SliverGrid.builder(
Expand Down
5 changes: 4 additions & 1 deletion lib/playlists/view/manual_add_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class ManualAddDialog extends StatelessWidget {
bottom: kLargestSpace,
),
content: SizedBox(
height: 200,
height: 220,
width: 400,
child: onlyPlaylists
? Padding(
Expand Down Expand Up @@ -199,6 +199,9 @@ class _PlaylistEditDialogContentState extends State<PlaylistEditDialogContent> {
),
),
),
const SizedBox(
height: kLargestSpace,
),
Align(
alignment: Alignment.bottomRight,
child: Wrap(
Expand Down
Loading

0 comments on commit c831745

Please sign in to comment.