Movie Search
This commit is contained in:
@@ -5,10 +5,12 @@ class CheckboxWithLabel extends StatefulWidget {
|
||||
super.key,
|
||||
required String this.label,
|
||||
required this.callback,
|
||||
this.state = false,
|
||||
});
|
||||
|
||||
final String label;
|
||||
final Function(bool state) callback;
|
||||
final bool state;
|
||||
|
||||
@override
|
||||
State<CheckboxWithLabel> createState() => _CheckboxWithLabelState();
|
||||
@@ -17,6 +19,13 @@ class CheckboxWithLabel extends StatefulWidget {
|
||||
class _CheckboxWithLabelState extends State<CheckboxWithLabel> {
|
||||
bool isChecked = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
isChecked = widget.state;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Color getColor(Set<WidgetState> states) {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
import 'package:accordion/accordion.dart';
|
||||
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/checkbox_with_label.dart';
|
||||
import 'package:multimedia/widgets/movies/add/movie_search_list.dart';
|
||||
|
||||
import 'package:tmdb_api/tmdb_api.dart' as TMDB;
|
||||
@@ -22,13 +23,17 @@ class _AddMovieScreenState extends State<AddMovieScreen> {
|
||||
Logger logger = getLogger();
|
||||
|
||||
String movieTitleSearch = '';
|
||||
|
||||
String yearSearch = '';
|
||||
bool includeAdult = false;
|
||||
|
||||
List<Movie> movieList = [];
|
||||
|
||||
late MovieSearchList movieSearchList;
|
||||
|
||||
static const headerStyle = TextStyle(
|
||||
color: Color(0xffffffff), fontSize: 18, fontWeight: FontWeight.bold);
|
||||
bool advancedOptionsOpen = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
movieSearchList = MovieSearchList(movieList: movieList);
|
||||
@@ -37,8 +42,38 @@ class _AddMovieScreenState extends State<AddMovieScreen> {
|
||||
appBar: AppBar(
|
||||
title: Text('Search Movie'),
|
||||
actions: [
|
||||
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: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
@@ -77,34 +112,58 @@ class _AddMovieScreenState extends State<AddMovieScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
const VerticalDivider(
|
||||
width: 10,
|
||||
Accordion(
|
||||
headerBorderColor: Colors.blueGrey,
|
||||
headerBorderColorOpened: Colors.transparent,
|
||||
// headerBorderWidth: 1,
|
||||
headerBackgroundColorOpened: Colors.grey,
|
||||
contentBackgroundColor: Colors.black87,
|
||||
contentBorderColor: Colors.grey,
|
||||
contentBorderWidth: 3,
|
||||
contentHorizontalPadding: 20,
|
||||
scaleWhenAnimating: true,
|
||||
openAndCloseAnimation: true,
|
||||
headerPadding:
|
||||
const EdgeInsets.symmetric(vertical: 7, horizontal: 15),
|
||||
children: [
|
||||
AccordionSection(
|
||||
isOpen: advancedOptionsOpen,
|
||||
contentVerticalPadding: 20,
|
||||
leftIcon: const Icon(Icons.settings, color: Colors.white),
|
||||
header: const Text('Advanced Options', style: headerStyle),
|
||||
content: advancedOptions(),
|
||||
onOpenSection: () { advancedOptionsOpen = true; },
|
||||
onCloseSection: () { advancedOptionsOpen = false; },
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const Divider(
|
||||
height: 5,
|
||||
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);
|
||||
},
|
||||
Expanded(
|
||||
child: MovieSearchList(
|
||||
movieList: movieList,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: MovieSearchList(
|
||||
movieList: movieList,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void includeAdultCallback(bool state) {
|
||||
includeAdult = state;
|
||||
logger.i('Include Adult: ${includeAdult}');
|
||||
}
|
||||
|
||||
Widget advancedOptions() {
|
||||
return CheckboxWithLabel(
|
||||
label: 'Include Adult',
|
||||
callback: includeAdultCallback,
|
||||
state: includeAdult,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -148,15 +207,17 @@ class _AddMovieScreenState extends State<AddMovieScreen> {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int year = int.tryParse(yearSearch) ?? 0;
|
||||
|
||||
logger.i('Wir suchen ...');
|
||||
final tmdb = TMDB.TMDB(TMDB.ApiKeys(
|
||||
'a33271b9e54cdcb9a80680eaf5522f1b', 'apiReadAccessTokenv4'));
|
||||
|
||||
logger.i('IncludeAdult: ${includeAdult}');
|
||||
final response = await tmdb.v3.search.queryMovies(
|
||||
movieTitleSearch,
|
||||
year: year,
|
||||
includeAdult: includeAdult,
|
||||
language: 'de',
|
||||
);
|
||||
List<dynamic> movies = response['results'];
|
||||
|
||||
@@ -45,42 +45,93 @@ class MovieFilterBox extends StatelessWidget {
|
||||
callSetFilter();
|
||||
}
|
||||
|
||||
Widget buildScreen(BuildContext context) {
|
||||
double width = MediaQuery.sizeOf(context).width;
|
||||
|
||||
if (width < 500.0) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Movie Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Movie Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Movie Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
);
|
||||
return buildScreen(context);
|
||||
}
|
||||
|
||||
void callSetFilter() {
|
||||
|
||||
@@ -267,7 +267,6 @@ class _MoviesScreenState extends State<MoviesScreen> {
|
||||
appBar: AppBar(
|
||||
title: Text('Movies'),
|
||||
actions: [
|
||||
MovieFilterBox(setFilter: setFilter),
|
||||
const VerticalDivider(
|
||||
width: 10,
|
||||
thickness: 3,
|
||||
@@ -295,57 +294,63 @@ class _MoviesScreenState extends State<MoviesScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: FutureBuilder<Object>(
|
||||
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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
body: Column(children: [
|
||||
MovieFilterBox(setFilter: setFilter),
|
||||
Expanded(
|
||||
child: FutureBuilder<Object>(
|
||||
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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
void addMovie() {
|
||||
final m = Navigator.push(
|
||||
context, MaterialPageRoute(builder: (ctx) => AddMovieScreen()));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void searchMovie() {
|
||||
logger.i('search movie');
|
||||
|
||||
@@ -45,42 +45,93 @@ class TVShowFilterBox extends StatelessWidget {
|
||||
callSetFilter();
|
||||
}
|
||||
|
||||
Widget buildScreen(BuildContext context) {
|
||||
double width = MediaQuery.sizeOf(context).width;
|
||||
|
||||
if (width < 500.0) {
|
||||
return Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'TVShow Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'TVShow Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 250,
|
||||
child: TextField(
|
||||
style: TextStyle(color: Colors.white),
|
||||
decoration: InputDecoration(
|
||||
labelText: 'TVShow Title',
|
||||
),
|
||||
onChanged: (text) {
|
||||
textCallback(text);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Init',
|
||||
callback: initCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Progress',
|
||||
callback: progCallback,
|
||||
),
|
||||
CheckboxWithLabel(
|
||||
label: 'Done',
|
||||
callback: doneCallback,
|
||||
),
|
||||
],
|
||||
);
|
||||
return buildScreen(context);
|
||||
}
|
||||
|
||||
void callSetFilter() {
|
||||
|
||||
@@ -363,7 +363,6 @@ class _TVShowsScreenState extends State<TVShowsScreen> {
|
||||
appBar: AppBar(
|
||||
title: Text('TV Shows'),
|
||||
actions: [
|
||||
TVShowFilterBox(setFilter: setFilter),
|
||||
const VerticalDivider(
|
||||
width: 10,
|
||||
thickness: 3,
|
||||
@@ -399,48 +398,57 @@ class _TVShowsScreenState extends State<TVShowsScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
body: FutureBuilder<Object>(
|
||||
future: generateTVShowList(),
|
||||
builder: (context, data) {
|
||||
return data.hasData
|
||||
? SfDataGridTheme(
|
||||
data: const SfDataGridThemeData(
|
||||
headerColor: Color(0xff009889),
|
||||
),
|
||||
child: SfDataGrid(
|
||||
source: tvshowDataSource,
|
||||
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;
|
||||
}
|
||||
showTVShowDetails(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,
|
||||
),
|
||||
);
|
||||
},
|
||||
body: Column(
|
||||
children: [
|
||||
TVShowFilterBox(setFilter: setFilter),
|
||||
Expanded(
|
||||
child: FutureBuilder<Object>(
|
||||
future: generateTVShowList(),
|
||||
builder: (context, data) {
|
||||
return data.hasData
|
||||
? SfDataGridTheme(
|
||||
data: const SfDataGridThemeData(
|
||||
headerColor: Color(0xff009889),
|
||||
),
|
||||
child: SfDataGrid(
|
||||
source: tvshowDataSource,
|
||||
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;
|
||||
}
|
||||
showTVShowDetails(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,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
accordion:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: accordion
|
||||
sha256: "0eca3d1c619c6df63d6e384010fd2ef1164e7385d7102f88a6b56f658f160cd0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -128,6 +136,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
get:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: get
|
||||
sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.6"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -296,6 +312,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
scroll_to_index:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: scroll_to_index
|
||||
sha256: b707546e7500d9f070d63e5acf74fd437ec7eeeb68d3412ef7b0afada0b4f176
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -44,6 +44,7 @@ dependencies:
|
||||
transparent_image: ^2.0.1
|
||||
logger: ^2.4.0
|
||||
tmdb_api: ^2.2.0
|
||||
accordion: ^2.6.0
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
||||
Reference in New Issue
Block a user