diff --git a/assets/cfg/config.json b/assets/cfg/config.json new file mode 100644 index 0000000..ef30091 --- /dev/null +++ b/assets/cfg/config.json @@ -0,0 +1,7 @@ +{ + "dbProtocol": "http", + "dbHost": "192.168.0.70", + "dbPath": "/multimedia.php", + "dbUser": "", + "dbPassword": "" +} diff --git a/lib/data/movies.dart b/lib/data/movies.dart index 640f4c4..5d7300f 100644 --- a/lib/data/movies.dart +++ b/lib/data/movies.dart @@ -1,8 +1,6 @@ -import 'dart:convert'; import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; -import 'package:http/http.dart' as http; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; class Movie { diff --git a/lib/data/tvshows.dart b/lib/data/tvshows.dart new file mode 100644 index 0000000..bea8a82 --- /dev/null +++ b/lib/data/tvshows.dart @@ -0,0 +1,111 @@ +import 'package:intl/intl.dart'; + +import 'package:flutter/material.dart'; +import 'package:syncfusion_flutter_datagrid/datagrid.dart'; + +class TVShow { + int seriesID; + String seriesName; + DateTime firstAired; + int seriesState; + String resolution; + int cliffhanger; + String status; + + TVShow({ + required this.seriesID, + required this.seriesName, + required this.firstAired, + required this.seriesState, + required this.resolution, + required this.cliffhanger, + required this.status, + }); + + factory TVShow.fromJson(Map json) { + int seriesState = 0; + List stateList = json['seriesState'].toString().split(','); + + bool hasInit = false; + bool hasProg = false; + bool hasDone = false; + + for (String state in stateList) { + if (state[0] == '1') { + hasInit = true; + } else if (state[0] == '2') { + hasProg = true; + } else if (state[0] == '3') { + hasDone = true; + } + } + + if (hasProg) { + seriesState = 2; + } else if (hasInit) { + seriesState = 1; + } else if (hasDone) { + seriesState = 3; + } + + return TVShow( + seriesID: int.parse(json['seriesID']), + seriesName: json['seriesName'], + firstAired: DateTime.parse(json['firstAired']), + seriesState: seriesState, + resolution: json['resolution'], + status: json['status'], + cliffhanger: int.parse(json['cliffhanger']), + ); + } +} + +class TVShowDataSource extends DataGridSource { + /// Creates the employee data source class with required details. + TVShowDataSource(this.tvshows) { + buildDataGridRow(); + } + + void buildDataGridRow() { + _tvshowDataGridRows = tvshows + .map((e) => DataGridRow(cells: [ + DataGridCell(columnName: 'seriesID', value: e.seriesID), + DataGridCell( + columnName: 'seriesState', value: e.seriesState), + DataGridCell(columnName: 'status', value: e.status), + DataGridCell( + columnName: 'cliffhanger', value: e.cliffhanger), + DataGridCell( + columnName: 'seriesName', value: e.seriesName), + DataGridCell( + columnName: 'firstAired', + value: DateFormat('yyyy-MM-dd').format(e.firstAired)), + DataGridCell( + columnName: 'resolution', value: e.resolution), + ])) + .toList(); + } + + List tvshows = []; + + List _tvshowDataGridRows = []; + + @override + List get rows => _tvshowDataGridRows; + + @override + DataGridRowAdapter buildRow(DataGridRow row) { + return DataGridRowAdapter( + cells: row.getCells().map((e) { + return Container( + alignment: Alignment.center, + padding: const EdgeInsets.all(8.0), + child: Text(e.value.toString()), + ); + }).toList()); + } + + void updateDataGrid() { + notifyListeners(); + } +} diff --git a/lib/main.dart b/lib/main.dart index 2633213..2eec633 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:global_configuration/global_configuration.dart'; import 'package:multimedia/widgets/tabsScreen.dart'; @@ -12,16 +13,19 @@ final theme = ThemeData( textTheme: GoogleFonts.latoTextTheme(), ); -void main() { +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await GlobalConfiguration().loadFromPath('assets/cfg/config.json'); + runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); - // This widget is the root of your application. @override Widget build(BuildContext context) { + return MaterialApp( theme: theme, title: 'Multimedia', diff --git a/lib/widgets/moviesScreen.dart b/lib/widgets/moviesScreen.dart index 91dad98..193ca71 100644 --- a/lib/widgets/moviesScreen.dart +++ b/lib/widgets/moviesScreen.dart @@ -7,17 +7,13 @@ import 'package:http/http.dart' as http; import 'package:syncfusion_flutter_datagrid/datagrid.dart'; import 'package:syncfusion_flutter_core/theme.dart'; +import 'package:global_configuration/global_configuration.dart'; + import 'package:multimedia/data/movies.dart'; Color _kColorInit = const Color.fromARGB(255, 192, 192, 192); Color _kColorProg = const Color.fromARGB(255, 0, 0, 192); Color _kColorDone = const Color.fromARGB(255, 0, 192, 0); -// if(m_state == 1) -// color = "background-color: #C0C0C0;"; -// else if(m_state == 2) -// color = "background-color: #0000C0; color: #FFFFFF"; -// else -// color = "background-color: #00C000;"; class MoviesScreen extends StatefulWidget { const MoviesScreen({ @@ -34,15 +30,25 @@ class _MoviesScreenState extends State { List _columns = []; Future> generateMovieList() async { - // Give your PHP URL. It may be online URL o local host URL. - // Follow the steps provided in the below KB to configure the mysql using - // XAMPP and get the local host php link, - /// - Uri url = Uri.http('192.168.0.70', 'multimedia.php'); + Uri url = Uri( + scheme: GlobalConfiguration().getValue('dbProtocol'), + host: GlobalConfiguration().getValue('dbHost'), + path: GlobalConfiguration().getValue('dbPath'), + queryParameters: { + 'module': 'movie', + 'function': 'getList', + }, + ); + final response = await http.get(url); - var list = json.decode(response.body); + bool? error; + String? errorMessage; + + Map movies = json.decode(response.body); + error = movies['error']; + errorMessage = movies['errmsg']; + var list = movies['data']; - // Convert the JSON to List collection. List _movies = await list.map((json) => Movie.fromJson(json)).toList(); movieDataSource = MovieDataSource(_movies); @@ -111,20 +117,18 @@ class _MoviesScreenState extends State { future: generateMovieList(), builder: (context, data) { return data.hasData - ? - SfDataGridTheme( + ? SfDataGridTheme( data: const SfDataGridThemeData( headerColor: Color(0xff009889), ), - child: - SfDataGrid( + child: SfDataGrid( source: movieDataSource, selectionMode: SelectionMode.single, navigationMode: GridNavigationMode.row, columns: _columns, controller: _dataGridController, columnWidthMode: ColumnWidthMode.fill, - ), + ), ) : const Center( child: CircularProgressIndicator( diff --git a/lib/widgets/tabsScreen.dart b/lib/widgets/tabsScreen.dart index 55f2440..1bde59c 100644 --- a/lib/widgets/tabsScreen.dart +++ b/lib/widgets/tabsScreen.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:multimedia/widgets/tvshowsScreen.dart'; import 'package:multimedia/widgets/moviesScreen.dart'; -import 'package:multimedia/data/movies.dart'; class TabsScreen extends StatefulWidget { const TabsScreen({super.key}); @@ -34,7 +33,7 @@ class _TabsScreenState extends State { var activePageTitle = 'TV Shows'; if (_selectedPageIndex == 1) { - activePage = MoviesScreen(); + activePage = const MoviesScreen(); activePageTitle = 'Movies'; } diff --git a/lib/widgets/tvshowsScreen.dart b/lib/widgets/tvshowsScreen.dart index 579ec9e..510028c 100644 --- a/lib/widgets/tvshowsScreen.dart +++ b/lib/widgets/tvshowsScreen.dart @@ -1,15 +1,19 @@ -import 'dart:ui' as ui; +import 'dart:convert'; +import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; -Color _kColGrey = const Color.fromARGB(255, 192, 192, 192); -Color _kColBlue = const Color.fromARGB(255, 0, 0, 192); -Color _kColGreen = const Color.fromARGB(255, 0, 192, 0); -Color _kColBlack = const Color.fromARGB(255, 0, 0, 0); -Color _kColWhite = const Color.fromARGB(255, 255, 255, 255); +import 'package:syncfusion_flutter_datagrid/datagrid.dart'; +import 'package:syncfusion_flutter_core/theme.dart'; -double _kStateWidth = 6; -double _kStateHeight = 30; +import 'package:global_configuration/global_configuration.dart'; + +import 'package:multimedia/data/tvshows.dart'; + +Color _kColorInit = const Color.fromARGB(255, 192, 192, 192); +Color _kColorProg = const Color.fromARGB(255, 0, 0, 192); +Color _kColorDone = const Color.fromARGB(255, 0, 192, 0); class TVShowsScreen extends StatefulWidget { const TVShowsScreen({ @@ -20,56 +24,215 @@ class TVShowsScreen extends StatefulWidget { State createState() => _TVShowsScreenState(); } -class _TVShowsScreenState extends State - with SingleTickerProviderStateMixin { - ui.Image? _image; +class _TVShowsScreenState extends State { + final DataGridController _dataGridController = DataGridController(); + late TVShowDataSource tvshowDataSource; + List _columns = []; + + Future> generateTVShowList() async { + Uri url = Uri( + scheme: GlobalConfiguration().getValue('dbProtocol'), + host: GlobalConfiguration().getValue('dbHost'), + path: GlobalConfiguration().getValue('dbPath'), + queryParameters: { + 'module': 'tvshow', + 'function': 'getList', + }, + ); + + final response = await http.get(url); + bool? error; + String? errorMessage; + + Map tvshows = json.decode(response.body); + error = tvshows['error']; + errorMessage = tvshows['errmsg']; + var list = tvshows['tvshows']; + + List _tvshows = + await list.map((json) => TVShow.fromJson(json)).toList(); + tvshowDataSource = TVShowDataSource(_tvshows); + return _tvshows; + } + + List getColumns() { + return [ + GridColumn( + columnName: 'seriesID', + visible: false, + width: 70, + label: Container( + padding: const EdgeInsets.all(16.0), + alignment: Alignment.centerLeft, + child: const Text('seriesID'))), + GridColumn( + columnName: 'seriesState', + visible: false, + width: 70, + label: Container( + padding: const EdgeInsets.all(16.0), + alignment: Alignment.centerLeft, + child: const Text('seriesState'))), + GridColumn( + columnName: 'status', + visible: false, + width: 70, + label: Container( + padding: const EdgeInsets.all(16.0), + alignment: Alignment.centerLeft, + child: const Text('status'))), + GridColumn( + columnName: 'cliffhanger', + visible: false, + width: 70, + label: Container( + padding: const EdgeInsets.all(16.0), + alignment: Alignment.centerLeft, + child: const Text('cliffhanger'))), + GridColumn( + columnName: 'seriesName', + columnWidthMode: ColumnWidthMode.auto, + label: Container( + padding: const EdgeInsets.all(8.0), + alignment: Alignment.centerLeft, + child: const Text('Name'))), + GridColumn( + columnName: 'firstAired', + columnWidthMode: ColumnWidthMode.auto, + label: Container( + padding: const EdgeInsets.all(8.0), + alignment: Alignment.centerLeft, + child: const Text('First Aired'))), + GridColumn( + columnName: 'resolution', + columnWidthMode: ColumnWidthMode.auto, + label: Container( + padding: const EdgeInsets.all(8.0), + alignment: Alignment.centerLeft, + child: const Text('Resolution'))), + ]; + } @override void initState() { super.initState(); - _image = null; - _asyncInit(); + _columns = getColumns(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: FutureBuilder( + 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.fill, + ), + ) + : const Center( + child: CircularProgressIndicator( + strokeWidth: 2, + value: 0.8, + ), + ); + }, + ), + ); } +} - Future _asyncInit() async { - final image = await _generateImage(); - setState(() { - _image = image; - }); +class TVShowDataSource extends DataGridSource { + /// Creates the employee data source class with required details. + TVShowDataSource(this.tvshows) { + buildDataGridRow(); } - void _drawEpisodeState(Canvas c, Paint p, double x, Color color) { - Offset p1 = Offset(x + _kStateWidth, 1); - Offset p2 = Offset(x + _kStateWidth, _kStateHeight - 1); - Rect rect = Rect.fromLTRB(x, 0, x + _kStateWidth, _kStateHeight); - p.style = PaintingStyle.fill; - p.color = color; - c.drawRect(rect, p); - p.color = Colors.black; - c.drawLine(p1, p2, p); + void buildDataGridRow() { + _tvshowDataGridRows = tvshows + .map((e) => DataGridRow(cells: [ + DataGridCell(columnName: 'seriesID', value: e.seriesID), + DataGridCell( + columnName: 'seriesState', value: e.seriesState), + DataGridCell(columnName: 'status', value: e.status), + DataGridCell( + columnName: 'cliffhanger', value: e.cliffhanger), + DataGridCell( + columnName: 'seriesName', value: e.seriesName), + DataGridCell( + columnName: 'firstAired', + value: DateFormat('yyyy-MM-dd').format(e.firstAired)), + DataGridCell( + columnName: 'resolution', value: e.resolution), + ])) + .toList(); } - Future _generateImage() async { - final Paint paint = Paint(); - ui.PictureRecorder recorder = ui.PictureRecorder(); - Canvas c = Canvas(recorder); + List tvshows = []; + + List _tvshowDataGridRows = []; + + @override + List get rows => _tvshowDataGridRows; + + @override + DataGridRowAdapter buildRow(DataGridRow row) { + return DataGridRowAdapter( + cells: row.getCells().map((e) { + Color colorBG = Colors.white; + Color colorFG = Colors.black; + FontWeight fontWeight = FontWeight.normal; + FontStyle fontStyle = FontStyle.normal; + + if (e.columnName == 'seriesName') { + int seriesState = row.getCells().toList()[1].value; + String status = row.getCells().toList()[2].value; + int cliffhanger = row.getCells().toList()[3].value; - _drawEpisodeState(c, paint, _kStateWidth * 0, _kColBlack); - _drawEpisodeState(c, paint, _kStateWidth * 1, _kColBlue); - _drawEpisodeState(c, paint, _kStateWidth * 2, _kColGreen); - _drawEpisodeState(c, paint, _kStateWidth * 3, _kColGrey); + if (seriesState == 1) { + colorBG = _kColorInit; + } else if (seriesState == 2) { + colorBG = _kColorProg; + colorFG = Colors.white; + } else { + colorBG = _kColorDone; + } - ui.Picture picture = recorder.endRecording(); - final ui.Image image = - await picture.toImage(_kStateWidth.toInt() * 4, _kStateHeight.toInt()); + if (cliffhanger == 1) { + fontStyle = FontStyle.italic; + } - return image; + if (status == 'In Production' || status == 'Returning Series') { + fontWeight = FontWeight.bold; + } + } + + return Container( + alignment: Alignment.centerLeft, + padding: const EdgeInsets.all(8.0), + color: colorBG, + child: Text( + e.value.toString(), + style: TextStyle( + color: colorFG, + fontWeight: fontWeight, + fontStyle: fontStyle, + ), + ), + ); + }).toList()); } - @override - Widget build(BuildContext context) { - return Scaffold( - body: _image != null ? RawImage(image: _image!) : const Text('loading'), - ); + void updateDataGrid() { + notifyListeners(); } } diff --git a/pubspec.lock b/pubspec.lock index 2ec3d43..3de4050 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -91,6 +91,14 @@ packages: description: flutter source: sdk version: "0.0.0" + global_configuration: + dependency: "direct main" + description: + name: global_configuration + sha256: "432cfe858cfad7263b5cd51b1d342865a3983c400185f3839cc63b4b20702f66" + url: "https://pub.dev" + source: hosted + version: "2.0.0" google_fonts: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index a69cd59..c6d6e5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,8 @@ dependencies: intl: ^0.19.0 syncfusion_flutter_core: ^25.1.37 google_fonts: ^6.2.1 + global_configuration: ^2.0.0 + #global_configuration: ^2.0.0 dev_dependencies: flutter_test: @@ -64,7 +66,8 @@ flutter: uses-material-design: true # To add assets to your application, add an assets section, like this: - # assets: + assets: + - assets/cfg/config.json # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg