freezer/lib/ui/home_screen.dart

307 lines
8.6 KiB
Dart
Raw Normal View History

2020-06-23 19:23:12 +00:00
import 'package:flutter/material.dart';
import 'package:freezer/api/deezer.dart';
import 'package:freezer/api/definitions.dart';
import 'package:freezer/api/player.dart';
import 'package:freezer/ui/elements.dart';
2020-06-23 19:23:12 +00:00
import 'package:freezer/ui/error.dart';
import 'package:freezer/ui/menu.dart';
import 'package:freezer/translations.i18n.dart';
2020-06-23 19:23:12 +00:00
import 'tiles.dart';
import 'details_screens.dart';
import '../settings.dart';
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
2021-08-29 22:25:18 +00:00
return SafeArea(
child: SingleChildScrollView(
child: HomePageScreen(),
2020-07-16 20:25:30 +00:00
),
);
2020-06-23 19:23:12 +00:00
}
}
class FreezerTitle extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 24, 0, 8),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Image.asset('assets/icon.png', width: 64, height: 64),
Text(
'freezer',
2021-08-29 22:25:18 +00:00
style: TextStyle(fontSize: 56, fontWeight: FontWeight.w900),
)
],
)
],
2020-06-23 19:23:12 +00:00
),
);
}
}
class HomePageScreen extends StatefulWidget {
2021-09-01 12:38:32 +00:00
final HomePage? homePage;
final DeezerChannel? channel;
HomePageScreen({this.homePage, this.channel, Key? key}) : super(key: key);
2020-06-23 19:23:12 +00:00
@override
_HomePageScreenState createState() => _HomePageScreenState();
}
class _HomePageScreenState extends State<HomePageScreen> {
2021-09-01 12:38:32 +00:00
HomePage? _homePage;
2020-06-23 19:23:12 +00:00
bool _cancel = false;
bool _error = false;
void _loadChannel() async {
2021-09-01 12:38:32 +00:00
HomePage? _hp;
2020-06-23 19:23:12 +00:00
//Fetch channel from api
try {
2021-09-01 12:38:32 +00:00
_hp = await deezerAPI.getChannel(widget.channel!.target);
2020-06-23 19:23:12 +00:00
} catch (e) {}
if (_hp == null) {
//On error
setState(() => _error = true);
return;
}
setState(() => _homePage = _hp);
}
2021-08-29 22:25:18 +00:00
2020-06-23 19:23:12 +00:00
void _loadHomePage() async {
//Load local
try {
HomePage _hp = await HomePage().load();
setState(() => _homePage = _hp);
} catch (e) {}
//On background load from API
try {
if (settings.offlineMode) await deezerAPI.authorize();
2020-06-23 19:23:12 +00:00
HomePage _hp = await deezerAPI.homePage();
2021-09-01 12:38:32 +00:00
if (_cancel) return;
if (_hp.sections!.length == 0) return;
setState(() => _homePage = _hp);
//Save to cache
await _homePage!.save();
2020-06-23 19:23:12 +00:00
} catch (e) {}
}
void _load() {
if (widget.channel != null) {
_loadChannel();
return;
}
if (widget.channel == null && widget.homePage == null) {
_loadHomePage();
return;
}
2021-09-01 12:38:32 +00:00
if (widget.homePage!.sections == null ||
widget.homePage!.sections!.length == 0) {
2020-06-23 19:23:12 +00:00
_loadHomePage();
return;
}
//Already have data
setState(() => _homePage = widget.homePage);
}
@override
void initState() {
super.initState();
2020-09-01 14:41:15 +00:00
_load();
2020-06-23 19:23:12 +00:00
}
@override
void dispose() {
_cancel = true;
super.dispose();
}
@override
Widget build(BuildContext context) {
2021-09-02 20:45:14 +00:00
if (_homePage == null) return Center(child: CircularProgressIndicator());
2021-08-29 22:25:18 +00:00
if (_error) return ErrorScreen();
2020-11-01 19:23:24 +00:00
return Column(
2021-08-29 22:25:18 +00:00
children: List.generate(
2021-09-01 12:38:32 +00:00
_homePage!.sections!.length,
2021-08-29 22:25:18 +00:00
(i) {
2021-09-01 12:38:32 +00:00
switch (_homePage!.sections![i].layout) {
2021-08-29 22:25:18 +00:00
case HomePageSectionLayout.ROW:
2021-09-01 12:38:32 +00:00
return HomepageRowSection(_homePage!.sections![i]);
2021-08-29 22:25:18 +00:00
case HomePageSectionLayout.GRID:
2021-09-01 12:38:32 +00:00
return HomePageGridSection(_homePage!.sections![i]);
2021-08-29 22:25:18 +00:00
default:
2021-09-01 12:38:32 +00:00
return HomepageRowSection(_homePage!.sections![i]);
2021-08-29 22:25:18 +00:00
}
},
2020-11-03 14:07:52 +00:00
));
}
}
class HomepageRowSection extends StatelessWidget {
2020-11-03 14:07:52 +00:00
final HomePageSection section;
HomepageRowSection(this.section);
2020-11-03 14:07:52 +00:00
@override
Widget build(BuildContext context) {
return ListTile(
2021-08-29 22:25:18 +00:00
contentPadding: EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
title: Padding(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0),
child: Text(
section.title ?? '',
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.w900),
),
),
2021-08-29 22:25:18 +00:00
subtitle: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
2021-09-01 12:38:32 +00:00
children: List.generate(section.items!.length + 1, (j) {
2021-08-29 22:25:18 +00:00
//Has more items
2021-09-01 12:38:32 +00:00
if (j == section.items!.length) {
2021-08-29 22:25:18 +00:00
if (section.hasMore ?? false) {
return TextButton(
child: Text(
'Show more'.i18n,
textAlign: TextAlign.center,
style: TextStyle(fontSize: 20.0),
),
2021-08-29 22:25:18 +00:00
onPressed: () =>
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
2021-08-29 22:25:18 +00:00
builder: (context) => Scaffold(
2021-11-01 16:41:25 +00:00
appBar: FreezerAppBar(section.title!),
2021-08-29 22:25:18 +00:00
body: SingleChildScrollView(
child: HomePageScreen(
channel:
2021-11-01 16:41:25 +00:00
DeezerChannel(target: section.pagePath)),
),
2021-08-29 22:25:18 +00:00
)),
);
}
return Container(height: 0, width: 0);
}
2021-08-29 22:25:18 +00:00
//Show item
2021-09-01 12:38:32 +00:00
HomePageItem item = section.items![j];
2021-08-29 22:25:18 +00:00
return HomePageItemWidget(item);
}),
),
));
2020-06-23 19:23:12 +00:00
}
}
class HomePageGridSection extends StatelessWidget {
final HomePageSection section;
HomePageGridSection(this.section);
@override
Widget build(BuildContext context) {
return ListTile(
contentPadding: EdgeInsets.symmetric(horizontal: 4.0, vertical: 2.0),
title: Padding(
padding: EdgeInsets.symmetric(vertical: 4.0, horizontal: 6.0),
child: Text(
2021-08-29 22:25:18 +00:00
section.title ?? '',
textAlign: TextAlign.left,
maxLines: 2,
overflow: TextOverflow.ellipsis,
2021-08-29 22:25:18 +00:00
style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.w900),
),
),
subtitle: Wrap(
alignment: WrapAlignment.spaceAround,
2021-09-01 12:38:32 +00:00
children: List.generate(section.items!.length, (i) {
//Item
2021-09-01 12:38:32 +00:00
return HomePageItemWidget(section.items![i]);
}),
),
);
}
}
class HomePageItemWidget extends StatelessWidget {
final HomePageItem item;
HomePageItemWidget(this.item);
@override
Widget build(BuildContext context) {
switch (item.type) {
case HomePageItemType.SMARTTRACKLIST:
return SmartTrackListTile(
item.value,
onTap: () {
playerHelper.playFromSmartTrackList(item.value);
},
);
case HomePageItemType.ALBUM:
return AlbumCard(
item.value,
onTap: () {
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
builder: (context) => AlbumDetails(item.value));
},
onHold: () {
MenuSheet m = MenuSheet(context);
m.defaultAlbumMenu(item.value);
},
);
case HomePageItemType.ARTIST:
return ArtistTile(
item.value,
onTap: () {
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
builder: (context) => ArtistDetails(item.value));
},
onHold: () {
MenuSheet m = MenuSheet(context);
m.defaultArtistMenu(item.value);
},
);
case HomePageItemType.PLAYLIST:
return PlaylistCardTile(
item.value,
onTap: () {
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
builder: (context) => PlaylistDetails(item.value));
},
onHold: () {
MenuSheet m = MenuSheet(context);
m.defaultPlaylistMenu(item.value);
},
);
case HomePageItemType.CHANNEL:
return ChannelTile(
item.value,
onTap: () {
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
builder: (context) => Scaffold(
2021-08-29 22:25:18 +00:00
appBar: FreezerAppBar(item.value.title.toString()),
body: SingleChildScrollView(
child: HomePageScreen(
channel: item.value,
)),
2021-11-01 16:41:25 +00:00
));
},
);
2020-11-28 21:32:17 +00:00
case HomePageItemType.SHOW:
return ShowCard(
item.value,
onTap: () {
2021-11-01 16:41:25 +00:00
Navigator.of(context).pushRoute(
builder: (context) => ShowScreen(item.value));
2020-11-28 21:32:17 +00:00
},
);
2021-09-01 12:38:32 +00:00
default:
return const SizedBox(height: 0, width: 0);
}
}
}