From 76d0538f96599fa753329e1c070db0f044aa5996 Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Tue, 4 Jan 2022 22:45:26 +0600 Subject: [PATCH] Working Sidebar added Unauthorized error fix Settings Page (initial) Redesinged PlaylistView with Table --- assets/spotube-logo.png | Bin 0 -> 84203 bytes lib/components/Home.dart | 200 +++++++++++++++++------------ lib/components/Login.dart | 66 +++++++--- lib/components/PlayerControls.dart | 5 +- lib/components/PlaylistView.dart | 147 ++++++++++++++++----- lib/components/Settings.dart | 46 +++++++ lib/components/TrackButton.dart | 77 ----------- lib/helpers/zero-pad-num-str.dart | 3 + lib/main.dart | 34 ++++- lib/models/LocalStorageKeys.dart | 7 + lib/provider/Auth.dart | 30 ++++- pubspec.yaml | 4 +- 12 files changed, 399 insertions(+), 220 deletions(-) create mode 100644 assets/spotube-logo.png create mode 100644 lib/components/Settings.dart delete mode 100644 lib/components/TrackButton.dart create mode 100644 lib/helpers/zero-pad-num-str.dart create mode 100644 lib/models/LocalStorageKeys.dart diff --git a/assets/spotube-logo.png b/assets/spotube-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0793df19c3974b523bec172324795730871677cd GIT binary patch literal 84203 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 UX71R7nz@ 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 literal 0 HcmV?d00001 diff --git a/lib/components/Home.dart b/lib/components/Home.dart index 463c76ba..a50e4dad 100644 --- a/lib/components/Home.dart +++ b/lib/components/Home.dart @@ -1,15 +1,26 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart' hide Page; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:spotify/spotify.dart'; +import 'package:spotify/spotify.dart' hide Image; import 'package:spotube/components/CategoryCard.dart'; import 'package:spotube/components/Login.dart'; import 'package:spotube/components/Player.dart' as player; +import 'package:spotube/components/Settings.dart'; +import 'package:spotube/models/LocalStorageKeys.dart'; import 'package:spotube/models/sideBarTiles.dart'; import 'package:spotube/provider/Auth.dart'; import 'package:spotube/provider/SpotifyDI.dart'; +List spotifyScopes = [ + "user-library-read", + "user-library-modify", + "user-read-private", + "user-read-email", + "playlist-read-collaborative" +]; + class Home extends StatefulWidget { const Home({Key? key}) : super(key: key); @@ -21,6 +32,8 @@ class _HomeState extends State { final PagingController _pagingController = PagingController(firstPageKey: 0); + int _selectedIndex = 0; + @override void initState() { super.initState(); @@ -28,24 +41,36 @@ class _HomeState extends State { try { Auth authProvider = context.read(); SharedPreferences localStorage = await SharedPreferences.getInstance(); - String? clientId = localStorage.getString('client_id'); - String? clientSecret = localStorage.getString('client_secret'); + var clientId = localStorage.getString(LocalStorageKeys.clientId); + var clientSecret = + localStorage.getString(LocalStorageKeys.clientSecret); + var accessToken = localStorage.getString(LocalStorageKeys.accessToken); + var refreshToken = + localStorage.getString(LocalStorageKeys.refreshToken); + var expirationStr = localStorage.getString(LocalStorageKeys.expiration); + var expiration = + expirationStr != null ? DateTime.parse(expirationStr) : null; if (clientId != null && clientSecret != null) { SpotifyApi spotifyApi = SpotifyApi( - SpotifyApiCredentials(clientId, clientSecret, scopes: [ - "user-library-read", - "user-library-modify", - "user-read-private", - "user-read-email", - "playlist-read-collaborative" - ]), + SpotifyApiCredentials( + clientId, + clientSecret, + accessToken: accessToken, + refreshToken: refreshToken, + expiration: expiration, + scopes: spotifyScopes, + ), ); SpotifyApiCredentials credentials = await spotifyApi.getCredentials(); if (credentials.accessToken?.isNotEmpty ?? false) { authProvider.setAuthState( - clientId: credentials.clientId, - clientSecret: credentials.clientSecret, + clientId: clientId, + clientSecret: clientSecret, + accessToken: + credentials.accessToken, // accessToken can be new/refreshed + refreshToken: refreshToken, + expiration: credentials.expiration, isLoggedIn: true, ); } @@ -89,87 +114,98 @@ class _HomeState extends State { return Scaffold( body: Column( children: [ - // Side Tab Bar Expanded( child: Row( children: [ - Container( - color: Colors.blueGrey[50], - constraints: const BoxConstraints(maxWidth: 230), - child: Material( - type: MaterialType.transparency, - child: Column( - children: [ - Flexible( - flex: 1, - // TabButtons - child: Column( - children: [ - ListTile( - title: Text("Spotube", - style: - Theme.of(context).textTheme.headline4), - leading: - const Icon(Icons.miscellaneous_services), + NavigationRail( + backgroundColor: Colors.blueGrey[50], + destinations: sidebarTileList + .map((e) => NavigationRailDestination( + icon: Icon(e.icon), + label: Text( + e.title, + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, ), - const SizedBox(height: 20), - ...sidebarTileList - .map( - (sidebarTile) => ListTile( - title: Text(sidebarTile.title), - leading: Icon(sidebarTile.icon), - onTap: () {}, - ), - ) - .toList(), + ), + )) + .toList(), + selectedIndex: _selectedIndex, + onDestinationSelected: (value) => setState(() { + _selectedIndex = value; + }), + extended: true, + leading: Padding( + padding: const EdgeInsets.only(left: 15), + child: Row(children: [ + Image.asset( + "assets/spotube-logo.png", + height: 50, + width: 50, + ), + const SizedBox( + width: 10, + ), + Text("Spotube", + style: Theme.of(context).textTheme.headline4), + ]), + ), + trailing: + Consumer(builder: (context, data, widget) { + return FutureBuilder( + future: data.spotifyApi.me.get(), + builder: (context, snapshot) { + var avatarImg = snapshot.data?.images?.last.url; + return Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + if (avatarImg != null) + CircleAvatar( + child: CachedNetworkImage( + imageUrl: avatarImg, + ), + ), + Text( + snapshot.data?.displayName ?? "User's name", + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + IconButton( + icon: const Icon(Icons.settings_outlined), + onPressed: () { + Navigator.of(context) + .push(MaterialPageRoute( + builder: (context) { + return const Settings(); + }, + )); + }), ], ), - ), - // user name & settings - Consumer(builder: (context, data, widget) { - return FutureBuilder( - future: data.spotifyApi.me.get(), - builder: (context, snapshot) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Text( - snapshot.data?.displayName ?? - "User's name", - style: const TextStyle( - fontWeight: FontWeight.bold, - ), - ), - IconButton( - icon: - const Icon(Icons.settings_outlined), - onPressed: () {}), - ], - ), - ); - }, - ); - }) - ], - ), - ), + ); + }, + ); + }), ), // contents of the spotify - Expanded( - child: Scrollbar( - child: PagedListView( - pagingController: _pagingController, - builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, item, index) { - return CategoryCard(item); - }, + if (_selectedIndex == 0) + Expanded( + child: Scrollbar( + child: PagedListView( + pagingController: _pagingController, + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, item, index) { + return CategoryCard(item); + }, + ), ), ), ), - ), + // player itself ], ), ), diff --git a/lib/components/Login.dart b/lib/components/Login.dart index 88eb2a1b..5fee5046 100644 --- a/lib/components/Login.dart +++ b/lib/components/Login.dart @@ -2,8 +2,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:spotify/spotify.dart'; +import 'package:spotify/spotify.dart' hide Image; +import 'package:spotube/components/Home.dart'; import 'package:spotube/helpers/server_ipc.dart'; +import 'package:spotube/models/LocalStorageKeys.dart'; import 'package:spotube/provider/Auth.dart'; class Login extends StatefulWidget { @@ -12,38 +14,65 @@ class Login extends StatefulWidget { } class _LoginState extends State { - String client_id = ""; - String client_secret = ""; + String clientId = ""; + String clientSecret = ""; bool _fieldError = false; + String? accessToken; + String? refreshToken; + DateTime? expiration; handleLogin(Auth authState) async { try { - if (client_id == "" || client_secret == "") { + if (clientId == "" || clientSecret == "") { return setState(() { _fieldError = true; }); } - final credentials = SpotifyApiCredentials(client_id, client_secret); + final credentials = SpotifyApiCredentials(clientId, clientSecret); final grant = SpotifyApi.authorizationCodeGrant(credentials); - final redirectUri = "http://localhost:4304/auth/spotify/callback"; - final scopes = ["user-library-read", "user-library-modify"]; + const redirectUri = "http://localhost:4304/auth/spotify/callback"; - final authUri = - grant.getAuthorizationUrl(Uri.parse(redirectUri), scopes: scopes); + final authUri = grant.getAuthorizationUrl(Uri.parse(redirectUri), + scopes: spotifyScopes); final responseUri = await connectIpc(authUri.toString(), redirectUri); + SharedPreferences localStorage = await SharedPreferences.getInstance(); if (responseUri != null) { final SpotifyApi spotify = SpotifyApi.fromAuthCodeGrant(grant, responseUri); + var credentials = await spotify.getCredentials(); + if (credentials.accessToken != null) { + accessToken = credentials.accessToken; + await localStorage.setString( + LocalStorageKeys.accessToken, credentials.accessToken!); + } + if (credentials.refreshToken != null) { + refreshToken = credentials.refreshToken; + await localStorage.setString( + LocalStorageKeys.refreshToken, credentials.refreshToken!); + } + if (credentials.expiration != null) { + expiration = credentials.expiration; + await localStorage.setString(LocalStorageKeys.expiration, + credentials.expiration?.toString() ?? ""); + } } - SharedPreferences localStorage = await SharedPreferences.getInstance(); - await localStorage.setString('client_id', client_id); - await localStorage.setString('client_secret', client_secret); + await localStorage.setString(LocalStorageKeys.clientId, clientId); + await localStorage.setString( + LocalStorageKeys.clientSecret, + clientSecret, + ); authState.setAuthState( - clientId: client_id, clientSecret: client_secret, isLoggedIn: true); + clientId: clientId, + clientSecret: clientSecret, + accessToken: accessToken, + refreshToken: refreshToken, + expiration: expiration, + isLoggedIn: true, + ); } catch (e) { - print(e); + print("[Login.handleLogin] $e"); } } @@ -57,6 +86,11 @@ class _LoginState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ + Image.asset( + "assets/spotube-logo.png", + width: 400, + height: 400, + ), Text("Add your spotify credentials to get started", style: Theme.of(context).textTheme.headline4), const Text( @@ -77,7 +111,7 @@ class _LoginState extends State { ), onChanged: (value) { setState(() { - client_id = value; + clientId = value; }); }, ), @@ -91,7 +125,7 @@ class _LoginState extends State { ), onChanged: (value) { setState(() { - client_secret = value; + clientSecret = value; }); }, ), diff --git a/lib/components/PlayerControls.dart b/lib/components/PlayerControls.dart index 46b4ba04..9a56d573 100644 --- a/lib/components/PlayerControls.dart +++ b/lib/components/PlayerControls.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:mpv_dart/mpv_dart.dart'; +import 'package:spotube/helpers/zero-pad-num-str.dart'; class PlayerControls extends StatefulWidget { final MPVPlayer player; @@ -43,10 +44,6 @@ class _PlayerControlsState extends State { super.dispose(); } - String zeroPadNumStr(int input) { - return input < 10 ? "0$input" : input.toString(); - } - @override Widget build(BuildContext context) { var totalDuration = Duration(seconds: widget.duration.toInt()); diff --git a/lib/components/PlaylistView.dart b/lib/components/PlaylistView.dart index 1872f161..f09ca7b3 100644 --- a/lib/components/PlaylistView.dart +++ b/lib/components/PlaylistView.dart @@ -1,8 +1,11 @@ +import 'dart:ui'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:spotube/helpers/zero-pad-num-str.dart'; import 'package:spotube/provider/Playback.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:spotify/spotify.dart'; -import 'package:spotube/components/TrackButton.dart'; import 'package:spotube/provider/SpotifyDI.dart'; class PlaylistView extends StatefulWidget { @@ -13,6 +16,70 @@ class PlaylistView extends StatefulWidget { } class _PlaylistViewState extends State { + List trackToTableRow(List tracks) { + return tracks.asMap().entries.map((track) { + var thumbnailUrl = track.value.album?.images?.last.url; + var duration = + "${track.value.duration?.inMinutes.remainder(60)}:${zeroPadNumStr(track.value.duration?.inSeconds.remainder(60) ?? 0)}"; + return (TableRow( + children: [ + TableCell( + child: Text( + track.key.toString(), + textAlign: TextAlign.center, + )), + TableCell( + child: Row( + children: [ + if (thumbnailUrl != null) + CachedNetworkImage( + imageUrl: thumbnailUrl, + maxHeightDiskCache: 40, + maxWidthDiskCache: 40, + ), + const SizedBox(width: 10), + Flexible( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + track.value.name ?? "", + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 17, + ), + overflow: TextOverflow.ellipsis, + ), + Text( + (track.value.artists ?? []) + .map((e) => e.name) + .join(", "), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ], + ), + ), + TableCell( + child: Text( + track.value.album?.name ?? "", + overflow: TextOverflow.ellipsis, + ), + ), + TableCell( + child: Text( + duration, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ), + ) + ], + )); + }).toList(); + } + @override Widget build(BuildContext context) { return Consumer(builder: (_, data, __) { @@ -23,6 +90,8 @@ class _PlaylistViewState extends State { .all(), builder: (context, snapshot) { List tracks = snapshot.data?.toList() ?? []; + TextStyle tableHeadStyle = + const TextStyle(fontWeight: FontWeight.bold, fontSize: 16); return Column( children: [ Row( @@ -72,39 +141,49 @@ class _PlaylistViewState extends State { ? const CircularProgressIndicator.adaptive() : Expanded( child: Scrollbar( - isAlwaysShown: true, - child: ListView.builder( - itemCount: tracks.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - return Column( - children: [ - TrackButton( - index: "#", - trackName: "Title", - artists: ["Artist"], - album: "Album", - playback_time: "Time"), - const Divider() - ], - ); - } - Track track = tracks[index - 1]; - return TrackButton( - index: (index - 1).toString(), - thumbnail_url: track - .album?.images?.last.url ?? - "https://i.scdn.co/image/ab67616d00001e02b993cba8ff7d0a8e9ee18d46", - trackName: track.name!, - artists: track.artists! - .map((e) => e.name!) - .toList(), - album: track.album!.name!, - playback_time: track.duration!.inMinutes - .toString(), - onTap: () {}, - ); - }), + child: ListView( + children: [ + SingleChildScrollView( + child: Table( + columnWidths: const { + 0: FixedColumnWidth(40), + 1: FlexColumnWidth(), + 2: FlexColumnWidth(), + 3: FixedColumnWidth(40), + }, + children: [ + TableRow( + children: [ + TableCell( + child: Text( + "#", + textAlign: TextAlign.center, + style: tableHeadStyle, + )), + TableCell( + child: Text( + "Title", + style: tableHeadStyle, + )), + TableCell( + child: Text( + "Album", + style: tableHeadStyle, + )), + TableCell( + child: Text( + "Time", + textAlign: TextAlign.center, + style: tableHeadStyle, + )), + ], + ), + ...trackToTableRow(tracks), + ], + ), + ), + ], + ), ), ), ], diff --git a/lib/components/Settings.dart b/lib/components/Settings.dart new file mode 100644 index 00000000..a36e6267 --- /dev/null +++ b/lib/components/Settings.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:spotube/provider/Auth.dart'; + +class Settings extends StatefulWidget { + const Settings({Key? key}) : super(key: key); + + @override + _SettingsState createState() => _SettingsState(); +} + +class _SettingsState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + elevation: 0, + iconTheme: Theme.of(context).iconTheme, + title: const Text( + "Settings", + ), + centerTitle: true, + titleTextStyle: Theme.of(context).textTheme.headline4, + ), + body: Column( + children: [ + Builder(builder: (context) { + var auth = context.read(); + return ElevatedButton( + child: const Text("Logout"), + onPressed: () async { + SharedPreferences localStorage = + await SharedPreferences.getInstance(); + await localStorage.clear(); + auth.logout(); + Navigator.of(context).pop(); + }, + ); + }) + ], + ), + ); + } +} diff --git a/lib/components/TrackButton.dart b/lib/components/TrackButton.dart deleted file mode 100644 index fc361e18..00000000 --- a/lib/components/TrackButton.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:flutter/material.dart'; - -class TrackButton extends StatefulWidget { - final String index; - final String trackName; - final List artists; - final String album; - final String playback_time; - final String? thumbnail_url; - final void Function()? onTap; - TrackButton({ - required this.index, - required this.trackName, - required this.artists, - required this.album, - required this.playback_time, - this.thumbnail_url, - this.onTap, - }); - - @override - _TrackButtonState createState() => _TrackButtonState(); -} - -class _TrackButtonState extends State { - @override - Widget build(BuildContext context) { - return Material( - child: InkWell( - onTap: widget.onTap, - child: Ink( - padding: const EdgeInsets.all(10), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - Text( - widget.index, - style: const TextStyle(fontSize: 20), - ), - const SizedBox(width: 15), - if (widget.thumbnail_url != null) - CachedNetworkImage( - imageUrl: widget.thumbnail_url!, - maxHeightDiskCache: 50, - maxWidthDiskCache: 50, - ), - const SizedBox(width: 15), - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.trackName, - textAlign: TextAlign.justify, - style: const TextStyle( - fontWeight: FontWeight.bold, fontSize: 17), - ), - Text(widget.artists.join(", ")) - ], - ), - ), - ], - ), - const SizedBox(width: 15), - Text(widget.album), - const SizedBox(width: 15), - Text(widget.playback_time) - ], - ), - ), - ), - ); - } -} diff --git a/lib/helpers/zero-pad-num-str.dart b/lib/helpers/zero-pad-num-str.dart new file mode 100644 index 00000000..f6c0ce10 --- /dev/null +++ b/lib/helpers/zero-pad-num-str.dart @@ -0,0 +1,3 @@ +String zeroPadNumStr(int input) { + return input < 10 ? "0$input" : input.toString(); +} diff --git a/lib/main.dart b/lib/main.dart index 80616a71..478c6220 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:spotify/spotify.dart'; import 'package:spotube/components/Home.dart'; +import 'package:spotube/models/LocalStorageKeys.dart'; import 'package:spotube/provider/Auth.dart'; import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/SpotifyDI.dart'; @@ -18,8 +20,36 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (context) => Auth()), ChangeNotifierProvider(create: (context) { Auth authState = Provider.of(context, listen: false); - return SpotifyDI(SpotifyApi(SpotifyApiCredentials( - authState.cliendId, authState.clientSecret))); + return SpotifyDI( + SpotifyApi( + SpotifyApiCredentials( + authState.clientId, + authState.clientSecret, + accessToken: authState.accessToken, + refreshToken: authState.refreshToken, + expiration: authState.expiration, + scopes: spotifyScopes, + ), + onCredentialsRefreshed: (credentials) async { + SharedPreferences localStorage = + await SharedPreferences.getInstance(); + localStorage.setString( + LocalStorageKeys.refreshToken, + credentials.refreshToken!, + ); + localStorage.setString( + LocalStorageKeys.accessToken, + credentials.accessToken!, + ); + localStorage.setString( + LocalStorageKeys.clientId, credentials.clientId!); + localStorage.setString( + LocalStorageKeys.clientSecret, + credentials.clientSecret!, + ); + }, + ), + ); }), ChangeNotifierProvider(create: (context) => Playback()), ], diff --git a/lib/models/LocalStorageKeys.dart b/lib/models/LocalStorageKeys.dart new file mode 100644 index 00000000..65bbad25 --- /dev/null +++ b/lib/models/LocalStorageKeys.dart @@ -0,0 +1,7 @@ +abstract class LocalStorageKeys { + static String clientId = 'client_id'; + static String clientSecret = 'client_secret'; + static String accessToken = 'access_token'; + static String refreshToken = 'refresh_token'; + static String expiration = " expiration"; +} diff --git a/lib/provider/Auth.dart b/lib/provider/Auth.dart index b6af6b0e..5249b891 100644 --- a/lib/provider/Auth.dart +++ b/lib/provider/Auth.dart @@ -3,10 +3,17 @@ import 'package:flutter/cupertino.dart'; class Auth with ChangeNotifier { String? _clientId; String? _clientSecret; + String? _accessToken; + String? _refreshToken; + DateTime? _expiration; + bool _isLoggedIn = false; - String? get cliendId => _clientId; + String? get clientId => _clientId; String? get clientSecret => _clientSecret; + String? get accessToken => _accessToken; + String? get refreshToken => _refreshToken; + DateTime? get expiration => _expiration; bool get isLoggedIn => _isLoggedIn; void setAuthState({ @@ -14,17 +21,34 @@ class Auth with ChangeNotifier { bool safe = true, String? clientId, String? clientSecret, - String? refresh_token, - String? access_token, + String? refreshToken, + String? accessToken, + DateTime? expiration, }) { if (safe) { if (clientId != null) _clientId = clientId; if (clientSecret != null) _clientSecret = clientSecret; if (isLoggedIn != null) _isLoggedIn = isLoggedIn; + if (refreshToken != null) _refreshToken = refreshToken; + if (accessToken != null) _accessToken = accessToken; + if (expiration != null) _expiration = expiration; } else { _clientId = clientId; _clientSecret = clientSecret; + _accessToken = accessToken; + _refreshToken = refreshToken; + _expiration = expiration; } notifyListeners(); } + + logout() { + _clientId = null; + _clientSecret = null; + _accessToken = null; + _refreshToken = null; + _expiration = null; + _isLoggedIn = false; + notifyListeners(); + } } diff --git a/pubspec.yaml b/pubspec.yaml index dab725e1..bf158dd5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -68,8 +68,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg + assets: + - assets/ # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see