From 2db1954585e641707b3ce72acec0f978981a04ec Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Tue, 15 Apr 2025 16:49:08 +0200 Subject: [PATCH] save new movie --- lib/data/movies.dart | 217 +++++++++++++++++++++---- lib/widgets/movies/add/add_screen.dart | 20 ++- lib/widgets/movies/list_screen.dart | 147 ++++++++++------- 3 files changed, 285 insertions(+), 99 deletions(-) diff --git a/lib/data/movies.dart b/lib/data/movies.dart index ef5593c..e837b52 100644 --- a/lib/data/movies.dart +++ b/lib/data/movies.dart @@ -1,6 +1,44 @@ import 'package:logger/logger.dart'; import 'package:multimedia/log_printer.dart'; +int getInt(Map json, String key) { + if (json.containsKey(key)) { + return json[key] + 0; + } + return 0; +} + +bool getBool(Map json, String key) { + if (json.containsKey(key)) { + return json[key]; + } + return false; +} + +double getDouble(Map json, String key) { + if (json.containsKey(key)) { + return json[key] + 0.0; + } + return 0.0; +} + +String getString(Map json, String key) { + if (json.containsKey(key)) { + if (json[key] == null) { + return ''; + } + return json[key]; + } + return ''; +} + +DateTime getDateTime(Map json, String key) { + if (json.containsKey(key)) { + return DateTime.parse(json[key].toString()); + } + return DateTime(1900); +} + class Movie { int movieID; String movieTitle; @@ -130,42 +168,153 @@ class Movie { } factory Movie.fromJsonDynamic(Map json) { - // dynamic languages = json['languages']; - // dynamic productionCountries = json['productionCountries']; - // dynamic productionCompanies = json['productionCompanies']; - // dynamic cast = json['cast']; - // dynamic crew = json['crew']; - // dynamic genre = json['genre']; + int movieID = getInt(json, 'id'); + String movieTitle = getString(json, 'title'); + String originalTitle = getString(json, 'original_title'); + String overview = getString(json, 'overview'); + DateTime releaseDate = getDateTime(json, 'release_date'); + int state = 1; + String resolution = ''; + String backdropPath = getString(json, 'backdrop_path'); + String posterPath = getString(json, 'poster_path'); + double voteAverage = getDouble(json, 'vote_average'); + int voteCount = getInt(json, 'vote_count'); + String localPath = ''; + dynamic externalIDs = json['external_ids']; + String imdbID = getString(externalIDs, 'imdb_id'); + double popularity = getDouble(json, 'popularity'); + String originalLanguage = getString(json, 'original_language'); + int adult = getBool(json, 'adult') == true ? 1 : 0; + double budget = getDouble(json, 'budget'); + String homepage = getString(json, 'homepage'); + double revenue = getDouble(json, 'revenue'); + int runtime = getInt(json, 'runtime'); + String tagline = getString(json, 'tagline'); + + dynamic languages = json['spoken_languages']; + dynamic productionCountries = json['production_countries']; + dynamic productionCompanies = json['production_companies']; + dynamic credits = json['credits']; + dynamic genres = json['genres']; + dynamic casts = credits['cast']; + dynamic crews = credits['crew']; + String belongsToCollection = ''; + + String languageList = ''; + String castList = ''; + String crewList = ''; + String genreList = ''; + String productionCompaniesList = ''; + String productionCountriesList = ''; + bool first; + + if (json.containsKey('belongsToCollection')) { + belongsToCollection = json['belongsToCollection']; + } + + first = true; + for (var i = 0; i < languages.length; i++) { + dynamic language = languages[i]; + String languageName = language['name']; + if (first) { + first = false; + } else { + languageList = languageList + ','; + } + languageList = languageName; + } + + first = true; + for (var i = 0; i < casts.length; i++) { + dynamic cast = casts[i]; + String castName = cast['name']; + String castChar = cast['character']; + if (first) { + first = false; + } else { + castList = castList + '|'; + } + castList = castList + castName + ',' + castChar; + } + + first = true; + for (var i = 0; i < crews.length; i++) { + dynamic crew = crews[i]; + String crewName = crew['name']; + String crewDepartment = crew['department']; + if (first) { + first = false; + } else { + crewList = crewList + '|'; + } + crewList = crewList + crewName + ',' + crewDepartment; + } + + first = true; + for (var i = 0; i < productionCountries.length; i++) { + dynamic productionCountry = productionCountries[i]; + String name = productionCountry['name']; + if (first) { + first = false; + } else { + productionCountriesList = productionCountriesList + ','; + } + productionCountriesList = productionCountriesList + name; + } + + first = true; + for (var i = 0; i < productionCompanies.length; i++) { + dynamic productionCompany = productionCompanies[i]; + String name = productionCompany['name']; + if (first) { + first = false; + } else { + productionCountriesList = productionCompaniesList + ','; + } + productionCompaniesList = productionCompaniesList + name; + } + + first = true; + for (var i = 0; i < genres.length; i++) { + dynamic genre = genres[i]; + String genreName = genre['name']; + if (first) { + first = false; + } else { + genreList = genreList + ','; + } + genreList = genreList + genreName; + } return Movie( - movieID: json['id'], - movieTitle: json['title'], - originalTitle: json['original_title'], - overview: json['overview'], - releaseDate: DateTime.parse(json['release_date'].toString()), - state: int.tryParse(['status'].toString()) ?? 0, - resolution: '', - backdropPath: json['backdrop_path'], - posterPath: '', - languages: '', - productionCountries: '', - productionCompanies: '', - voteAverage: double.tryParse(['vote_average'].toString()) ?? 0, - voteCount: int.tryParse(['vote_count'].toString()) ?? 0, - cast: '', - crew: '', - genre: '', - localPath: '', - imdbID: '', - originalLanguage: '', - popularity: 0, - adult: false, - belongsToCollection: '', - budget: 0, - homepage: '', - revenue: 0, - runtime: 0, - tagline: '', + movieID: movieID, + movieTitle: movieTitle, + originalTitle: originalTitle, + overview: overview, + releaseDate: releaseDate, + state: state, + resolution: resolution, + backdropPath: backdropPath, + posterPath: posterPath, + languages: languageList, + productionCountries: productionCountriesList, + productionCompanies: productionCompaniesList, + voteAverage: voteAverage, + voteCount: voteCount, + cast: castList, + crew: crewList, + genre: genreList, + localPath: localPath, + imdbID: imdbID, + originalLanguage: originalLanguage, + popularity: popularity, + adult: adult == 1, + belongsToCollection: belongsToCollection, + budget: budget, + homepage: homepage, + revenue: revenue, + runtime: runtime, + tagline: tagline, ); } } diff --git a/lib/widgets/movies/add/add_screen.dart b/lib/widgets/movies/add/add_screen.dart index b29862d..c897110 100644 --- a/lib/widgets/movies/add/add_screen.dart +++ b/lib/widgets/movies/add/add_screen.dart @@ -16,7 +16,12 @@ import 'package:tmdb_api/tmdb_api.dart' as TMDB; // ignore: must_be_immutable class AddMovieScreen extends StatefulWidget { - AddMovieScreen({ + final Function(Movie) addMovieToList; + final Function() addMovieFinished; + + AddMovieScreen( + this.addMovieToList, + this.addMovieFinished, { super.key, }); @@ -35,6 +40,8 @@ class _AddMovieScreenState extends State { List movieList = []; late MovieSearchList movieSearchList; + late Function(Movie) addMovieToList; + late Function() addMovieFinished; static const headerStyle = TextStyle( color: Color(0xffffffff), fontSize: 18, fontWeight: FontWeight.bold); @@ -42,6 +49,8 @@ class _AddMovieScreenState extends State { @override Widget build(BuildContext context) { + addMovieToList = widget.addMovieToList; + addMovieFinished = widget.addMovieFinished; movieSearchList = MovieSearchList(movieList: movieList); return Scaffold( @@ -376,15 +385,15 @@ class _AddMovieScreenState extends State { if (movie.state == 1) { somethingFound = true; addMovie(movieList[i].movieID); + addMovieToList(movie); } } + addMovieFinished(); return somethingFound; } Future addMovie(int movieID) async { - logger.i('addMovie'); - String lang = 'de'; if (!searchGerman || searchEnglish) { @@ -400,10 +409,8 @@ class _AddMovieScreenState extends State { appendToResponse: 'credits,external_ids', ); -// logger.i(response); Movie movie = Movie.fromJsonDynamic(response); writeToDB(movie); -// logger.i('${movie.movieTitle} (${movie.movieID})'); return true; } @@ -435,8 +442,7 @@ class _AddMovieScreenState extends State { 'movieTitle': movie.movieTitle, 'originalTitle': movie.originalTitle, 'overview': movie.overview, - 'releaseDate': - DateFormat('yyyy-MM-dd').format(movie.releaseDate), + 'releaseDate': DateFormat('yyyy-MM-dd').format(movie.releaseDate), 'resolution': movie.resolution, 'state': movie.state.toString(), 'backdropPath': movie.backdropPath, diff --git a/lib/widgets/movies/list_screen.dart b/lib/widgets/movies/list_screen.dart index c7fe83c..b34d188 100644 --- a/lib/widgets/movies/list_screen.dart +++ b/lib/widgets/movies/list_screen.dart @@ -1,11 +1,11 @@ import 'dart:convert'; +import 'package:flutter/material.dart'; 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'; import 'package:intl/intl.dart'; -import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; @@ -195,19 +195,6 @@ class _MoviesScreenState extends State { movieDataSource.updateDataGridSource( rowColumnIndex: RowColumnIndex(realIndex, i)); } - - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 0)); - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 1)); - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 2)); - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 3)); - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 4)); - // movieDataSource.updateDataGridSource( - // rowColumnIndex: RowColumnIndex(realIndex, 5)); } else {} filter(); } @@ -261,6 +248,7 @@ class _MoviesScreenState extends State { )); } + late SfDataGrid dataGrid; @override Widget build(BuildContext context) { return Scaffold( @@ -279,9 +267,6 @@ class _MoviesScreenState extends State { tooltip: 'Add Movie', onPressed: () { addMovie(); - // if (save()) { - // Navigator.pop(context, movieDetails); - // } }, ), IconButton( @@ -300,46 +285,48 @@ class _MoviesScreenState extends State { child: FutureBuilder( future: generateMovieList(), builder: (context, data) { - return data.hasData - ? SfDataGridTheme( - data: const SfDataGridThemeData( - headerColor: Color(0xff009889), - ), - child: SfDataGrid( - source: movieDataSource, - selectionMode: SelectionMode.single, - navigationMode: GridNavigationMode.row, - columns: _columns, - controller: _dataGridController, - columnWidthMode: ColumnWidthMode.auto, - columnWidthCalculationRange: - ColumnWidthCalculationRange.allRows, - onCellTap: (DataGridCellTapDetails details) { - int index = details.rowColumnIndex.rowIndex - 1; - if (index < 0) { - return; - } - showMovieDetails(index); - }, - onCellDoubleTap: - (DataGridCellDoubleTapDetails details) { - print(details.rowColumnIndex); - }, - onCellLongPress: - (DataGridCellLongPressDetails details) { - print(details.rowColumnIndex); - }, - onCellSecondaryTap: (DataGridCellTapDetails details) { - print(details.rowColumnIndex); - }, - ), - ) - : const Center( - child: CircularProgressIndicator( - strokeWidth: 2, - value: 0.8, - ), - ); + if (data.hasData) { + dataGrid = SfDataGrid( + source: movieDataSource, + selectionMode: SelectionMode.single, + navigationMode: GridNavigationMode.row, + columns: _columns, + controller: _dataGridController, + columnWidthMode: ColumnWidthMode.auto, + columnWidthCalculationRange: + ColumnWidthCalculationRange.allRows, + onCellTap: (DataGridCellTapDetails details) { + int index = details.rowColumnIndex.rowIndex - 1; + if (index < 0) { + return; + } + showMovieDetails(index); + }, + onCellDoubleTap: (DataGridCellDoubleTapDetails details) { + print(details.rowColumnIndex); + }, + onCellLongPress: (DataGridCellLongPressDetails details) { + print(details.rowColumnIndex); + }, + onCellSecondaryTap: (DataGridCellTapDetails details) { + print(details.rowColumnIndex); + }, + ); + + return SfDataGridTheme( + data: const SfDataGridThemeData( + headerColor: Color(0xff009889), + ), + child: dataGrid, + ); + } else { + return const Center( + child: CircularProgressIndicator( + strokeWidth: 2, + value: 0.8, + ), + ); + } }, ), ), @@ -347,9 +334,53 @@ class _MoviesScreenState extends State { ); } + void addMovieToList(Movie movie) { + String movieTitle = movie.movieTitle.toUpperCase(); + + _moviesList.add(movie); + + DataGridRow newRow = DataGridRow(cells: [ + DataGridCell(columnName: 'movieID', value: movie.movieID), + DataGridCell(columnName: 'state', value: movie.state), + DataGridCell( + columnName: 'backdropPath', value: movie.backdropPath), + DataGridCell(columnName: 'movieTitle', value: movie.movieTitle), + DataGridCell( + columnName: 'releaseDate', + value: DateFormat('yyyy-MM-dd').format(movie.releaseDate)), + DataGridCell(columnName: 'resolution', value: movie.resolution), + DataGridCell(columnName: 'overview', value: movie.overview), + ]); + + int rowNum = -1; + for (int i = 0; i < movieDataSource._movieDataGridRows.length; i++) { + DataGridRow tmpRow = movieDataSource._movieDataGridRows[i]; + List tmpCells = tmpRow.getCells(); + String tmpTitle = tmpCells[3].value.toString(); + + if (tmpTitle.toUpperCase().compareTo(movieTitle) >= 0) { + rowNum = i; + break; + } + + } + + if (rowNum == -1) { + rowNum = movieDataSource._movieDataGridRows.length; + } + + movieDataSource._movieDataGridRows.insert(rowNum, newRow); + movieDataSource.updateDataGrid(); + } + + void addMovieFinished() {} + void addMovie() { final m = Navigator.push( - context, MaterialPageRoute(builder: (ctx) => AddMovieScreen())); + context, + MaterialPageRoute( + builder: (ctx) => + AddMovieScreen(addMovieToList, addMovieFinished))); } void searchMovie() {