diff --git a/.gitignore b/.gitignore index b03cd4a..af00231 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release -/lib/screens/home_screen_v2.dart -/lib/screens/movie_detail_screen.dart -/lib/services/API -/lib/services/Database helper.dart +/lib/screens/home_screen.dart \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index ef31b03..62e24d9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,14 @@ // ignore_for_file: prefer_const_constructors, prefer_final_fields, prefer_const_literals_to_create_immutables import 'package:flutter/material.dart'; +import 'package:movie_app/models/movie_model.dart'; import 'package:movie_app/screens/category_screen.dart'; -import 'package:movie_app/screens/home_screen.dart'; +import 'package:movie_app/screens/favourite_screen.dart'; +import 'package:movie_app/screens/home_screen_v2.dart'; import 'package:movie_app/screens/settings_screen.dart'; -import 'package:movie_app/screens/wishlist_screen.dart'; +import 'package:movie_app/services/API/api.dart'; +import 'package:movie_app/services/Database%20helper.dart'; + void main() { runApp(const MyApp()); @@ -39,10 +43,16 @@ class MovieApp extends StatefulWidget { class _MovieAppState extends State { int _selectedIndex = 0; + + @override + void initState() { + super.initState(); + Database_helper.instance.createDatabase(); + } static List _widgets = [ - HomeScreen(), + MyHomePage(), CategoryScreen(), - WishlistScreen(), + fav_screen(), SettingsScreen() ]; diff --git a/lib/models/movie_model.dart b/lib/models/movie_model.dart new file mode 100644 index 0000000..839a69f --- /dev/null +++ b/lib/models/movie_model.dart @@ -0,0 +1,34 @@ +import 'package:flutter/foundation.dart'; + +class Movie_model { + late int id; + late double populartiy; + late String title; + late String posterPath; + late bool adult; + late String backDropPath; + late String overview; + late String language; + late double rating; + late String date; + Movie_model({ required this.id,required this.populartiy,required this.title,required this.posterPath,required this.adult,required this.backDropPath,required this.overview, + required this.language,required this.rating ,required this.date}); + factory Movie_model.fromMap(Map map) + { + return Movie_model(id:map['id'],populartiy: map['popularity'],title: map['title'], posterPath: map['poster_path'], adult: map['adult'], backDropPath: map['backdrop_path'], overview: map['overview'], language: map['original_language'], rating: map['vote_average'], date: map['release_date']); + } + Map toMap(){ + return { + 'id':id, + 'popularity':populartiy, + 'title':title, + 'poster_path':posterPath, + 'adult':adult, + 'backdrop_path':backDropPath, + 'overview':overview, + 'original_language':language, + 'vote_average':rating, + 'release_date':date + }; + } +} \ No newline at end of file diff --git a/lib/screens/favourite_screen.dart b/lib/screens/favourite_screen.dart new file mode 100644 index 0000000..bb39d29 --- /dev/null +++ b/lib/screens/favourite_screen.dart @@ -0,0 +1,133 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:movie_app/services/Database%20helper.dart'; + +class fav_screen extends StatefulWidget { + @override + State createState() => _fav_screenState(); +} + +class _fav_screenState extends State { + @override + void initState() { + super.initState(); + _loadFavorites(); + Database_helper.instance.favoriteNotifier.addListener(_onFavoritesChanged); + } + + @override + void dispose() { + Database_helper.instance.favoriteNotifier + .removeListener(_onFavoritesChanged); + super.dispose(); + } + + void _onFavoritesChanged() { + if (mounted) { + _loadFavorites(); + } + } + + Future _loadFavorites() async { + movies = + await Database_helper.instance.getDataFromDatabase(Database_helper.db); + if (mounted) { + setState(() { + movies = movies; + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + elevation: 0, + backgroundColor: Colors.black, + title: Text( + "My List ", + style: GoogleFonts.montserrat( + fontSize: 22, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.white, + ), + ), + ), + body: ListView.builder( + itemCount: movies.length, + itemBuilder: (context, index) => Padding( + padding: const EdgeInsets.only(top: 10,bottom: 10,left: 7), + child: Row( + children: [ + Expanded( + child: Container( + //margin: EdgeInsets.symmetric(horizontal: 5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15) + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(15), + child:Image.network( + "https://image.tmdb.org/t/p/original/${movies[index]['image']}", + height: 100, + width: double.infinity, + fit: BoxFit.cover,) , + ), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + movies[index]['title'], + //overflow: TextOverflow.ellipsis, + style: GoogleFonts.montserrat( + fontSize: 15, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.white, + ), + ), + ], + ), + ), + ), + IconButton( + icon: Icon( + Icons.delete, + color: Colors.white, + ), + onPressed: () async { + await Database_helper.instance + .deleteFromDatabase(movies[index]['id']); + _loadFavorites(); + }, + ), + ], + )), + ), + ); + } +} +// ListTile( +// leading: Image.network("https://image.tmdb.org/t/p/original/${movies[index]['image']}",), +// title: Text(movies[index]['title'],style: GoogleFonts.montserrat( +// fontSize: 20, +// fontWeight: FontWeight.bold, +// fontStyle: FontStyle.italic, +// color: Colors.white, +// ),), +// trailing: IconButton( +// icon: Icon(Icons.delete,color: Colors.white,), +// onPressed: () async{ +// await Database_helper.instance.deleteFromDatabase(movies[index]['id']); +// _loadFavorites(); +// }, +// ),),${movies[index]['image']} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart deleted file mode 100644 index 81f51fc..0000000 --- a/lib/screens/home_screen.dart +++ /dev/null @@ -1,173 +0,0 @@ -// ignore_for_file: prefer_const_constructors - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:movie_app/models/movie.dart'; -import 'package:movie_app/widgets/category_widget.dart'; -import 'package:movie_app/widgets/movie_card.dart'; - -class HomeScreen extends StatelessWidget { - HomeScreen({super.key}); - final Movie movieTest = Movie( - name: 'One Piece', - image: Image.network( - 'https://static.wikia.nocookie.net/onepiece/images/b/bd/One_Piece_Live_Action_Epic_Poster.png/revision/latest?cb=20230830194014', - fit: BoxFit.fill, - height: 1000, - width: 1000, - )); - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.black, - appBar: AppBar( - backgroundColor: Colors.transparent, - title: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Icon( - Icons.movie, - color: Colors.white, - ), - Row( - children: [ - IconButton( - onPressed: () {}, - icon: Icon( - Icons.search, - color: Colors.white, - ), - ), - ], - ) - ], - ), - ), - body: ListView( - children: [ - Container( - margin: EdgeInsets.fromLTRB(30, 0, 30, 0), - height: 500, - child: movieTest.image, - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(9, 20, 9, 0), - child: ElevatedButton( - onPressed: () {}, - style: ElevatedButton.styleFrom( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8), - // ), - backgroundColor: Colors.transparent, - ), - child: Column( - children: const [ - Icon( - Icons.add, - color: Colors.white, - ), - Text( - 'My List', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(8, 20, 12, 0), - child: ElevatedButton( - onPressed: () {}, - style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - ), - child: Text('Play'), - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(9, 20, 9, 0), - child: ElevatedButton( - onPressed: () {}, - style: ElevatedButton.styleFrom( - // shape: RoundedRectangleBorder( - // borderRadius: BorderRadius.circular(8), - // ), - backgroundColor: Colors.transparent, - ), - child: Column( - children: const [ - Icon( - Icons.info_outline, - color: Colors.white, - ), - Text( - ' Info ', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ), - ), - ], - ), - // movieTest.image, - CategoryWidget( - categoryName: "Sci-fi", - categoryMovies: [ - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - ], - ), - CategoryWidget( - categoryName: "Drama", - categoryMovies: [ - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - ], - ), - CategoryWidget( - categoryName: "Action", - categoryMovies: [ - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - movieTest, - ], - ), - ], - ), - ); - } -} diff --git a/lib/screens/home_screen_v2.dart b/lib/screens/home_screen_v2.dart new file mode 100644 index 0000000..0ca707d --- /dev/null +++ b/lib/screens/home_screen_v2.dart @@ -0,0 +1,250 @@ +import 'package:carousel_slider/carousel_options.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:movie_app/models/movie_model.dart'; +import 'package:movie_app/screens/favourite_screen.dart'; +import 'package:movie_app/screens/movie_detail_screen.dart'; +import 'package:movie_app/services/API/api.dart'; + +import 'package:movie_app/services/Database%20helper.dart'; + +class MyHomePage extends StatefulWidget { + const MyHomePage({super.key}); + + @override + State createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State { + late Future> upcomingMovies; + late Future> topRatedMovies; + late Future> popularMovies; + + @override + void initState() { + super.initState(); + upcomingMovies = API().getUpcomingMovies(); + topRatedMovies = API().getTopRatedMovies(); + popularMovies = API().getPopularMovies(); + // Database_helper.instance.createDatabase(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + appBar: AppBar( + backgroundColor: Colors.black, + leading: IconButton( + icon: Icon( + Icons.menu, + ), + onPressed: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => fav_screen()),); + }, + ), + centerTitle: true, + title: Text( + "Show Spot", + style: GoogleFonts.montserrat( + fontSize: 22, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.white, + ), + ), + actions: [ + IconButton( + icon: Icon( + Icons.search_rounded, + ), + onPressed: () {}, + ), + IconButton( + icon: Icon( + Icons.notifications, + ), + onPressed: () {}, + ), + ], + ), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "UpComing", + style: GoogleFonts.montserrat( + fontSize: 20, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ), + ), + FutureBuilder( + future: upcomingMovies, + builder: (context, snaphot) { + if (!snaphot.hasData) { + return const Center( + child: CircularProgressIndicator(), + ); + } + final movies = snaphot.data!; + return CarouselSlider.builder( + itemCount: movies.length, + itemBuilder: (context, index, movieindex) { + final movie = movies[index]; + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + movieDetailScreen(movie: movie), + ), + ); + }, + child: Container( + width: double.infinity, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8), + ), + child: Image.network( + "https://image.tmdb.org/t/p/original/${movie.backDropPath}"), + ), + ); + }, + options: CarouselOptions( + autoPlay: true, + enlargeCenterPage: true, + aspectRatio: 1.4, + autoPlayInterval: const Duration(seconds: 3)), + ); + }), + Text( + "Popular", + style: GoogleFonts.montserrat( + fontSize: 20, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ), + ), + Container( + margin: EdgeInsets.symmetric(vertical: 20), + height: 200, + child: FutureBuilder( + future: popularMovies, + builder: (context, snaphot) { + if (!snaphot.hasData) { + return const Center( + child: CircularProgressIndicator(), + ); + } + final movies = snaphot.data!; + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: movies.length, + itemBuilder: (context, index) { + final movie = movies[index]; + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + movieDetailScreen(movie: movie), + ), + ); + }, + child: Container( + width: 150, + margin: EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15) + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(15), + child:Image.network( + "https://image.tmdb.org/t/p/original/${movie.backDropPath}", + height: 120, + width: double.infinity, + fit: BoxFit.cover,) , + ), + ), + ); + }, + ); + }), + ), + Text( + "Top Rated", + style: GoogleFonts.montserrat( + fontSize: 20, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ), + ), + Container( + margin: EdgeInsets.symmetric(vertical: 20), + height: 200, + child: FutureBuilder( + future: topRatedMovies, + builder: (context, snaphot) { + if (!snaphot.hasData) { + return const Center( + child: CircularProgressIndicator(), + ); + } + final movies = snaphot.data!; + return ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: movies.length, + itemBuilder: (context, index) { + final movie = movies[index]; + return GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + movieDetailScreen(movie: movie), + ), + ); + }, + child: Container( + width: 150, + margin: EdgeInsets.symmetric(horizontal: 20), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15) + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(15), + child:Image.network( + "https://image.tmdb.org/t/p/original/${movie.backDropPath}", + height: 120, + width: double.infinity, + fit: BoxFit.cover,) , + ), + ), + ); + }, + ); + }), + ) + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/movie_detail_screen.dart b/lib/screens/movie_detail_screen.dart new file mode 100644 index 0000000..9149b80 --- /dev/null +++ b/lib/screens/movie_detail_screen.dart @@ -0,0 +1,275 @@ +import 'package:flutter/material.dart'; +import 'package:movie_app/models/movie_model.dart'; +import 'package:movie_app/services/Database%20helper.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:google_fonts/google_fonts.dart'; +class movieDetailScreen extends StatefulWidget { + late Movie_model movie; + + movieDetailScreen({required this.movie}); + @override + State createState() => _movieDetailScreenState(); +} + +class _movieDetailScreenState extends State { + late Movie_model movie; + bool isLoveActivated = false; + late Database db; + @override + // int randomInt = movie.rating/2 as int; + List star() { + List starList = []; + int realNumber = (movie.rating/2).floor(); + int partNumber = (((movie.rating/2) - realNumber) * 10).ceil(); + for (int i = 0; i < 6; i++) { + if (i < realNumber) { + starList.add(Icon(Icons.star, color: Colors.amber, size: 20,)); + } + else if (i == realNumber) { + + } + else { + starList.add(Icon(Icons.star, color: Colors.grey, size: 20,)); + } + } + return starList; + } + Future _checkFavoriteStatus() async { + final isFav = await Database_helper.instance.isFavorite(movie.id); + print(isFav); + setState(() { + isLoveActivated = isFav!; + }); + } + Future _toggleFavorite() async { + if (isLoveActivated) { + Database_helper.instance.deleteFromDatabase(movie.id); + } else { + await Database_helper.instance.insertToDatabase( + id: movie.id, title: movie.title, image: movie.backDropPath); + } + setState(() { + isLoveActivated = !isLoveActivated; + }); + } + void initState() { + super.initState(); + movie = widget.movie; + _checkFavoriteStatus(); + + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.black, + floatingActionButtonLocation: FloatingActionButtonLocation.endDocked, + floatingActionButton: FloatingActionButton( + backgroundColor: Color(0xFFD04848), + // backgroundColor: isLoveActivated ?Colors.white :Colors.red, + child: Icon( + isLoveActivated ? Icons.remove_circle : Icons.favorite, + color: Colors.black, + size: 35, + ), + onPressed: () { + setState(() { + _toggleFavorite(); + }); + }, + ), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + SizedBox( + height: 450, + width: MediaQuery + .of(context) + .size + .width, + child: ClipRRect( + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(15), + bottomLeft: Radius.circular(15)), + child: Image.network( + "https://image.tmdb.org/t/p/original/${movie.backDropPath}", + scale: 20, + fit: BoxFit.cover, + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 35, horizontal: 15), + child: Container( + child: Container( + width: 50, + height: 50, + decoration: BoxDecoration( + color: Colors.black, + borderRadius: BorderRadius.circular(15)), + child: IconButton( + color: Colors.white, + icon: Icon(Icons.arrow_back, size: 30, + color: Colors.white,), + onPressed: () { + Navigator.of(context).pop(); + }, + )), + ), + ), + ], + ), + Padding( + padding: EdgeInsets.only( + top: 20, right: 20, left: 20), + child: Text( + "Title :", + style:GoogleFonts.montserrat( + fontSize: 20, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ), + ), + ), + Padding( + padding: EdgeInsets.only(left: 20,top: 5), + child: Text(movie.title+' (' + movie.date.substring(0,4) + ')', style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white + ),), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5), + child: Row( + children: + star(), + ), + ), + Padding( + padding: const EdgeInsets.only( + top: 5, left: 20, bottom: 7), + child: Text( + "Storyline :", + style: GoogleFonts.montserrat( + fontSize: 20, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ), + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Text( + movie.overview, + style: TextStyle( + fontSize: 15, + color: Colors.white + ),), + ), + SizedBox( + height: 10, + ), + Padding( + padding: EdgeInsets.only( + top: 10, right: 20, left: 20, bottom: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Text("Popularity", style: GoogleFonts.montserrat( + fontSize: 18, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ),), + SizedBox(height: 10,), + Text(movie.populartiy.floor().toString(), style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: Colors.white + ),) + ], + ), + Container( + height: 35, + child: VerticalDivider( + color: Colors.amber, + thickness: 2, + width: 11, + ), + ), + Column( + children: [ + Text("Language", style: GoogleFonts.montserrat( + fontSize: 18, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ),), + SizedBox(height: 10,), + Text(movie.language.toUpperCase(), style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: Colors.white + ),) + ], + ), + Container( + height: 35, + child: VerticalDivider( + color: Colors.amber, + thickness: 2, + width: 10, + ), + ), + Column( + children: [ + Text("Rating", style: GoogleFonts.montserrat( + fontSize: 18, + fontWeight: FontWeight.bold, + fontStyle: FontStyle.italic, + color: Colors.amber, + ),), + SizedBox(height: 10,), + Text(movie.rating.floor().toString()+'/10', style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.bold, + color: Colors.white + ),) + ], + ), + ], + ) + ), + SizedBox(height: 13,), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 50), + child: ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(8), + backgroundColor: MaterialStateProperty.all( + Color(0xFFD04848)), // Background color + minimumSize: MaterialStateProperty.all(Size(200, 50)), + ), + child: Text("Watch Now", style: TextStyle( + fontWeight: FontWeight.bold, fontSize: 15 + ),), + onPressed: () { + }, + ), + ), + ], + ), + ), + ); + } + } + diff --git a/lib/screens/wishlist_screen.dart b/lib/screens/wishlist_screen.dart deleted file mode 100644 index d3be3a7..0000000 --- a/lib/screens/wishlist_screen.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/material.dart'; - -class WishlistScreen extends StatelessWidget { - const WishlistScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Placeholder(); - } -} \ No newline at end of file diff --git a/lib/services/API/Constants.dart b/lib/services/API/Constants.dart new file mode 100644 index 0000000..f418bc2 --- /dev/null +++ b/lib/services/API/Constants.dart @@ -0,0 +1 @@ +const apiKey = "f5aa37718545ca90afc97b445ad6339a"; \ No newline at end of file diff --git a/lib/services/API/api.dart b/lib/services/API/api.dart new file mode 100644 index 0000000..8f8d1a9 --- /dev/null +++ b/lib/services/API/api.dart @@ -0,0 +1,51 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; + +import 'package:movie_app/models/movie_model.dart'; +import 'package:movie_app/services/API/Constants.dart'; + +class API { + late String upComingApiUrl = + "https://api.themoviedb.org/3/movie/upcoming?api_key=$apiKey"; + late String popularApiUrl = + "https://api.themoviedb.org/3/movie/popular?api_key=$apiKey"; + late String topRatedApiUrl = + "https://api.themoviedb.org/3/movie/top_rated?api_key=$apiKey"; + + Future> getUpcomingMovies() async { + final response = await http.get(Uri.parse(upComingApiUrl)); + if(response.statusCode == 200) + { + final List data = json.decode(response.body)['results']; + List Movies = data.map((movie) => Movie_model.fromMap(movie)).toList(); + return Movies; + }else{ + throw Exception('Failed to load Upcoming movies'); + } + } + + Future> getTopRatedMovies() async { + final response = await http.get(Uri.parse(topRatedApiUrl)); + if(response.statusCode == 200) + { + final List data = json.decode(response.body)['results']; + List Movies = data.map((movie) => Movie_model.fromMap(movie)).toList(); + return Movies; + }else{ + throw Exception('Failed to load TopRated movies'); + } + } + + Future> getPopularMovies() async { + final response = await http.get(Uri.parse(popularApiUrl)); + if(response.statusCode == 200) + { + final List data = json.decode(response.body)['results']; + List Movies = data.map((movie) => Movie_model.fromMap(movie)).toList(); + return Movies; + }else{ + throw Exception('Failed to load Popular movies'); + } + } +} diff --git a/lib/services/Database helper.dart b/lib/services/Database helper.dart new file mode 100644 index 0000000..0b0f510 --- /dev/null +++ b/lib/services/Database helper.dart @@ -0,0 +1,74 @@ + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:sqflite/sqflite.dart'; +List movies = []; +class Database_helper{ + static final Database_helper instance = Database_helper._init(); + + static Database? db; + Database_helper._init(); + final _favoriteNotifier = ValueNotifier>([]); + ValueListenable> get favoriteNotifier => + _favoriteNotifier; + void createDatabase() async { + db = await openDatabase( + 'fav.db', + onCreate: (db, version) async { + print("Database is created"); + await db + .execute( + ' CREATE TABLE favs (id INTEGER PRIMARY KEY, title TEXT ,image TEXT )') + .then((value) { + print("table is created"); + }).catchError((error) { + print("Error when creating table"); + }); + }, + onOpen: (db) { + getDataFromDatabase(db).then((value) { + movies = value; + print(movies); + }); + print("Database is opened"); + }, + version: 1, + ); + } + + Future insertToDatabase({required int id,required String title,required String image}) async { + await db?.transaction((txn) async { + try { + txn.rawInsert( + 'INSERT INTO favs(id,title,image) VALUES("$id","$title","$image")'); + print('Inserted Successfully'); + } catch (error) { + print('Error inserting into database: $error'); + } + }); + } + Future isFavorite(int productId) async { + // final db = instance._db; + final result = await db?.query( + 'favs', + where: ' Id = ?', + whereArgs: [productId], + ); + return result?.isNotEmpty; + } +Future> getDataFromDatabase(database)async{ + movies = await database.rawQuery('SELECT * FROM favs'); + _favoriteNotifier.value = movies; + return movies; + } + Future deleteFromDatabase(int id) async{ + late var result; + try { + result = await db?.rawDelete('DELETE FROM favs WHERE id = $id'); + print('Deleted Successfully'); + } catch (e) { + print('Error deleting item: $e'); + } + return result; + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 0c74448..b4a1562 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -116,7 +116,7 @@ packages: source: hosted version: "6.2.0" http: - dependency: transitive + dependency: "direct main" description: name: http sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" diff --git a/pubspec.yaml b/pubspec.yaml index 45b3a19..94bc025 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -39,6 +39,7 @@ dependencies: google_fonts: ^6.2.0 sqflite: ^2.3.3 carousel_slider: ^4.2.1 + http: ^1.2.1 dev_dependencies: flutter_test: