summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2023-06-03 23:36:51 -0600
committerIván Ávalos <avalos@disroot.org>2023-06-03 23:36:51 -0600
commita28fa912bc04f28125c3d62d2e288145233cd789 (patch)
tree0913b5387aeded6206fef98ccc834612debce778
parent17bd9bc740e3be5509b81d42184819324881fe54 (diff)
downloadpmsna1-a28fa912bc04f28125c3d62d2e288145233cd789.tar.gz
pmsna1-a28fa912bc04f28125c3d62d2e288145233cd789.tar.bz2
pmsna1-a28fa912bc04f28125c3d62d2e288145233cd789.zip
Finished practice 5
-rw-r--r--android/build.gradle2
-rw-r--r--lib/database/helper.dart38
-rw-r--r--lib/models/popular.dart22
-rw-r--r--lib/models/popular_credit.dart19
-rw-r--r--lib/models/popular_detail.dart83
-rw-r--r--lib/models/popular_video.dart32
-rw-r--r--lib/network/popular_api.dart29
-rw-r--r--lib/routes.dart2
-rw-r--r--lib/screens/favorites_screen.dart96
-rw-r--r--lib/screens/popular_detail_screen.dart385
-rw-r--r--lib/screens/popular_screen.dart44
-rw-r--r--lib/screens/register_screen.dart2
-rw-r--r--lib/widgets/popular_item.dart40
-rw-r--r--lib/widgets/popular_list.dart38
-rw-r--r--linux/flutter/generated_plugin_registrant.cc4
-rw-r--r--linux/flutter/generated_plugins.cmake1
-rw-r--r--macos/Flutter/GeneratedPluginRegistrant.swift2
-rw-r--r--pubspec.lock202
-rw-r--r--pubspec.yaml7
-rw-r--r--windows/flutter/generated_plugin_registrant.cc6
-rw-r--r--windows/flutter/generated_plugins.cmake2
21 files changed, 941 insertions, 115 deletions
diff --git a/android/build.gradle b/android/build.gradle
index 144835c..f1fb363 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -27,6 +27,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
-task clean(type: Delete) {
+tasks.register("clean", Delete) {
delete rootProject.buildDir
}
diff --git a/lib/database/helper.dart b/lib/database/helper.dart
index da2d199..54e415c 100644
--- a/lib/database/helper.dart
+++ b/lib/database/helper.dart
@@ -4,6 +4,7 @@ import 'dart:io';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pmsna1/models/event.dart';
+import 'package:pmsna1/models/popular.dart';
import 'package:pmsna1/models/post.dart';
import 'package:sqflite/sqflite.dart';
@@ -47,6 +48,14 @@ class DatabaseHelper {
date DATE NOT NULL,
completed INT DEFAULT 0
);""");
+
+ await db.execute("""CREATE TABLE IF NOT EXISTS favorites (
+ id INT PRIMARY KEY,
+ title VARCHAR(128),
+ posterPath VARCHAR(128),
+ backdropPath VARCHAR(128),
+ overview TEXT
+);""");
}
Future<int> insert(String table, Map<String, dynamic> data) async {
@@ -92,4 +101,33 @@ class DatabaseHelper {
List<Map<String, Object?>> result = await conn.query("events");
return result.map((event) => Event.fromMap(event)).toList();
}
+
+ /*
+ * Favorite specific functions
+ */
+
+ Future<List<Popular>> getAllFavorites() async {
+ Database conn = await database;
+ List<Map<String, Object?>> result = await conn.query("favorites");
+ return result.map((p) {
+ Popular popular = Popular.fromDb(p);
+ popular.hasFavorite = true;
+ return popular;
+ }).toList();
+ }
+
+ Future<bool> hasFavorite(int id) async {
+ Database conn = await database;
+ List result =
+ await conn.query("favorites", where: "id = ?", whereArgs: [id]);
+ return result.isNotEmpty;
+ }
+
+ Future<int> favoritePopular(Popular popular) async {
+ return insert('favorites', popular.toDb());
+ }
+
+ Future<int> unfavoritePopular(Popular popular) async {
+ return delete('favorites', 'id', popular.id);
+ }
}
diff --git a/lib/models/popular.dart b/lib/models/popular.dart
index afe6858..a1c136b 100644
--- a/lib/models/popular.dart
+++ b/lib/models/popular.dart
@@ -11,6 +11,8 @@ class Popular {
double? voteAverage;
int? voteCount;
+ bool hasFavorite = false;
+
Popular({
this.backdropPath,
this.id,
@@ -25,6 +27,26 @@ class Popular {
this.voteCount,
});
+ Map<String, dynamic> toDb() {
+ return {
+ "id": id,
+ "title": title,
+ "posterPath": posterPath,
+ "backdropPath": backdropPath,
+ "overview": overview,
+ };
+ }
+
+ factory Popular.fromDb(Map<String, dynamic> map) {
+ return Popular(
+ id: map['id'],
+ title: map['title'],
+ posterPath: map['posterPath'],
+ backdropPath: map['backdropPath'],
+ overview: map['overview'],
+ );
+ }
+
factory Popular.fromMap(Map<String, dynamic> map) {
return Popular(
backdropPath: map['backdrop_path'],
diff --git a/lib/models/popular_credit.dart b/lib/models/popular_credit.dart
new file mode 100644
index 0000000..568beb0
--- /dev/null
+++ b/lib/models/popular_credit.dart
@@ -0,0 +1,19 @@
+class PopularCredit {
+ String? name;
+ String? character;
+ String? profilePath;
+
+ PopularCredit({
+ this.name,
+ this.character,
+ this.profilePath,
+ });
+
+ factory PopularCredit.fromMap(Map<String, dynamic> map) {
+ return PopularCredit(
+ name: map['name'],
+ character: map['character'],
+ profilePath: map['profile_path'],
+ );
+ }
+}
diff --git a/lib/models/popular_detail.dart b/lib/models/popular_detail.dart
new file mode 100644
index 0000000..8b158ac
--- /dev/null
+++ b/lib/models/popular_detail.dart
@@ -0,0 +1,83 @@
+import 'package:pmsna1/models/popular_credit.dart';
+import 'package:pmsna1/models/popular_video.dart';
+
+class Genre {
+ int? id;
+ String? name;
+}
+
+class PopularDetail {
+ bool? adult;
+ String? backdropPath;
+ int? budget;
+ List<Genre>? genres;
+ String? homepage;
+ int? id;
+ String? originalLanguage;
+ String? overview;
+ double? popularity;
+ String? posterPath;
+ String? releaseDate;
+ int? revenue;
+ int? runtime;
+ String? tagline;
+ String? title;
+ bool? video;
+ double? voteAverage;
+ double? voteCount;
+ List<PopularVideo> videos;
+ List<PopularCredit> credits;
+
+ bool hasFavorite = false;
+
+ PopularDetail({
+ this.adult,
+ this.backdropPath,
+ this.budget,
+ this.genres,
+ this.homepage,
+ this.id,
+ this.originalLanguage,
+ this.overview,
+ this.popularity,
+ this.posterPath,
+ this.releaseDate,
+ this.revenue,
+ this.runtime,
+ this.tagline,
+ this.title,
+ this.video,
+ this.voteAverage,
+ this.voteCount,
+ this.videos = const [],
+ this.credits = const [],
+ });
+
+ factory PopularDetail.fromMap(Map<String, dynamic> map) {
+ return PopularDetail(
+ adult: map['adult'],
+ backdropPath: map['backdrop_path'],
+ id: map['id'],
+ originalLanguage: map['original_language'],
+ overview: map['overview'],
+ popularity: map['popularity'],
+ posterPath: map['posterPath'],
+ releaseDate: map['releaseDate'],
+ revenue: map['revenue'],
+ runtime: map['runtime'],
+ tagline: map['tagline'],
+ title: map['title'],
+ video: map['video'],
+ voteAverage: (map['vote_average'] is int)
+ ? (map['vote_average'] as int).toDouble()
+ : map['vote_average'],
+ voteCount: map['voteCount'],
+ videos: (map['videos']['results'] as List<dynamic>)
+ .map((v) => PopularVideo.fromMap(v))
+ .toList(),
+ credits: (map['credits']['cast'] as List<dynamic>)
+ .map((c) => PopularCredit.fromMap(c))
+ .toList(),
+ );
+ }
+}
diff --git a/lib/models/popular_video.dart b/lib/models/popular_video.dart
new file mode 100644
index 0000000..b626431
--- /dev/null
+++ b/lib/models/popular_video.dart
@@ -0,0 +1,32 @@
+class PopularVideo {
+ String? name;
+ String? key;
+ String? site;
+ int? size;
+ String? type;
+ bool? official;
+ String? id;
+
+ PopularVideo({
+ this.name,
+ this.key,
+ this.site,
+ this.size,
+ this.type,
+ this.official,
+ this.id,
+ });
+
+ factory PopularVideo.fromMap(Map<String, dynamic> map) {
+ print(map.toString());
+ return PopularVideo(
+ id: map['id'],
+ key: map['key'],
+ name: map['name'],
+ site: map['site'],
+ size: map['size'],
+ type: map['type'],
+ official: map['official'],
+ );
+ }
+}
diff --git a/lib/network/popular_api.dart b/lib/network/popular_api.dart
index 4d2c033..bf4098a 100644
--- a/lib/network/popular_api.dart
+++ b/lib/network/popular_api.dart
@@ -1,19 +1,42 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
+import 'package:pmsna1/database/helper.dart';
import 'package:pmsna1/models/popular.dart';
+import 'package:pmsna1/models/popular_detail.dart';
class PopularApi {
String apiKey = '0cb894064f40656f3575e8ccae3d8d73';
- Uri get link => Uri.parse(
+ Uri get popularLink => Uri.parse(
'https://api.themoviedb.org/3/movie/popular?api_key=$apiKey&language=es-MX&page=1');
+ Uri getDetailLink(int id) => Uri.parse(
+ 'https://api.themoviedb.org/3/movie/$id?api_key=$apiKey&language=es-MX&page=1&append_to_response=videos,credits',
+ );
Future<List<Popular>?> getAllPopular() async {
- http.Response result = await http.get(link);
+ http.Response result = await http.get(popularLink);
var list = jsonDecode(result.body)['results'] as List;
if (result.statusCode != 200) {
return null;
}
- return list.map((popular) => Popular.fromMap(popular)).toList();
+ List<Popular> favorites = await DatabaseHelper().getAllFavorites();
+ return list.map((p) {
+ Popular popular = Popular.fromMap(p);
+ if (favorites.where((f) => f.id == popular.id).isNotEmpty) {
+ popular.hasFavorite = true;
+ }
+ return popular;
+ }).toList();
+ }
+
+ Future<PopularDetail?> getPopularDetail(int id) async {
+ http.Response result = await http.get(getDetailLink(id));
+ var map = jsonDecode(result.body) as Map<String, dynamic>;
+ if (result.statusCode != 200) {
+ return null;
+ }
+ PopularDetail detail = PopularDetail.fromMap(map);
+ detail.hasFavorite = await DatabaseHelper().hasFavorite(detail.id!);
+ return detail;
}
}
diff --git a/lib/routes.dart b/lib/routes.dart
index 7b64e9c..5f5d192 100644
--- a/lib/routes.dart
+++ b/lib/routes.dart
@@ -8,6 +8,7 @@ import 'package:pmsna1/screens/map_screen.dart';
import 'package:pmsna1/screens/new_event_screen.dart';
import 'package:pmsna1/screens/new_post_screen.dart';
import 'package:pmsna1/screens/onboarding_screen.dart';
+import 'package:pmsna1/screens/popular_detail_screen.dart';
import 'package:pmsna1/screens/popular_screen.dart';
import 'screens/login_screen.dart';
@@ -26,6 +27,7 @@ Map<String, WidgetBuilder> getApplicationRoutes() {
'/albums': (BuildContext context) => const AlbumsScreen(),
'/album': (BuildContext context) => const AlbumDetailScreen(),
'/favorites': (BuildContext context) => const FavoritesScreen(),
+ '/popular_detail': (BuildContext context) => const PopularDetailScreen(),
'/map': (BuildContext context) => const MapSample(),
};
}
diff --git a/lib/screens/favorites_screen.dart b/lib/screens/favorites_screen.dart
index 74432a7..132b61f 100644
--- a/lib/screens/favorites_screen.dart
+++ b/lib/screens/favorites_screen.dart
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
-import 'package:pmsna1/firebase/favorites.dart';
+import 'package:pmsna1/database/helper.dart';
+
+import '../widgets/loading_modal_widget.dart';
+import '../widgets/popular_list.dart';
class FavoritesScreen extends StatefulWidget {
const FavoritesScreen({super.key});
@@ -9,73 +12,48 @@ class FavoritesScreen extends StatefulWidget {
}
class _FavoritesScreenState extends State<FavoritesScreen> {
- final FavoritesFirebase _firebase = FavoritesFirebase();
+ late DatabaseHelper _db;
+
+ @override
+ void initState() {
+ super.initState();
+ _db = DatabaseHelper();
+ }
@override
Widget build(BuildContext context) {
return Scaffold(
- body: StreamBuilder(
- stream: _firebase.getAllFavorites(),
+ appBar: AppBar(title: const Text('Favoritos')),
+ body: FutureBuilder(
+ future: _db.getAllFavorites(),
builder: (context, snapshot) {
if (snapshot.hasData) {
- return ListView.builder(
- itemCount: snapshot.data!.size,
- itemBuilder: (context, index) => ListTile(
- title: Text(snapshot.data!.docs[index].get('title')),
- trailing: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- IconButton(
- onPressed: () {
- // _firebase.insertFavorite({
- // 'title': snapshot.data!.docs[index].get('title')
- // })
- },
- icon: Icon(
- Icons.favorite,
- color: Theme.of(context).colorScheme.onBackground,
- ),
- ),
- IconButton(
- onPressed: () {
- showDialog(
- context: context,
- builder: (context) => AlertDialog(
- title: const Text('Confirmar borrado'),
- content: const Text('¿Desea borrar el post?'),
- actions: [
- TextButton(
- child: const Text('Sí'),
- onPressed: () {
- // Delete post
- _firebase.deleteFavorite(
- snapshot.data!.docs[index].id);
- Navigator.of(context).pop();
- },
- ),
- TextButton(
- child: const Text('No'),
- onPressed: () {
- Navigator.of(context).pop();
- },
- )
- ],
- ),
- );
- },
- icon: Icon(
- Icons.delete,
- color: Theme.of(context).colorScheme.onBackground,
- ),
- ),
- ],
- ),
- ),
+ return PopularList(
+ snapshot.data!,
+ onFavorited: (popular, favorited) {
+ if (favorited) {
+ _db.favoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ } else {
+ _db.unfavoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ }
+ },
+ onPressed: (popular) {
+ Navigator.of(context)
+ .pushNamed('/popular_detail', arguments: popular);
+ },
);
} else if (snapshot.hasError) {
- return const Center(child: Text('Hubo un error'));
+ print(snapshot.error);
+ return const Center(
+ child: Text('Ocurrió un error'),
+ );
+ } else {
+ return const LoadingModal();
}
- return const Center(child: CircularProgressIndicator());
},
),
);
diff --git a/lib/screens/popular_detail_screen.dart b/lib/screens/popular_detail_screen.dart
new file mode 100644
index 0000000..16f7811
--- /dev/null
+++ b/lib/screens/popular_detail_screen.dart
@@ -0,0 +1,385 @@
+import 'dart:ui';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_rating_bar/flutter_rating_bar.dart';
+import 'package:infinite_carousel/infinite_carousel.dart';
+import 'package:pmsna1/database/helper.dart';
+import 'package:pmsna1/models/popular_detail.dart';
+import 'package:pmsna1/models/popular_video.dart';
+import 'package:pmsna1/network/popular_api.dart';
+import 'package:pmsna1/widgets/loading_modal_widget.dart';
+import 'package:youtube/youtube_thumbnail.dart';
+import 'package:youtube_player_iframe/youtube_player_iframe.dart';
+
+import '../models/popular.dart';
+import '../models/popular_credit.dart';
+
+class PopularDetailScreen extends StatefulWidget {
+ const PopularDetailScreen({super.key});
+
+ @override
+ State<PopularDetailScreen> createState() => _PopularDetailScreenState();
+}
+
+class _PopularDetailScreenState extends State<PopularDetailScreen> {
+ late Popular popular;
+ late PopularApi api;
+ late DatabaseHelper _db;
+
+ @override
+ void initState() {
+ super.initState();
+ api = PopularApi();
+ _db = DatabaseHelper();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ popular = ModalRoute.of(context)?.settings.arguments as Popular;
+
+ ImageFiltered backdrop = ImageFiltered(
+ imageFilter: ImageFilter.blur(sigmaX: 9.0, sigmaY: 9.0),
+ child: Image.network(
+ 'https://image.tmdb.org/t/p/w500/${popular.backdropPath!}',
+ fit: BoxFit.cover,
+ alignment: Alignment.center,
+ ),
+ );
+
+ return Scaffold(
+ body: NestedScrollView(
+ headerSliverBuilder: (context, innerBoxIsScrolled) => <Widget>[
+ SliverAppBar(
+ expandedHeight: 200.0,
+ pinned: true,
+ actions: [
+ FutureBuilder(
+ future: _db.hasFavorite(popular.id!),
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ return snapshot.data == true
+ ? IconButton(
+ icon: const Icon(Icons.favorite),
+ onPressed: () {
+ _db.unfavoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ },
+ )
+ : IconButton(
+ icon: const Icon(Icons.favorite_outline),
+ onPressed: () {
+ _db.favoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ },
+ );
+ } else if (snapshot.hasError) {
+ return const SizedBox.shrink();
+ } else {
+ return const CircularProgressIndicator(value: null);
+ }
+ },
+ )
+ ],
+ flexibleSpace: FlexibleSpaceBar(
+ title: Text(popular.title!),
+ background: backdrop,
+ ),
+ )
+ ],
+ body: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(10.0),
+ child: Column(
+ children: [
+ Synopsis(popular: popular),
+ FutureBuilder(
+ future: api.getPopularDetail(popular.id!),
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ PopularDetail detail = snapshot.data!;
+ return Column(
+ children: [
+ Rating(detail.voteAverage),
+ Trailers(detail.videos),
+ Casting(detail.credits),
+ ],
+ );
+ } else if (snapshot.hasError) {
+ print(snapshot.error);
+ return const Center(child: Text('Ocurrió un error'));
+ } else {
+ return const LoadingModal();
+ }
+ },
+ )
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
+
+class Synopsis extends StatelessWidget {
+ const Synopsis({
+ super.key,
+ required this.popular,
+ });
+
+ final Popular popular;
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ clipBehavior: Clip.antiAliasWithSaveLayer,
+ semanticContainer: true,
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Hero(
+ tag: popular.posterPath!,
+ child: Card(
+ clipBehavior: Clip.antiAliasWithSaveLayer,
+ semanticContainer: true,
+ child: FadeInImage(
+ height: 160.0,
+ placeholder: const AssetImage('assets/loading.gif'),
+ image: NetworkImage(
+ 'https://image.tmdb.org/t/p/w500/${popular.posterPath!}',
+ ),
+ ),
+ ),
+ ),
+ const SizedBox(width: 16.0),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Sinopsis',
+ style: Theme.of(context).typography.englishLike.titleLarge,
+ ),
+ const SizedBox(height: 10),
+ Text(popular.overview ?? ""),
+ ],
+ ),
+ ),
+ // Expanded(child: Text(popular.overview ?? "")),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class Rating extends StatelessWidget {
+ final double? voteAverage;
+ const Rating(this.voteAverage, {super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Rating',
+ style: Theme.of(context).typography.englishLike.headlineLarge,
+ ),
+ const SizedBox(height: 16),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ RatingBar.builder(
+ initialRating: (voteAverage ?? 0.0) / 2,
+ minRating: 0.0,
+ direction: Axis.horizontal,
+ allowHalfRating: true,
+ itemCount: 5,
+ itemPadding: const EdgeInsets.symmetric(horizontal: 4.0),
+ itemBuilder: (context, _) => Icon(
+ Icons.star,
+ color: Theme.of(context).colorScheme.primary,
+ ),
+ ignoreGestures: true,
+ onRatingUpdate: (rating) {},
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class Trailers extends StatefulWidget {
+ final List<PopularVideo> videos;
+ const Trailers(this.videos, {super.key});
+
+ @override
+ State<Trailers> createState() => _TrailersState();
+}
+
+class _TrailersState extends State<Trailers> {
+ List<PopularVideo> get filteredVideos => widget.videos
+ .where((v) =>
+ v.site == 'YouTube' && v.official == true && v.type == 'Trailer')
+ .toList();
+
+ final _controller = YoutubePlayerController(
+ params: const YoutubePlayerParams(
+ mute: false,
+ showControls: true,
+ showFullscreenButton: false,
+ ),
+ );
+
+ bool isLoaded = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
+ child: Text(
+ 'Trailers',
+ style: Theme.of(context).typography.englishLike.headlineLarge,
+ ),
+ ),
+ isLoaded
+ ? Padding(
+ padding: const EdgeInsets.only(top: 16),
+ child: YoutubePlayer(
+ controller: _controller,
+ aspectRatio: 16 / 9,
+ ),
+ )
+ : const SizedBox.shrink(),
+ ListView.builder(
+ padding: const EdgeInsets.all(16),
+ physics: const NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ itemCount: filteredVideos.length,
+ itemBuilder: (context, index) {
+ PopularVideo video = widget.videos[index];
+ return Card(
+ clipBehavior: Clip.antiAliasWithSaveLayer,
+ semanticContainer: true,
+ child: InkWell(
+ onTap: () {
+ _controller.loadVideoById(videoId: video.key!);
+ setState(() {
+ isLoaded = true;
+ });
+ },
+ child: Row(
+ children: [
+ Image.network(
+ YoutubeThumbnail(youtubeId: video.key!).standard(),
+ height: 100.0,
+ errorBuilder: (context, error, stackTrace) => Container(
+ color: Theme.of(context).colorScheme.primary,
+ height: 100.0,
+ width: (4 * 100) / 3,
+ child: const Icon(Icons.movie),
+ ),
+ ),
+ const SizedBox(width: 16.0),
+ Expanded(
+ child: Text(
+ video.name ?? "",
+ style: Theme.of(context)
+ .typography
+ .englishLike
+ .titleMedium,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ )
+ ],
+ ),
+ );
+ }
+}
+
+class Casting extends StatelessWidget {
+ final List<PopularCredit> credits;
+ const Casting(this.credits, {super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Card(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
+ child: Text(
+ 'Reparto',
+ style: Theme.of(context).typography.englishLike.headlineLarge,
+ ),
+ ),
+ SizedBox(
+ height: 350.0,
+ child: InfiniteCarousel.builder(
+ axisDirection: Axis.horizontal,
+ velocityFactor: 0.5,
+ itemCount: credits.length,
+ itemExtent: 160,
+ itemBuilder: (context, itemIndex, realIndex) {
+ PopularCredit credit = credits[itemIndex];
+ return Card(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ CircleAvatar(
+ radius: 50.0,
+ backgroundImage: credit.profilePath != null
+ ? NetworkImage(
+ 'https://image.tmdb.org/t/p/w500/${credit.profilePath!}',
+ )
+ : null,
+ child: credit.profilePath == null
+ ? const Icon(Icons.person)
+ : null,
+ ),
+ const SizedBox(height: 16.0),
+ Text(
+ credit.name ?? "",
+ style: Theme.of(context)
+ .typography
+ .englishLike
+ .titleMedium,
+ ),
+ Text('como «${credit.character ?? ""}»'),
+ ],
+ ),
+ ),
+ ),
+ );
+ },
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/screens/popular_screen.dart b/lib/screens/popular_screen.dart
index 07ca70e..b961ce9 100644
--- a/lib/screens/popular_screen.dart
+++ b/lib/screens/popular_screen.dart
@@ -1,8 +1,10 @@
import 'package:flutter/material.dart';
+import 'package:pmsna1/database/helper.dart';
import 'package:pmsna1/models/popular.dart';
import 'package:pmsna1/network/popular_api.dart';
import 'package:pmsna1/widgets/loading_modal_widget.dart';
-import 'package:pmsna1/widgets/popular_item.dart';
+
+import '../widgets/popular_list.dart';
class PopularScreen extends StatefulWidget {
const PopularScreen({super.key});
@@ -13,31 +15,49 @@ class PopularScreen extends StatefulWidget {
class _PopularScreenState extends State<PopularScreen> {
PopularApi? popularApi;
+ late DatabaseHelper _db;
@override
void initState() {
super.initState();
popularApi = PopularApi();
+ _db = DatabaseHelper();
}
@override
Widget build(BuildContext context) {
return Scaffold(
- appBar: AppBar(title: const Text('Películas populares')),
+ appBar: AppBar(
+ title: const Text('Películas populares'),
+ actions: [
+ IconButton(
+ icon: const Icon(Icons.favorite_outline),
+ onPressed: () {
+ Navigator.of(context).pushNamed('/favorites');
+ },
+ ),
+ ],
+ ),
body: FutureBuilder(
future: popularApi!.getAllPopular(),
builder: (context, AsyncSnapshot<List<Popular>?> snapshot) {
if (snapshot.hasData) {
- return GridView.builder(
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
- crossAxisCount: 2,
- childAspectRatio: .9,
- mainAxisSpacing: 10,
- crossAxisSpacing: 10,
- ),
- itemCount: snapshot.data != null ? snapshot.data!.length : 0,
- itemBuilder: (context, index) {
- return PopularItem(snapshot.data![index]);
+ return PopularList(
+ snapshot.data!,
+ onFavorited: (popular, favorited) {
+ if (favorited) {
+ _db.favoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ } else {
+ _db.unfavoritePopular(popular).whenComplete(() {
+ setState(() {});
+ });
+ }
+ },
+ onPressed: (popular) {
+ Navigator.of(context)
+ .pushNamed('/popular_detail', arguments: popular);
},
);
} else if (snapshot.hasError) {
diff --git a/lib/screens/register_screen.dart b/lib/screens/register_screen.dart
index 16875f2..ec9eb25 100644
--- a/lib/screens/register_screen.dart
+++ b/lib/screens/register_screen.dart
@@ -165,7 +165,7 @@ class _RegisterScreenState extends State<RegisterScreen> {
)
.then((success) {
if (success) {
- Navigator.of(context).pushNamed('/dash');
+ Navigator.of(context).pushNamed('/onboard');
}
});
}
diff --git a/lib/widgets/popular_item.dart b/lib/widgets/popular_item.dart
index 7e8cc2c..3ef32cd 100644
--- a/lib/widgets/popular_item.dart
+++ b/lib/widgets/popular_item.dart
@@ -3,15 +3,45 @@ import 'package:pmsna1/models/popular.dart';
class PopularItem extends StatelessWidget {
final Popular popular;
+ final void Function(bool favorited) onFavorited;
+ final void Function() onPressed;
- const PopularItem(this.popular, {super.key});
+ const PopularItem(
+ this.popular, {
+ super.key,
+ required this.onFavorited,
+ required this.onPressed,
+ });
@override
Widget build(BuildContext context) {
- return FadeInImage(
- placeholder: const AssetImage('assets/loading.gif'),
- image: NetworkImage(
- 'https://image.tmdb.org/t/p/w500/${popular.posterPath!}',
+ return Card(
+ semanticContainer: true,
+ clipBehavior: Clip.antiAliasWithSaveLayer,
+ child: InkWell(
+ onTap: onPressed,
+ child: Stack(
+ children: [
+ Hero(
+ tag: popular.posterPath!,
+ child: FadeInImage(
+ placeholder: const AssetImage('assets/loading.gif'),
+ image: NetworkImage(
+ 'https://image.tmdb.org/t/p/w500/${popular.posterPath!}',
+ ),
+ ),
+ ),
+ popular.hasFavorite
+ ? IconButton(
+ icon: const Icon(Icons.favorite),
+ onPressed: () => onFavorited(!popular.hasFavorite),
+ )
+ : IconButton(
+ icon: const Icon(Icons.favorite_outline),
+ onPressed: () => onFavorited(!popular.hasFavorite),
+ ),
+ ],
+ ),
),
);
}
diff --git a/lib/widgets/popular_list.dart b/lib/widgets/popular_list.dart
new file mode 100644
index 0000000..2422a38
--- /dev/null
+++ b/lib/widgets/popular_list.dart
@@ -0,0 +1,38 @@
+import 'package:flutter/material.dart';
+
+import '../models/popular.dart';
+import 'popular_item.dart';
+
+class PopularList extends StatelessWidget {
+ final List<Popular> popularList;
+ final void Function(Popular popular, bool favorited) onFavorited;
+ final void Function(Popular popular) onPressed;
+
+ const PopularList(
+ this.popularList, {
+ super.key,
+ required this.onFavorited,
+ required this.onPressed,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return GridView.builder(
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 2,
+ childAspectRatio: 2 / 3,
+ mainAxisSpacing: 10,
+ crossAxisSpacing: 10,
+ ),
+ itemCount: popularList.length,
+ itemBuilder: (context, index) {
+ return PopularItem(
+ popularList[index],
+ onFavorited: (favorited) =>
+ onFavorited(popularList[index], favorited),
+ onPressed: () => onPressed(popularList[index]),
+ );
+ },
+ );
+ }
+}
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index e71a16d..f6f23bf 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
+#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
+ g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
+ fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
+ url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index 2e1de87..f16b4c3 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 9d1472f..d201a30 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -11,6 +11,7 @@ import firebase_core
import path_provider_foundation
import shared_preferences_foundation
import sqflite
+import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin"))
@@ -19,4 +20,5 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
diff --git a/pubspec.lock b/pubspec.lock
index a5e6d10..8115999 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: _flutterfire_internals
- sha256: "6a0ad72b2bcdb461749e40c01c478212a78db848dfcb2f10f2a461988bc5fb29"
+ sha256: "9ebe81588e666f7e2b21309f2b5653bd9642d7f27fd0a6894278d2ff40cb9481"
url: "https://pub.dev"
source: hosted
- version: "1.1.1"
+ version: "1.3.2"
archive:
dependency: transitive
description:
@@ -29,10 +29,10 @@ packages:
dependency: transitive
description:
name: async
- sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0
+ sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
- version: "2.10.0"
+ version: "2.11.0"
boolean_selector:
dependency: transitive
description:
@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: characters
- sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
- version: "1.2.1"
+ version: "1.3.0"
circular_menu:
dependency: "direct main"
description:
@@ -93,10 +93,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0
+ sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
url: "https://pub.dev"
source: hosted
- version: "1.17.0"
+ version: "1.17.1"
concentric_transition:
dependency: "direct main"
description:
@@ -181,42 +181,42 @@ packages:
dependency: transitive
description:
name: firebase_auth_platform_interface
- sha256: "1217d8aa313b49d58b489aa8879544563abc8793d9612ff20d8df193f202aedc"
+ sha256: e46e136a6f6eec88b30f12445ff7f5b19b23b7ede694921ced4f8eba8eb634f6
url: "https://pub.dev"
source: hosted
- version: "6.12.0"
+ version: "6.15.2"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
- sha256: bf7f1a87995a58b0f07dc617806dabd7ff25c64be7fa47b41ab1bb9a485b0062
+ sha256: "553bd576d793d05b920971a2c7ab02bd049d4971153702074ea2555877efd392"
url: "https://pub.dev"
source: hosted
- version: "5.2.10"
+ version: "5.5.2"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
- sha256: "239e4ac688674a7e7b5476fd16b0d8e2b5a453d464f32091af3ce1df4ebb7316"
+ sha256: e9b36b391690cf329c6fb1de220045e97c13784c303820cd33962319580a56c6
url: "https://pub.dev"
source: hosted
- version: "2.10.0"
+ version: "2.13.1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
- sha256: "0df0a064ab0cad7f8836291ca6f3272edd7b83ad5b3540478ee46a0849d8022b"
+ sha256: b63e3be6c96ef5c33bdec1aab23c91eb00696f6452f0519401d640938c94cba2
url: "https://pub.dev"
source: hosted
- version: "4.6.0"
+ version: "4.8.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
- sha256: "347351a8f0518f3343d79a9a0690fa67ad232fc32e2ea270677791949eac792b"
+ sha256: "8c0f4c87d20e2d001a5915df238c1f9c88704231f591324205f5a5d2a7740a45"
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.5.0"
flutter:
dependency: "direct main"
description: flutter
@@ -238,6 +238,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.8"
+ flutter_rating_bar:
+ dependency: "direct main"
+ description:
+ name: flutter_rating_bar
+ sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.1"
flutter_staggered_grid_view:
dependency: "direct main"
description:
@@ -352,22 +360,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.6.3"
+ infinite_carousel:
+ dependency: "direct main"
+ description:
+ name: infinite_carousel
+ sha256: fe04c3b08adad2ee00c9bf40b46e0ff7944d206081392c4ae0f6b82c89c6e70d
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.3"
intl:
dependency: transitive
description:
name: intl
- sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.17.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
name: js
- sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7"
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
- version: "0.6.5"
+ version: "0.6.7"
lints:
dependency: transitive
description:
@@ -388,10 +404,10 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72"
+ sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
url: "https://pub.dev"
source: hosted
- version: "0.12.13"
+ version: "0.12.15"
material_color_utilities:
dependency: transitive
description:
@@ -404,10 +420,10 @@ packages:
dependency: transitive
description:
name: meta
- sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42"
+ sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.9.1"
nested:
dependency: transitive
description:
@@ -420,10 +436,10 @@ packages:
dependency: transitive
description:
name: path
- sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b
+ sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
- version: "1.8.2"
+ version: "1.8.3"
path_parsing:
dependency: transitive
description:
@@ -689,10 +705,10 @@ packages:
dependency: "direct main"
description:
name: table_calendar
- sha256: "526854609e1a3df31a841f4dd307b9be7a6a21c945b88a8867dcb66fe5d84d70"
+ sha256: "1e3521a3e6d3fc7f645a58b135ab663d458ab12504f1ea7f9b4b81d47086c478"
url: "https://pub.dev"
source: hosted
- version: "3.0.0"
+ version: "3.0.9"
term_glyph:
dependency: transitive
description:
@@ -705,10 +721,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206
+ sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
url: "https://pub.dev"
source: hosted
- version: "0.4.16"
+ version: "0.5.1"
typed_data:
dependency: transitive
description:
@@ -717,6 +733,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.11"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: eed4e6a1164aa9794409325c3b707ff424d4d1c2a785e7db67f8bbda00e36e51
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.35"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.4"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.5"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.5"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: "6c9ca697a5ae218ce56cece69d46128169a58aa8653c1b01d26fcd4aad8c4370"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.17"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.6"
vector_graphics:
dependency: transitive
description:
@@ -749,6 +829,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
+ webview_flutter:
+ dependency: transitive
+ description:
+ name: webview_flutter
+ sha256: "5604dac1178680a34fbe4a08c7b69ec42cca6601dc300009ec9ff69bef284cc2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.1"
+ webview_flutter_android:
+ dependency: transitive
+ description:
+ name: webview_flutter_android
+ sha256: "57a22c86065375c1598b57224f92d6008141be0c877c64100de8bfb6f71083d8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.7.1"
+ webview_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: webview_flutter_platform_interface
+ sha256: "656e2aeaef318900fffd21468b6ddc7958c7092a642f0e7220bac328b70d4a81"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.1"
+ webview_flutter_wkwebview:
+ dependency: transitive
+ description:
+ name: webview_flutter_wkwebview
+ sha256: "6bbc6ade302b842999b27cbaa7171241c273deea8a9c73f92ceb3d811c767de2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.4.4"
win32:
dependency: transitive
description:
@@ -773,6 +885,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.2.2"
+ youtube:
+ dependency: "direct main"
+ description:
+ name: youtube
+ sha256: "3d82e77fe8918a891c3aaba68adc14d5f4bbc6c2e368cfa100a9d620f238f9b0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ youtube_player_iframe:
+ dependency: "direct main"
+ description:
+ name: youtube_player_iframe
+ sha256: d7aec9083430db4e5da83a3b5d7b7fcbb93cfa027d9f680ce3c7e7cd20724305
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.4"
+ youtube_player_iframe_web:
+ dependency: transitive
+ description:
+ name: youtube_player_iframe_web
+ sha256: c7020816031600349b56d2729d4e8be011fcb723ff7dc2dd0cdf72096a0e5ff4
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.2"
sdks:
- dart: ">=2.19.1 <3.0.0"
+ dart: ">=3.0.2 <4.0.0"
flutter: ">=3.7.0-0"
diff --git a/pubspec.yaml b/pubspec.yaml
index e19aaa7..cf88624 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -23,11 +23,16 @@ dependencies:
http: ^0.13.5
firebase_core: ^2.8.0
firebase_auth: ^4.3.0
- table_calendar: <=3.0.9
+ table_calendar: ^3.0.9
flutter_staggered_grid_view: ^0.6.2
cloud_firestore: ^4.5.2
google_maps_flutter: ^2.2.6
circular_menu: ^2.0.1
+ url_launcher: ^6.1.11
+ youtube: ^1.0.1
+ youtube_player_iframe: ^4.0.4
+ infinite_carousel: ^1.0.3
+ flutter_rating_bar: ^4.0.1
dev_dependencies:
flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 8b6d468..ec8e8d4 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -6,6 +6,12 @@
#include "generated_plugin_registrant.h"
+#include <firebase_core/firebase_core_plugin_c_api.h>
+#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
+ FirebaseCorePluginCApiRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index b93c4c3..02d26c3 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -3,6 +3,8 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
+ firebase_core
+ url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST