Movie Search
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:multimedia/data/movies.dart';
|
||||
import 'package:multimedia/log_printer.dart';
|
||||
import 'package:multimedia/widgets/movies/add/movie_search_list.dart';
|
||||
|
||||
import 'package:tmdb_api/tmdb_api.dart' as TMDB;
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AddMovieScreen extends StatefulWidget {
|
||||
AddMovieScreen({
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AddMovieScreen> createState() => _AddMovieScreenState();
|
||||
}
|
||||
|
||||
class _AddMovieScreenState extends State<AddMovieScreen> {
|
||||
Logger logger = getLogger();
|
||||
|
||||
String movieTitleSearch = '';
|
||||
|
||||
String yearSearch = '';
|
||||
|
||||
List<Movie> movieList = [];
|
||||
|
||||
late MovieSearchList movieSearchList;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
movieSearchList = MovieSearchList(movieList: movieList);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('Search Movie'),
|
||||
actions: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Movie Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
movieTitleSearch = text;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
SizedBox(
|
||||
width: 50,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Year',
|
||||
),
|
||||
onChanged: (text) {
|
||||
yearSearch = text;
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
startSearch();
|
||||
},
|
||||
child: const Text('Search'),
|
||||
),
|
||||
],
|
||||
),
|
||||
const VerticalDivider(
|
||||
width: 10,
|
||||
thickness: 3,
|
||||
indent: 0,
|
||||
endIndent: 0,
|
||||
color: Colors.grey,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.check_circle_outline),
|
||||
tooltip: 'Save changes',
|
||||
onPressed: () {
|
||||
// if (save()) {
|
||||
// Navigator.pop(context, movieDetails);
|
||||
// }
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.highlight_off),
|
||||
tooltip: 'Revert changes',
|
||||
onPressed: () {
|
||||
// Navigator.pop(context, null);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: MovieSearchList(
|
||||
movieList: movieList,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String parseString(dynamic data, String field) {
|
||||
if (data[field].toString() == Null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return data[field].toString();
|
||||
}
|
||||
|
||||
DateTime parseDate(dynamic data, String field) {
|
||||
if (data[field].toString() == Null) {
|
||||
return DateTime(1900, 1, 1);
|
||||
}
|
||||
return DateTime.parse(data[field].toString());
|
||||
}
|
||||
|
||||
double parseDouble(dynamic data, String field) {
|
||||
if (data[field] == Null) {
|
||||
return 0.0;
|
||||
}
|
||||
return data[field];
|
||||
}
|
||||
|
||||
int parseInt(dynamic data, String field) {
|
||||
if (data[field] == Null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return data[field];
|
||||
}
|
||||
|
||||
Future<void> startSearch() async {
|
||||
if (movieTitleSearch.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
int year = int.tryParse(yearSearch) ?? 0;
|
||||
|
||||
logger.i('Wir suchen ...');
|
||||
final tmdb = TMDB.TMDB(TMDB.ApiKeys(
|
||||
'a33271b9e54cdcb9a80680eaf5522f1b', 'apiReadAccessTokenv4'));
|
||||
|
||||
final response = await tmdb.v3.search.queryMovies(
|
||||
movieTitleSearch,
|
||||
year: year,
|
||||
language: 'de',
|
||||
);
|
||||
// logger.i(response);
|
||||
// logger.i(response['page']);
|
||||
// logger.i(response['results']);
|
||||
List<dynamic> movies = response['results'];
|
||||
|
||||
setState(
|
||||
() {
|
||||
movieList.clear();
|
||||
|
||||
for (int i = 0; i < movies.length; i++) {
|
||||
dynamic movie = movies[i];
|
||||
|
||||
String movieTitle = parseString(movie, 'title');
|
||||
String originalTitle = parseString(movie, 'original_title');
|
||||
String overview = parseString(movie, 'overview');
|
||||
DateTime releaseDate = parseDate(movie, 'release_date');
|
||||
String backdropPath = parseString(movie, 'backdrop_path');
|
||||
double voteAverage = parseDouble(movie, 'vote_average');
|
||||
int voteCount = parseInt(movie, 'vote_count');
|
||||
|
||||
logger.i(backdropPath);
|
||||
movieList.add(Movie(
|
||||
movieID: -1,
|
||||
movieTitle: movieTitle,
|
||||
originalTitle: originalTitle,
|
||||
overview: overview,
|
||||
releaseDate: releaseDate,
|
||||
state: 0,
|
||||
resolution: '',
|
||||
backdropPath: backdropPath,
|
||||
languages: '',
|
||||
productionCountries: '',
|
||||
productionCompanies: '',
|
||||
voteAverage: voteAverage,
|
||||
voteCount: voteCount,
|
||||
cast: '',
|
||||
crew: '',
|
||||
genre: '',
|
||||
localPath: '',
|
||||
));
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:multimedia/data/movies.dart';
|
||||
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:multimedia/log_printer.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class MovieSearchList extends StatefulWidget {
|
||||
MovieSearchList({
|
||||
super.key,
|
||||
required List<Movie> this.movieList,
|
||||
});
|
||||
|
||||
List<Movie> movieList = [];
|
||||
|
||||
@override
|
||||
State<MovieSearchList> createState() => _MovieSearchListState();
|
||||
}
|
||||
|
||||
class _MovieSearchListState extends State<MovieSearchList> {
|
||||
Logger logger = getLogger();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: widget.movieList
|
||||
.map(
|
||||
(movie) => Column(children: [
|
||||
Row(
|
||||
children: [
|
||||
movie.backdropPath == 'null'
|
||||
? const SizedBox(width: 200)
|
||||
: Image.network(
|
||||
'https://image.tmdb.org/t/p/w200${movie.backdropPath}'),
|
||||
Expanded(
|
||||
child: CheckboxListTile(
|
||||
title: Text(
|
||||
'${movie.movieTitle} (${movie.releaseDate.year})'),
|
||||
subtitle: Text(movie.overview),
|
||||
value: movie.state == 1,
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
if (movie.state == 1) {
|
||||
movie.state = 0;
|
||||
} else {
|
||||
movie.state = 1;
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(height: 0),
|
||||
]),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:multimedia/widgets/movies/add/add_screen.dart';
|
||||
import 'package:multimedia/widgets/movies/details/details_screen.dart';
|
||||
import 'package:multimedia/widgets/movies/filter_box.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@@ -284,14 +285,6 @@ class _MoviesScreenState extends State<MoviesScreen> {
|
||||
// }
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.search_outlined),
|
||||
tooltip: 'Search for movie',
|
||||
onPressed: () {
|
||||
searchMovie();
|
||||
// Navigator.pop(context, null);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.update_outlined),
|
||||
tooltip: 'Update movie',
|
||||
@@ -349,7 +342,11 @@ class _MoviesScreenState extends State<MoviesScreen> {
|
||||
}
|
||||
|
||||
void addMovie() {
|
||||
logger.i('add movie');
|
||||
final m = Navigator.push(
|
||||
context, MaterialPageRoute(builder: (ctx) => AddMovieScreen()));
|
||||
|
||||
if (m != null) {
|
||||
} else {}
|
||||
}
|
||||
|
||||
void searchMovie() {
|
||||
|
||||
+42
-10
@@ -41,6 +41,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.18.0"
|
||||
colorize:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: colorize
|
||||
sha256: "584746cd6ba1cba0633b6720f494fe6f9601c4170f0666c1579d2aa2a61071ba"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -57,6 +65,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
dio:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio
|
||||
sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.7.0"
|
||||
dio_web_adapter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_web_adapter
|
||||
sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -132,10 +156,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
||||
sha256: "99f282cb0e02edcbbf8c6b3bbc7c90b65635156c412e58f3975a7e55284ce685"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.19.0"
|
||||
version: "0.20.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -172,10 +196,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: logger
|
||||
sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32"
|
||||
sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.5.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -369,18 +393,18 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: "31d2ddf410ee41abb3ecf85b7b6e8e1563307ad52ee784ddd91337e30280f715"
|
||||
sha256: "225b1cc135549bb4eef096d63b7323c30ee61c4b095c7e8a14bf9333e243d84b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.1.58"
|
||||
version: "27.2.2"
|
||||
syncfusion_flutter_datagrid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_datagrid
|
||||
sha256: e7ddbb1bbadbb671e5fd636cadcde2ae06d9eec294c24937859f3c77ed1d1cbe
|
||||
sha256: "6db8e5828dcc65f603a948cc28beb07c506654a4cf22a490924eb568c944d344"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.1.58"
|
||||
version: "27.2.2"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -397,6 +421,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
tmdb_api:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: tmdb_api
|
||||
sha256: d0db63d044dcc104731610b68f496d7a672dde70b5261f6272c8dfba2d4489d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
transparent_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -433,10 +465,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
|
||||
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "0.5.1"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
+2
-1
@@ -37,12 +37,13 @@ dependencies:
|
||||
cupertino_icons: ^1.0.2
|
||||
http: ^1.2.0
|
||||
syncfusion_flutter_datagrid: ^27.1.58
|
||||
intl: ^0.19.0
|
||||
intl: ^0.20.0
|
||||
syncfusion_flutter_core: ^27.1.58
|
||||
google_fonts: ^6.2.1
|
||||
shared_preferences: ^2.3.3
|
||||
transparent_image: ^2.0.1
|
||||
logger: ^2.4.0
|
||||
tmdb_api: ^2.2.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user