Play playlist from PlaylistCard support

Login page tuned
Replace loading texts with Circular progress bar
Sidebar icons are rounded now
New Icon & banner
This commit is contained in:
Kingkor Roy Tirtho 2022-01-04 00:00:12 +06:00
parent 0ef44709fa
commit db42e81501
10 changed files with 348 additions and 107 deletions

68
assets/spotube-logo.svg Normal file
View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:bx="https://boxy-svg.com">
<defs>
<filter id="inner-shadow-filter-1" x="-500%" y="-500%" width="1000%" height="1000%" bx:preset="inner-shadow 1 0 0 9 0.5 rgba(0,0,0,0.7)">
<feOffset dx="0" dy="0"/>
<feGaussianBlur stdDeviation="9"/>
<feComposite operator="out" in="SourceGraphic"/>
<feComponentTransfer result="choke">
<feFuncA type="linear" slope="1"/>
</feComponentTransfer>
<feFlood flood-color="rgba(0,0,0,0.7)" result="color"/>
<feComposite operator="in" in="color" in2="choke" result="shadow"/>
<feComposite operator="over" in="shadow" in2="SourceGraphic"/>
</filter>
<linearGradient id="gradient-0-0" gradientUnits="userSpaceOnUse" x1="47.146" y1="18.044" x2="47.146" y2="75.354" xlink:href="#gradient-0"/>
<linearGradient id="gradient-0">
<stop offset="0.031" style="stop-color: rgb(255, 115, 0);"/>
<stop offset="1" style="stop-color: rgb(1, 107, 255);"/>
</linearGradient>
<filter id="inner-shadow-filter-0" x="-500%" y="-500%" width="1000%" height="1000%" bx:preset="inner-shadow 1 0 0 3 0.5 rgba(0,0,0,0.7)">
<feOffset dx="0" dy="0"/>
<feGaussianBlur stdDeviation="3"/>
<feComposite operator="out" in="SourceGraphic"/>
<feComponentTransfer result="choke">
<feFuncA type="linear" slope="1"/>
</feComponentTransfer>
<feFlood flood-color="rgba(0,0,0,0.7)" result="color"/>
<feComposite operator="in" in="color" in2="choke" result="shadow"/>
<feComposite operator="over" in="shadow" in2="SourceGraphic"/>
</filter>
<linearGradient id="gradient-4-1" gradientUnits="userSpaceOnUse" x1="82.026" y1="144.832" x2="82.026" y2="264.462" xlink:href="#gradient-4"/>
<linearGradient id="gradient-4">
<stop offset="0.04" style="stop-color: rgb(255, 107, 1);"/>
<stop offset="0.598" style="stop-color: rgb(0, 234, 255);"/>
<stop offset="0.909" style="stop-color: rgb(8, 85, 140);"/>
</linearGradient>
<linearGradient id="gradient-4-2" gradientUnits="userSpaceOnUse" x1="143.693" y1="22.804" x2="143.693" y2="264.582" xlink:href="#gradient-4"/>
<linearGradient id="gradient-4-0" gradientUnits="userSpaceOnUse" x1="205.862" y1="146.28" x2="205.862" y2="265.91" xlink:href="#gradient-4"/>
</defs>
<ellipse style="paint-order: fill; fill: rgb(255, 255, 255); filter: url(#inner-shadow-filter-1);" cx="249.704" cy="250.295" rx="241.45" ry="241.45"/>
<g transform="matrix(0.372585, 0, 0, 0.376313, 245.872849, 308.773438)" style="">
<g style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill: none; fill-rule: nonzero; opacity: 1;" transform="translate(-175.05 -175.05000000000004) scale(3.89 3.89)">
<path d="M 91.835 18.32 C 91.637 18.132 91.374 18.036 91.096 18.046 C 84.617 18.367 77.578 19.444 68.948 21.435 C 68.677 21.498 68.444 21.67 68.305 21.911 C 68.166 22.152 68.135 22.44 68.217 22.705 L 69.055 25.409 C 62.692 22.996 53.742 21.607 45.995 21.912 C 43.155 21.912 39.913 23.321 36.95 25.412 L 25.235 25.412 L 26.074 22.704 C 26.157 22.438 26.124 22.151 25.986 21.91 C 25.848 21.669 25.615 21.496 25.344 21.434 C 16.714 19.443 9.676 18.366 3.196 18.045 C 2.927 18.033 2.656 18.13 2.457 18.319 C 2.258 18.509 2.146 18.771 2.146 19.045 L 2.146 53.387 C 2.146 53.94 2.594 54.387 3.146 54.387 L 15.524 54.387 C 15.962 54.387 16.35 54.102 16.479 53.683 L 16.951 52.16 C 27.138 64.032 37.497 74.935 45.585 74.935 C 47.142 74.935 48.614 74.524 49.986 73.645 L 50.197 73.859 C 51.141 74.815 52.406 75.346 53.758 75.354 C 53.769 75.354 53.779 75.354 53.79 75.354 C 55.129 75.354 56.387 74.839 57.336 73.903 C 58.17 73.078 58.635 72.03 58.772 70.947 C 59.702 71.718 60.833 72.127 61.978 72.127 C 63.259 72.126 64.542 71.643 65.525 70.673 C 66.634 69.577 67.105 68.092 66.981 66.648 C 67.427 66.758 67.878 66.833 68.331 66.833 C 69.614 66.833 70.869 66.39 71.779 65.491 C 72.735 64.547 73.266 63.282 73.274 61.93 C 73.282 60.578 72.767 59.308 71.887 58.423 C 71.519 57.97 71.139 57.535 70.766 57.089 L 77.582 52.94 L 77.812 53.682 C 77.942 54.101 78.329 54.386 78.767 54.386 L 91.146 54.386 C 91.699 54.386 92.146 53.939 92.146 53.386 L 92.146 19.045 C 92.146 18.771 92.034 18.509 91.835 18.32 Z M 14.787 52.387 L 4.146 52.387 L 4.146 20.102 C 9.952 20.461 16.268 21.437 23.845 23.145 L 14.787 52.387 Z M 70.373 64.067 C 69.234 65.193 67.063 65.072 65.817 63.809 C 65.8 63.792 65.778 63.786 65.76 63.771 C 65.693 63.694 65.642 63.608 65.569 63.534 L 54.619 52.448 C 54.229 52.056 53.598 52.052 53.204 52.439 C 52.811 52.828 52.808 53.46 53.195 53.854 L 64.145 64.94 C 64.714 65.515 65.025 66.283 65.02 67.1 C 65.015 67.916 64.695 68.68 64.119 69.248 C 62.924 70.431 60.991 70.416 59.809 69.222 L 57.384 66.767 C 57.382 66.765 57.381 66.763 57.38 66.762 L 46.43 55.677 C 46.041 55.286 45.408 55.281 45.016 55.668 C 44.623 56.057 44.619 56.689 45.007 57.083 L 55.956 68.169 C 57.138 69.364 57.126 71.298 55.93 72.479 C 54.734 73.661 52.8 73.647 51.62 72.453 L 38.24 58.908 C 37.851 58.516 37.218 58.51 36.826 58.9 C 36.433 59.288 36.429 59.921 36.817 60.314 L 48.528 72.169 C 41.093 76.143 28.778 62.93 17.651 49.901 L 24.616 27.414 L 34.431 27.414 C 31.69 29.846 29.43 32.75 28.339 35.397 C 26.943 38.783 27.852 40.687 28.86 41.688 C 28.886 41.714 28.914 41.739 28.943 41.762 C 32.786 44.809 36.571 45.577 42.466 39.479 C 44.467 39.601 46.171 39.254 47.65 38.415 C 55.956 44.222 63.587 51.376 70.399 59.758 C 71.581 60.953 71.569 62.887 70.373 64.067 Z M 69.464 55.541 C 63.058 48.131 55.937 41.698 48.248 36.395 C 47.907 36.159 47.455 36.159 47.114 36.394 C 45.792 37.301 44.175 37.645 42.17 37.449 C 41.859 37.415 41.556 37.533 41.343 37.759 C 35.758 43.702 32.999 42.415 30.234 40.232 C 29.238 39.193 29.657 37.448 30.188 36.159 C 32.412 30.761 40.301 23.913 46.034 23.912 C 54.206 23.599 63.683 25.188 69.82 27.879 L 76.972 50.97 L 69.464 55.541 Z M 90.146 52.387 L 79.504 52.387 L 70.446 23.145 C 78.023 21.437 84.34 20.461 90.145 20.102 L 90.145 52.387 Z" style="stroke-dasharray: none; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 10; fill-rule: nonzero; opacity: 1; stroke: url(#gradient-0-0); fill: rgb(28, 28, 29); stroke-width: 3.33887px; paint-order: stroke;" stroke-linecap="round"/>
</g>
</g>
<g transform="matrix(1.289989, 0, 0, 1.28817, 62.9105, 31.643152)" style="filter: url(#inner-shadow-filter-0);">
<g>
<path d="M 71.421 155.437 L 71.421 253.857 C 71.421 259.724 76.162 264.462 82.026 264.462 C 87.88 264.462 92.631 259.724 92.631 253.857 L 92.631 155.437 C 92.631 149.581 87.88 144.832 82.026 144.832 C 76.162 144.832 71.421 149.576 71.421 155.437 Z" style="stroke-width: 9.80924px; stroke: url(#gradient-4-1); fill: rgb(29, 29, 29); stroke-linecap: round; stroke-linejoin: round;"/>
<path d="M29.456,264.582h23.351v-116.85c0.064-0.56,0.166-1.119,0.166-1.693c0-50.412,40.69-91.42,90.698-91.42 c50.002,0,90.692,41.008,90.692,91.42c0,0.771,0.113,1.518,0.228,2.263v116.28h23.354c16.254,0,29.442-13.64,29.442-30.469 v-60.936c0-13.878-8.989-25.57-21.261-29.249c-1.129-66.971-55.608-121.124-122.45-121.124 c-66.86,0-121.347,54.158-122.465,121.15C8.956,147.638,0,159.32,0,173.187v60.926C0,250.932,13.187,264.582,29.456,264.582z" style="stroke-width: 11.3184px; stroke: url(#gradient-4-2); fill: rgb(29, 29, 29); stroke-linecap: round; stroke-linejoin: round;"/>
<path d="M 195.258 156.885 L 195.258 255.305 C 195.258 261.172 200.006 265.91 205.862 265.91 C 211.718 265.91 216.466 261.172 216.466 255.305 L 216.466 156.885 C 216.466 151.029 211.718 146.28 205.862 146.28 C 199.995 146.28 195.258 151.024 195.258 156.885 Z" style="stroke-width: 9.80924px; stroke: url(#gradient-4-0); fill: rgb(29, 29, 29); stroke-linecap: round; stroke-linejoin: round;"/>
</g>
</g>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
<g transform="matrix(0.972684, 0, 0, 0.972684, 62.9105, 10.735223)" style=""/>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 736 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -33,8 +33,13 @@ class _HomeState extends State<Home> {
if (clientId != null && clientSecret != null) { if (clientId != null && clientSecret != null) {
SpotifyApi spotifyApi = SpotifyApi( SpotifyApi spotifyApi = SpotifyApi(
SpotifyApiCredentials(clientId, clientSecret, SpotifyApiCredentials(clientId, clientSecret, scopes: [
scopes: ["user-library-read", "user-library-modify"]), "user-library-read",
"user-library-modify",
"user-read-private",
"user-read-email",
"playlist-read-collaborative"
]),
); );
SpotifyApiCredentials credentials = await spotifyApi.getCredentials(); SpotifyApiCredentials credentials = await spotifyApi.getCredentials();
if (credentials.accessToken?.isNotEmpty ?? false) { if (credentials.accessToken?.isNotEmpty ?? false) {
@ -89,7 +94,7 @@ class _HomeState extends State<Home> {
child: Row( child: Row(
children: [ children: [
Container( Container(
color: Colors.grey.shade100, color: Colors.blueGrey[50],
constraints: const BoxConstraints(maxWidth: 230), constraints: const BoxConstraints(maxWidth: 230),
child: Material( child: Material(
type: MaterialType.transparency, type: MaterialType.transparency,
@ -121,39 +126,50 @@ class _HomeState extends State<Home> {
), ),
), ),
// user name & settings // user name & settings
Padding( Consumer<SpotifyDI>(builder: (context, data, widget) {
padding: const EdgeInsets.all(8.0), return FutureBuilder<User>(
child: Row( future: data.spotifyApi.me.get(),
mainAxisAlignment: MainAxisAlignment.spaceBetween, builder: (context, snapshot) {
children: [ return Padding(
const Text( padding: const EdgeInsets.all(8.0),
"User's name", child: Row(
style: TextStyle(fontWeight: FontWeight.bold), mainAxisAlignment:
), MainAxisAlignment.spaceBetween,
IconButton( children: [
icon: const Icon(Icons.settings_outlined), Text(
onPressed: () {}), snapshot.data?.displayName ??
], "User's name",
), style: const TextStyle(
) fontWeight: FontWeight.bold,
),
),
IconButton(
icon:
const Icon(Icons.settings_outlined),
onPressed: () {}),
],
),
);
},
);
})
], ],
), ),
), ),
), ),
// contents of the spotify // contents of the spotify
Consumer<SpotifyDI>(builder: (_, data, __) { Expanded(
return Expanded( child: Scrollbar(
child: Scrollbar( child: PagedListView(
child: PagedListView( pagingController: _pagingController,
pagingController: _pagingController, builderDelegate: PagedChildBuilderDelegate<Category>(
builderDelegate: PagedChildBuilderDelegate<Category>( itemBuilder: (context, item, index) {
itemBuilder: (context, item, index) { return CategoryCard(item);
return CategoryCard(item); },
}, ),
)),
), ),
); ),
}), ),
], ],
), ),
), ),

View File

@ -1,3 +1,4 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -51,43 +52,61 @@ class _LoginState extends State<Login> {
return Consumer<Auth>( return Consumer<Auth>(
builder: (context, authState, child) { builder: (context, authState, child) {
return Scaffold( return Scaffold(
body: Container( body: Center(
padding: EdgeInsets.all(8.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text("Add your spotify credentials to get started", Text("Add your spotify credentials to get started",
style: Theme.of(context).textTheme.headline3), style: Theme.of(context).textTheme.headline4),
Text( const Text(
"Don't worry, any of your credentials won't be collected or shared with anyone"), "Don't worry, any of your credentials won't be collected or shared with anyone"),
TextField( const SizedBox(
decoration: InputDecoration(
hintText: "Spotify Client ID", labelText: "ClientId"),
onChanged: (value) {
setState(() {
client_id = value;
});
},
),
TextField(
decoration: InputDecoration(
hintText: "Spotify Client Secret",
labelText: "ClientSecret"),
onChanged: (value) {
setState(() {
client_secret = value;
});
},
),
SizedBox(
height: 10, height: 10,
), ),
MaterialButton( Container(
color: Theme.of(context).buttonColor, constraints: const BoxConstraints(
onPressed: () { maxWidth: 400,
handleLogin(authState); ),
}, child: Column(
child: Text("Submit"), children: [
) TextField(
decoration: const InputDecoration(
hintText: "Spotify Client ID",
label: Text("ClientID"),
),
onChanged: (value) {
setState(() {
client_id = value;
});
},
),
const SizedBox(
height: 10,
),
TextField(
decoration: const InputDecoration(
hintText: "Spotify Client Secret",
label: Text("Client Secret"),
),
onChanged: (value) {
setState(() {
client_secret = value;
});
},
),
const SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () {
handleLogin(authState);
},
child: const Text("Submit"),
)
],
),
),
], ],
), ),
), ),

View File

@ -115,22 +115,27 @@ class _PlayerState extends State<Player> {
} }
Future playPlaylist(CurrentPlaylist playlist) async { Future playPlaylist(CurrentPlaylist playlist) async {
if (player.isRunning() && playlist.id != _currentPlaylistId) { try {
var playlistPath = "/tmp/playlist-${playlist.id}.txt"; if (player.isRunning() && playlist.id != _currentPlaylistId) {
File file = File(playlistPath); var playlistPath = "/tmp/playlist-${playlist.id}.txt";
var newPlaylist = playlistToStr(playlist); File file = File(playlistPath);
var newPlaylist = playlistToStr(playlist);
if (!await file.exists()) { if (!await file.exists()) {
await file.create(); await file.create();
}
await file.writeAsString(newPlaylist);
await player.loadPlaylist(playlistPath);
setState(() {
_currentPlaylistId = playlist.id;
_shuffled = false;
});
} }
} catch (e, stackTrace) {
await file.writeAsString(newPlaylist); print("[Player]: $e");
print(stackTrace);
await player.loadPlaylist(playlistPath);
setState(() {
_currentPlaylistId = playlist.id;
_shuffled = false;
});
} }
} }

View File

@ -1,11 +1,14 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/PlaylistView.dart'; import 'package:spotube/components/PlaylistView.dart';
import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart';
class PlaylistCard extends StatefulWidget { class PlaylistCard extends StatefulWidget {
PlaylistSimple playlist; final PlaylistSimple playlist;
PlaylistCard(this.playlist); const PlaylistCard(this.playlist, {Key? key}) : super(key: key);
@override @override
_PlaylistCardState createState() => _PlaylistCardState(); _PlaylistCardState createState() => _PlaylistCardState();
} }
@ -22,7 +25,7 @@ class _PlaylistCardState extends State<PlaylistCard> {
)); ));
}, },
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 200), constraints: const BoxConstraints(maxWidth: 200),
child: Ink( child: Ink(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
@ -30,7 +33,7 @@ class _PlaylistCardState extends State<PlaylistCard> {
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
blurRadius: 10, blurRadius: 10,
offset: Offset(0, 3), offset: const Offset(0, 3),
spreadRadius: 5, spreadRadius: 5,
color: Colors.grey.shade300, color: Colors.grey.shade300,
) )
@ -40,21 +43,66 @@ class _PlaylistCardState extends State<PlaylistCard> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
// thumbnail of the playlist // thumbnail of the playlist
ClipRRect( Stack(
borderRadius: BorderRadius.circular(8), children: [
child: CachedNetworkImage( ClipRRect(
imageUrl: widget.playlist.images![0].url!), borderRadius: BorderRadius.circular(8),
child: CachedNetworkImage(
imageUrl: widget.playlist.images![0].url!),
),
Positioned.directional(
textDirection: TextDirection.ltr,
bottom: 10,
end: 5,
child: Builder(builder: (context) {
Playback playback = context.watch<Playback>();
SpotifyDI data = context.watch<SpotifyDI>();
bool isPlaylistPlaying = playback.currentPlaylist !=
null &&
playback.currentPlaylist!.id == widget.playlist.id;
return ElevatedButton(
onPressed: () async {
if (isPlaylistPlaying) return;
List<Track> tracks = (await data.spotifyApi.playlists
.getTracksByPlaylistId(widget.playlist.id!)
.all())
.toList();
playback.setCurrentPlaylist = CurrentPlaylist(
tracks: tracks,
id: widget.playlist.id!,
name: widget.playlist.name!,
thumbnail: widget.playlist.images!.first.url!,
);
},
child: Icon(
isPlaylistPlaying
? Icons.pause_rounded
: Icons.play_arrow_rounded,
),
style: ButtonStyle(
shape: MaterialStateProperty.all(
const CircleBorder(),
),
padding: MaterialStateProperty.all(
const EdgeInsets.all(16),
),
),
);
}),
)
],
), ),
SizedBox(height: 5), const SizedBox(height: 5),
Padding( Padding(
padding: padding:
const EdgeInsets.symmetric(horizontal: 8, vertical: 10), const EdgeInsets.symmetric(horizontal: 8, vertical: 10),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
widget.playlist.name!, widget.playlist.name!,
style: TextStyle(fontWeight: FontWeight.bold), style: const TextStyle(fontWeight: FontWeight.bold),
), ),
], ],
), ),

View File

@ -45,7 +45,7 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
return const Center(child: Text("Error occurred")); return const Center(child: Text("Error occurred"));
} }
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const Center(child: Text("Loading..")); return const CircularProgressIndicator.adaptive();
} }
return Wrap( return Wrap(
children: snapshot.data! children: snapshot.data!

View File

@ -15,7 +15,6 @@ class PlaylistView extends StatefulWidget {
class _PlaylistViewState extends State<PlaylistView> { class _PlaylistViewState extends State<PlaylistView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Playback playback = context.read<Playback>();
return Consumer<SpotifyDI>(builder: (_, data, __) { return Consumer<SpotifyDI>(builder: (_, data, __) {
return Scaffold( return Scaffold(
body: FutureBuilder<Iterable<Track>>( body: FutureBuilder<Iterable<Track>>(
@ -70,7 +69,7 @@ class _PlaylistViewState extends State<PlaylistView> {
snapshot.hasError snapshot.hasError
? const Center(child: Text("Error occurred")) ? const Center(child: Text("Error occurred"))
: !snapshot.hasData : !snapshot.hasData
? const Center(child: Text("Loading..")) ? const CircularProgressIndicator.adaptive()
: Expanded( : Expanded(
child: Scrollbar( child: Scrollbar(
isAlwaysShown: true, isAlwaysShown: true,

View File

@ -27,13 +27,38 @@ class MyApp extends StatelessWidget {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Flutter Demo', title: 'Flutter Demo',
theme: ThemeData( theme: ThemeData(
primaryColor: Colors.greenAccent[400], primaryColor: Colors.greenAccent[400],
primarySwatch: Colors.green, primarySwatch: Colors.green,
buttonTheme: const ButtonThemeData( buttonTheme: const ButtonThemeData(
buttonColor: Colors.green, buttonColor: Colors.green,
), ),
), textTheme: TextTheme(
home: Home(), bodyText1: TextStyle(color: Colors.grey[850]),
headline1: TextStyle(color: Colors.grey[850]),
headline2: TextStyle(color: Colors.grey[850]),
headline3: TextStyle(color: Colors.grey[850]),
headline4: TextStyle(color: Colors.grey[850]),
headline5: TextStyle(color: Colors.grey[850]),
headline6: TextStyle(color: Colors.grey[850]),
),
listTileTheme: ListTileThemeData(
iconColor: Colors.grey[850],
horizontalTitleGap: 0,
),
inputDecorationTheme: InputDecorationTheme(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.green[400]!,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.grey[800]!,
),
),
)),
home: const Home(),
), ),
); );
} }

View File

@ -7,7 +7,7 @@ class SideBarTiles {
} }
List<SideBarTiles> sidebarTileList = [ List<SideBarTiles> sidebarTileList = [
SideBarTiles(icon: Icons.home_filled, title: "Browse"), SideBarTiles(icon: Icons.home_rounded, title: "Browse"),
SideBarTiles(icon: Icons.search, title: "Search"), SideBarTiles(icon: Icons.search_rounded, title: "Search"),
SideBarTiles(icon: Icons.library_books_rounded, title: "Library"), SideBarTiles(icon: Icons.library_books_rounded, title: "Library"),
]; ];