mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
Login guide added
This commit is contained in:
parent
68d10f10c4
commit
89bcfecfb5
BIN
assets/success.png
Normal file
BIN
assets/success.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
69
lib/components/Login/Login.dart
Normal file
69
lib/components/Login/Login.dart
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:spotube/components/Login/LoginForm.dart';
|
||||||
|
import 'package:spotube/components/Shared/Hyperlink.dart';
|
||||||
|
import 'package:spotube/components/Shared/LinkText.dart';
|
||||||
|
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
||||||
|
import 'package:spotube/hooks/useBreakpoints.dart';
|
||||||
|
import 'package:spotube/models/Logger.dart';
|
||||||
|
|
||||||
|
class Login extends HookConsumerWidget {
|
||||||
|
Login({Key? key}) : super(key: key);
|
||||||
|
final log = getLogger(Login);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, ref) {
|
||||||
|
final breakpoint = useBreakpoints();
|
||||||
|
|
||||||
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: const PageWindowTitleBar(leading: BackButton()),
|
||||||
|
body: SingleChildScrollView(
|
||||||
|
child: Center(
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Image.asset(
|
||||||
|
"assets/spotube-logo.png",
|
||||||
|
width: MediaQuery.of(context).size.width *
|
||||||
|
(breakpoint <= Breakpoints.md ? .5 : .3),
|
||||||
|
),
|
||||||
|
Text("Add your spotify credentials to get started",
|
||||||
|
style: breakpoint <= Breakpoints.md
|
||||||
|
? textTheme.headline5
|
||||||
|
: textTheme.headline4),
|
||||||
|
Text(
|
||||||
|
"Don't worry, any of your credentials won't be collected or shared with anyone",
|
||||||
|
style: Theme.of(context).textTheme.caption,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
LoginForm(
|
||||||
|
onDone: () => GoRouter.of(context).pop(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Wrap(
|
||||||
|
alignment: WrapAlignment.center,
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Text("Don't know how to do this?"),
|
||||||
|
TextButton(
|
||||||
|
child: const Text(
|
||||||
|
"Follow along the Step by Step guid",
|
||||||
|
),
|
||||||
|
onPressed: () => GoRouter.of(context).push(
|
||||||
|
"/login-tutorial",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
74
lib/components/Login/LoginForm.dart
Normal file
74
lib/components/Login/LoginForm.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:spotube/helpers/oauth-login.dart';
|
||||||
|
import 'package:spotube/models/Logger.dart';
|
||||||
|
import 'package:spotube/provider/Auth.dart';
|
||||||
|
|
||||||
|
class LoginForm extends HookConsumerWidget {
|
||||||
|
final void Function()? onDone;
|
||||||
|
LoginForm({this.onDone, Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
final log = getLogger(LoginForm);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, ref) {
|
||||||
|
Auth authState = ref.watch(authProvider);
|
||||||
|
final clientIdController = useTextEditingController();
|
||||||
|
final clientSecretController = useTextEditingController();
|
||||||
|
final fieldError = useState(false);
|
||||||
|
|
||||||
|
Future handleLogin(Auth authState) async {
|
||||||
|
try {
|
||||||
|
if (clientIdController.value.text == "" ||
|
||||||
|
clientSecretController.value.text == "") {
|
||||||
|
fieldError.value = true;
|
||||||
|
}
|
||||||
|
await oauthLogin(
|
||||||
|
ref.read(authProvider),
|
||||||
|
clientId: clientIdController.value.text,
|
||||||
|
clientSecret: clientSecretController.value.text,
|
||||||
|
).then(
|
||||||
|
(value) => onDone?.call(),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
log.e("[Login.handleLogin] $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 400,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: clientIdController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Spotify Client ID",
|
||||||
|
label: Text("ClientID"),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.visiblePassword,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
TextField(
|
||||||
|
controller: clientSecretController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Spotify Client Secret",
|
||||||
|
label: Text("Client Secret"),
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.visiblePassword,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await handleLogin(authState);
|
||||||
|
},
|
||||||
|
child: const Text("Submit"),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
180
lib/components/Login/LoginTutorial.dart
Normal file
180
lib/components/Login/LoginTutorial.dart
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:introduction_screen/introduction_screen.dart';
|
||||||
|
import 'package:spotube/components/Login/LoginForm.dart';
|
||||||
|
import 'package:spotube/components/Shared/Hyperlink.dart';
|
||||||
|
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
||||||
|
import 'package:spotube/provider/Auth.dart';
|
||||||
|
|
||||||
|
class LoginTutorial extends ConsumerWidget {
|
||||||
|
const LoginTutorial({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, ref) {
|
||||||
|
final auth = ref.watch(authProvider);
|
||||||
|
|
||||||
|
return Scaffold(
|
||||||
|
appBar: PageWindowTitleBar(
|
||||||
|
leading: TextButton(
|
||||||
|
child: const Text("Exit"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: IntroductionScreen(
|
||||||
|
next: const Text("Next"),
|
||||||
|
back: const Text("Previous"),
|
||||||
|
showBackButton: true,
|
||||||
|
overrideDone: TextButton(
|
||||||
|
child: const Text("Done"),
|
||||||
|
onPressed: auth.isLoggedIn
|
||||||
|
? () {
|
||||||
|
GoRouter.of(context).go("/");
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
pages: [
|
||||||
|
PageViewModel(
|
||||||
|
title: "Step 1",
|
||||||
|
image: CachedNetworkImage(
|
||||||
|
imageUrl:
|
||||||
|
"https://user-images.githubusercontent.com/61944859/111762106-d1d37680-88ca-11eb-9884-ec7a40c0dd27.png"),
|
||||||
|
bodyWidget: Wrap(
|
||||||
|
children: [
|
||||||
|
Text("First, Go to ",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1),
|
||||||
|
Hyperlink(
|
||||||
|
"developer.spotify.com/dashboard ",
|
||||||
|
"https://developer.spotify.com/dashboard",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1!,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"and Login if you're not logged in",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PageViewModel(
|
||||||
|
title: "Step 2",
|
||||||
|
image: CachedNetworkImage(
|
||||||
|
imageUrl:
|
||||||
|
"https://user-images.githubusercontent.com/61944859/111762507-473f4700-88cb-11eb-91f3-d480e9584883.png"),
|
||||||
|
bodyWidget: Text(
|
||||||
|
"Now, create an Spotify Developer Application by Clicking on the \"CREATE AN APP\" button. Give it a name and description too",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PageViewModel(
|
||||||
|
title: "Step 3 [Really Important!]",
|
||||||
|
bodyWidget: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Tap on the \"EDIT SETTINGS\" Button & navigate to \"Redirect URIs\" section",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Wrap(
|
||||||
|
crossAxisAlignment: WrapCrossAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Add",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: Text(
|
||||||
|
"http://localhost:4304/auth/spotify/callback",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1?.copyWith(
|
||||||
|
color: Theme.of(context).primaryColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await Clipboard.setData(
|
||||||
|
const ClipboardData(
|
||||||
|
text: "http://localhost:4304/auth/spotify/callback",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
width: 300,
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
content: Text(
|
||||||
|
"Copied http://localhost:4304/auth/spotify/callback to clipboard",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"to \"Redirect URIs\"",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
Wrap(
|
||||||
|
runSpacing: 10,
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 500),
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl:
|
||||||
|
"https://user-images.githubusercontent.com/61944859/172991668-fa40f247-1118-4aba-a749-e669b732fa4d.jpg",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(maxWidth: 700),
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl:
|
||||||
|
"https://user-images.githubusercontent.com/61944859/111768971-d308a180-88d2-11eb-9108-3e7444cef049.png",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PageViewModel(
|
||||||
|
title: "Step 4",
|
||||||
|
image: CachedNetworkImage(
|
||||||
|
imageUrl:
|
||||||
|
"https://user-images.githubusercontent.com/61944859/111769501-7fe31e80-88d3-11eb-8fc1-f3655dbd4711.png"),
|
||||||
|
body:
|
||||||
|
"Finally, reveal the \"Client Secret\" by clicking on the \"SHOW CLIENT SECRET\" text\n Copy the Client ID & Client Secret then Paste them in the next Screen",
|
||||||
|
),
|
||||||
|
PageViewModel(
|
||||||
|
title: "Step 5",
|
||||||
|
bodyWidget: Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
"Paste the Copied \"Client ID\" and \"Client Secret\" Here",
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
LoginForm(),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (auth.isLoggedIn)
|
||||||
|
PageViewModel(
|
||||||
|
decoration: const PageDecoration(
|
||||||
|
bodyAlignment: Alignment.center,
|
||||||
|
),
|
||||||
|
title: "Success🥳",
|
||||||
|
image: Image.asset("assets/success.png"),
|
||||||
|
body:
|
||||||
|
"Now you're successfully Logged In with your Spotify account. Good Job, mate!",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,108 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:spotube/components/Shared/Hyperlink.dart';
|
|
||||||
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
|
|
||||||
import 'package:spotube/helpers/oauth-login.dart';
|
|
||||||
import 'package:spotube/hooks/useBreakpoints.dart';
|
|
||||||
import 'package:spotube/models/Logger.dart';
|
|
||||||
import 'package:spotube/provider/Auth.dart';
|
|
||||||
|
|
||||||
class Login extends HookConsumerWidget {
|
|
||||||
Login({Key? key}) : super(key: key);
|
|
||||||
final log = getLogger(Login);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, ref) {
|
|
||||||
Auth authState = ref.watch(authProvider);
|
|
||||||
final clientIdController = useTextEditingController();
|
|
||||||
final clientSecretController = useTextEditingController();
|
|
||||||
final fieldError = useState(false);
|
|
||||||
final breakpoint = useBreakpoints();
|
|
||||||
|
|
||||||
Future handleLogin(Auth authState) async {
|
|
||||||
try {
|
|
||||||
if (clientIdController.value.text == "" ||
|
|
||||||
clientSecretController.value.text == "") {
|
|
||||||
fieldError.value = true;
|
|
||||||
}
|
|
||||||
await oauthLogin(
|
|
||||||
ref.read(authProvider),
|
|
||||||
clientId: clientIdController.value.text,
|
|
||||||
clientSecret: clientSecretController.value.text,
|
|
||||||
).then(
|
|
||||||
(value) => GoRouter.of(context).pop(),
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
log.e("[Login.handleLogin] $e");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final textTheme = Theme.of(context).textTheme;
|
|
||||||
|
|
||||||
return Scaffold(
|
|
||||||
appBar: const PageWindowTitleBar(leading: BackButton()),
|
|
||||||
body: SingleChildScrollView(
|
|
||||||
child: Center(
|
|
||||||
child: Container(
|
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 10),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Image.asset(
|
|
||||||
"assets/spotube-logo.png",
|
|
||||||
width: MediaQuery.of(context).size.width *
|
|
||||||
(breakpoint <= Breakpoints.md ? .5 : .3),
|
|
||||||
),
|
|
||||||
Text("Add your spotify credentials to get started",
|
|
||||||
style: breakpoint <= Breakpoints.md
|
|
||||||
? textTheme.headline5
|
|
||||||
: textTheme.headline4),
|
|
||||||
const Text(
|
|
||||||
"Don't worry, any of your credentials won't be collected or shared with anyone"),
|
|
||||||
const Hyperlink("How to get these client-id & client-secret?",
|
|
||||||
"https://github.com/KRTirtho/spotube#optional-configurations"),
|
|
||||||
const SizedBox(
|
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
constraints: const BoxConstraints(
|
|
||||||
maxWidth: 400,
|
|
||||||
),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
TextField(
|
|
||||||
controller: clientIdController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: "Spotify Client ID",
|
|
||||||
label: Text("ClientID"),
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.visiblePassword,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
TextField(
|
|
||||||
controller: clientSecretController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: "Spotify Client Secret",
|
|
||||||
label: Text("Client Secret"),
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.visiblePassword,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
ElevatedButton(
|
|
||||||
onPressed: () async {
|
|
||||||
await handleLogin(authState);
|
|
||||||
},
|
|
||||||
child: const Text("Submit"),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:spotube/components/Shared/AnchorButton.dart';
|
import 'package:spotube/components/Shared/AnchorButton.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
class Hyperlink extends StatelessWidget {
|
class Hyperlink extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
@ -22,7 +23,7 @@ class Hyperlink extends StatelessWidget {
|
|||||||
return AnchorButton(
|
return AnchorButton(
|
||||||
text,
|
text,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await launch(url);
|
await launchUrlString(url);
|
||||||
},
|
},
|
||||||
key: key,
|
key: key,
|
||||||
overflow: overflow,
|
overflow: overflow,
|
||||||
|
@ -4,7 +4,8 @@ import 'package:spotube/components/Album/AlbumView.dart';
|
|||||||
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
import 'package:spotube/components/Artist/ArtistAlbumView.dart';
|
||||||
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
import 'package:spotube/components/Artist/ArtistProfile.dart';
|
||||||
import 'package:spotube/components/Home/Home.dart';
|
import 'package:spotube/components/Home/Home.dart';
|
||||||
import 'package:spotube/components/Settings/Login.dart';
|
import 'package:spotube/components/Login/Login.dart';
|
||||||
|
import 'package:spotube/components/Login/LoginTutorial.dart';
|
||||||
import 'package:spotube/components/Player/PlayerView.dart';
|
import 'package:spotube/components/Player/PlayerView.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
import 'package:spotube/components/Playlist/PlaylistView.dart';
|
||||||
import 'package:spotube/components/Settings/Settings.dart';
|
import 'package:spotube/components/Settings/Settings.dart';
|
||||||
@ -22,6 +23,12 @@ GoRouter createGoRouter() => GoRouter(
|
|||||||
child: Login(),
|
child: Login(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: "/login-tutorial",
|
||||||
|
pageBuilder: (context, state) => const SpotubePage(
|
||||||
|
child: LoginTutorial(),
|
||||||
|
),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: "/settings",
|
path: "/settings",
|
||||||
pageBuilder: (context, state) => const SpotubePage(
|
pageBuilder: (context, state) => const SpotubePage(
|
||||||
@ -71,6 +78,6 @@ GoRouter createGoRouter() => GoRouter(
|
|||||||
child: PlayerView(),
|
child: PlayerView(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
23
pubspec.lock
23
pubspec.lock
@ -37,7 +37,7 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.1"
|
version: "2.3.1"
|
||||||
async:
|
async:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
@ -323,6 +323,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3"
|
version: "0.7.3"
|
||||||
|
dots_indicator:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dots_indicator
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
fading_edge_scrollview:
|
fading_edge_scrollview:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -527,6 +534,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.0"
|
||||||
|
introduction_screen:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: introduction_screen
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -828,13 +842,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
resizable_widget:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: resizable_widget
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.5"
|
|
||||||
riverpod:
|
riverpod:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -63,6 +63,7 @@ dependencies:
|
|||||||
hive_flutter: ^1.1.0
|
hive_flutter: ^1.1.0
|
||||||
dbus: ^0.7.3
|
dbus: ^0.7.3
|
||||||
audioplayers: ^1.0.1
|
audioplayers: ^1.0.1
|
||||||
|
introduction_screen: ^3.0.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user