├── .gitignore
├── .metadata
├── README.md
├── analysis_options.yaml
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── io
│ │ │ │ └── flutter
│ │ │ │ └── app
│ │ │ │ └── FlutterMultiDexApplication.java
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── flutter_tv
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── drawable-v21
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── drawable
│ │ │ ├── background.png
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-night-v31
│ │ │ └── styles.xml
│ │ │ ├── values-night
│ │ │ └── styles.xml
│ │ │ ├── values-v31
│ │ │ └── styles.xml
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
└── splash.png
├── flutter_native_splash.yaml
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── 100.png
│ │ ├── 102.png
│ │ ├── 1024.png
│ │ ├── 114.png
│ │ ├── 120.png
│ │ ├── 128.png
│ │ ├── 144.png
│ │ ├── 152.png
│ │ ├── 16.png
│ │ ├── 167.png
│ │ ├── 172.png
│ │ ├── 180.png
│ │ ├── 196.png
│ │ ├── 20.png
│ │ ├── 216.png
│ │ ├── 256.png
│ │ ├── 29.png
│ │ ├── 32.png
│ │ ├── 40.png
│ │ ├── 48.png
│ │ ├── 50.png
│ │ ├── 512.png
│ │ ├── 55.png
│ │ ├── 57.png
│ │ ├── 58.png
│ │ ├── 60.png
│ │ ├── 64.png
│ │ ├── 66.png
│ │ ├── 72.png
│ │ ├── 76.png
│ │ ├── 80.png
│ │ ├── 87.png
│ │ ├── 88.png
│ │ ├── 92.png
│ │ └── Contents.json
│ ├── LaunchBackground.imageset
│ │ ├── Contents.json
│ │ └── background.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── Runner-Bridging-Header.h
├── lib
├── commons
│ └── vars.dart
├── controller
│ ├── get_channel.dart
│ ├── get_episode.dart
│ ├── provider
│ │ ├── altadefinizione.dart
│ │ ├── cb01_film.dart
│ │ └── guardaserie.dart
│ ├── tmdb.dart
│ └── web_loader.dart
├── main.dart
├── model
│ ├── channel_model.dart
│ ├── episodio_model.dart
│ ├── film_model.dart
│ ├── popular_serie.dart
│ └── season_model.dart
├── pages
│ ├── film
│ │ ├── film_details.dart
│ │ ├── film_search.dart
│ │ └── film_view.dart
│ ├── home_page.dart
│ ├── serie
│ │ ├── serie_details.dart
│ │ ├── serie_search.dart
│ │ └── series_view.dart
│ ├── settings_page.dart
│ └── video_player.dart
└── widget
│ ├── barra_ricerca.dart
│ ├── channel_card.dart
│ ├── channel_list.dart
│ ├── film_field.dart
│ ├── home_field.dart
│ └── serie_field.dart
├── linux
├── .gitignore
├── CMakeLists.txt
├── flutter
│ ├── CMakeLists.txt
│ ├── generated_plugin_registrant.cc
│ ├── generated_plugin_registrant.h
│ └── generated_plugins.cmake
├── main.cc
├── my_application.cc
└── my_application.h
├── macos
├── .gitignore
├── Flutter
│ ├── Flutter-Debug.xcconfig
│ ├── Flutter-Release.xcconfig
│ └── GeneratedPluginRegistrant.swift
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── app_icon_1024.png
│ │ ├── app_icon_128.png
│ │ ├── app_icon_16.png
│ │ ├── app_icon_256.png
│ │ ├── app_icon_32.png
│ │ ├── app_icon_512.png
│ │ └── app_icon_64.png
│ ├── Base.lproj
│ └── MainMenu.xib
│ ├── Configs
│ ├── AppInfo.xcconfig
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── Warnings.xcconfig
│ ├── DebugProfile.entitlements
│ ├── Info.plist
│ ├── MainFlutterWindow.swift
│ └── Release.entitlements
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
├── web
├── favicon.png
├── icons
│ ├── Icon-192.png
│ ├── Icon-512.png
│ ├── Icon-maskable-192.png
│ └── Icon-maskable-512.png
├── index.html
├── manifest.json
└── splash
│ ├── img
│ └── light-background.png
│ ├── splash.js
│ └── style.css
└── windows
├── .gitignore
├── CMakeLists.txt
├── flutter
├── CMakeLists.txt
├── generated_plugin_registrant.cc
├── generated_plugin_registrant.h
└── generated_plugins.cmake
└── runner
├── CMakeLists.txt
├── Runner.rc
├── flutter_window.cpp
├── flutter_window.h
├── main.cpp
├── resource.h
├── resources
└── app_icon.ico
├── runner.exe.manifest
├── utils.cpp
├── utils.h
├── win32_window.cpp
└── win32_window.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
8 | channel: stable
9 |
10 | project_type: app
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
17 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
18 | - platform: android
19 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
20 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
21 | - platform: ios
22 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
23 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
24 | - platform: linux
25 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
26 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
27 | - platform: macos
28 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
29 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
30 | - platform: web
31 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
32 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
33 | - platform: windows
34 | create_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
35 | base_revision: e99c9c7cd9f6c0b2f8ae6e3ebfd585239f5568f4
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter TV
2 | App per la visione di film, serie tv
3 |
4 | ## Features
5 |
6 | - Film
7 | - Serie TV
8 | - Ricerca
9 |
10 | ## Provider
11 | WIP
12 |
13 |
14 | ## To-Do
15 | - [ ] Guarda Film
16 | - [ ] Guarda Serie TV
17 | - [x] Selezione Stagione Serie TV
18 | - [x] Notifica Aggiornamento
19 | - [x] Ricerca
20 | - [x] UI Home
21 | - [x] UI Dettagli Film
22 | - [x] UI Dettagli Serie
23 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 33
30 | ndkVersion flutter.ndkVersion
31 |
32 | compileOptions {
33 | sourceCompatibility JavaVersion.VERSION_1_8
34 | targetCompatibility JavaVersion.VERSION_1_8
35 | }
36 |
37 | kotlinOptions {
38 | jvmTarget = '1.8'
39 | }
40 |
41 | sourceSets {
42 | main.java.srcDirs += 'src/main/kotlin'
43 | }
44 |
45 | defaultConfig {
46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
47 | applicationId "it.d4n73.fluttertv"
48 | // You can update the following values to match your application needs.
49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
50 | minSdkVersion 19
51 | targetSdkVersion flutter.targetSdkVersion
52 | versionCode flutterVersionCode.toInteger()
53 | versionName flutterVersionName
54 | }
55 |
56 | buildTypes {
57 | release {
58 | // TODO: Add your own signing config for the release build.
59 | // Signing with the debug keys for now, so `flutter run --release` works.
60 | signingConfig signingConfigs.debug
61 | }
62 | }
63 | }
64 |
65 | flutter {
66 | source '../..'
67 | }
68 |
69 | dependencies {
70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
71 | }
72 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
10 |
18 |
22 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java:
--------------------------------------------------------------------------------
1 | // Generated file.
2 | //
3 | // If you wish to remove Flutter's multidex support, delete this entire file.
4 | //
5 | // Modifications to this file should be done in a copy under a different name
6 | // as this file may be regenerated.
7 |
8 | package io.flutter.app;
9 |
10 | import android.app.Application;
11 | import android.content.Context;
12 | import androidx.annotation.CallSuper;
13 | import androidx.multidex.MultiDex;
14 |
15 | /**
16 | * Extension of {@link android.app.Application}, adding multidex support.
17 | */
18 | public class FlutterMultiDexApplication extends Application {
19 | @Override
20 | @CallSuper
21 | protected void attachBaseContext(Context base) {
22 | super.attachBaseContext(base);
23 | MultiDex.install(this);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/flutter_tv/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package it.d4n73.fluttertv
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/drawable-v21/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/drawable/background.png
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night-v31/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
19 |
22 |
23 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-v31/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
19 |
22 |
23 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.6.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.1.2'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | tasks.register("clean", Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
6 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/assets/splash.png
--------------------------------------------------------------------------------
/flutter_native_splash.yaml:
--------------------------------------------------------------------------------
1 | flutter_native_splash:
2 | # This package generates native code to customize Flutter's default white native splash screen
3 | # with background color and splash image.
4 | # Customize the parameters below, and run the following command in the terminal:
5 | # dart run flutter_native_splash:create
6 | # To restore Flutter's default white splash screen, run the following command in the terminal:
7 | # dart run flutter_native_splash:remove
8 |
9 | # color or background_image is the only required parameter. Use color to set the background
10 | # of your splash screen to a solid color. Use background_image to set the background of your
11 | # splash screen to a png image. This is useful for gradients. The image will be stretch to the
12 | # size of the app. Only one parameter can be used, color and background_image cannot both be set.
13 | #color: "#42a5f5"
14 | background_image: "assets/splash.png"
15 |
16 | # Optional parameters are listed below. To enable a parameter, uncomment the line by removing
17 | # the leading # character.
18 |
19 | # The image parameter allows you to specify an image used in the splash screen. It must be a
20 | # png file and should be sized for 4x pixel density.
21 | #image: assets/splash.png
22 |
23 | # The branding property allows you to specify an image used as branding in the splash screen.
24 | # It must be a png file. It is supported for Android, iOS and the Web. For Android 12,
25 | # see the Android 12 section below.
26 | #branding: assets/dart.png
27 |
28 | # To position the branding image at the bottom of the screen you can use bottom, bottomRight,
29 | # and bottomLeft. The default values is bottom if not specified or specified something else.
30 | #branding_mode: bottom
31 |
32 | # The color_dark, background_image_dark, image_dark, branding_dark are parameters that set the background
33 | # and image when the device is in dark mode. If they are not specified, the app will use the
34 | # parameters from above. If the image_dark parameter is specified, color_dark or
35 | # background_image_dark must be specified. color_dark and background_image_dark cannot both be
36 | # set.
37 | #color_dark: "#042a49"
38 | #background_image_dark: "assets/dark-background.png"
39 | #image_dark: assets/splash-invert.png
40 | #branding_dark: assets/dart_dark.png
41 |
42 | # Android 12 handles the splash screen differently than previous versions. Please visit
43 | # https://developer.android.com/guide/topics/ui/splash-screen
44 | # Following are Android 12 specific parameter.
45 | android_12:
46 | # The image parameter sets the splash screen icon image. If this parameter is not specified,
47 | # the app's launcher icon will be used instead.
48 | # Please note that the splash screen will be clipped to a circle on the center of the screen.
49 | # App icon with an icon background: This should be 960×960 pixels, and fit within a circle
50 | # 640 pixels in diameter.
51 | # App icon without an icon background: This should be 1152×1152 pixels, and fit within a circle
52 | # 768 pixels in diameter.
53 | #image: assets/android12splash.png
54 |
55 | # Splash screen background color.
56 | #color: "#42a5f5"
57 |
58 | # App icon background color.
59 | #icon_background_color: "#111111"
60 |
61 | # The branding property allows you to specify an image used as branding in the splash screen.
62 | #branding: assets/dart.png
63 |
64 | # The image_dark, color_dark, icon_background_color_dark, and branding_dark set values that
65 | # apply when the device is in dark mode. If they are not specified, the app will use the
66 | # parameters from above.
67 | #image_dark: assets/android12splash-invert.png
68 | #color_dark: "#042a49"
69 | #icon_background_color_dark: "#eeeeee"
70 |
71 | # The android, ios and web parameters can be used to disable generating a splash screen on a given
72 | # platform.
73 | #android: false
74 | #ios: false
75 | #web: false
76 |
77 | # Platform specific images can be specified with the following parameters, which will override
78 | # the respective parameter. You may specify all, selected, or none of these parameters:
79 | #color_android: "#42a5f5"
80 | #color_dark_android: "#042a49"
81 | #color_ios: "#42a5f5"
82 | #color_dark_ios: "#042a49"
83 | #color_web: "#42a5f5"
84 | #color_dark_web: "#042a49"
85 | #image_android: assets/splash-android.png
86 | #image_dark_android: assets/splash-invert-android.png
87 | #image_ios: assets/splash-ios.png
88 | #image_dark_ios: assets/splash-invert-ios.png
89 | #image_web: assets/splash-web.gif
90 | #image_dark_web: assets/splash-invert-web.gif
91 | #background_image_android: "assets/background-android.png"
92 | #background_image_dark_android: "assets/dark-background-android.png"
93 | #background_image_ios: "assets/background-ios.png"
94 | #background_image_dark_ios: "assets/dark-background-ios.png"
95 | #background_image_web: "assets/background-web.png"
96 | #background_image_dark_web: "assets/dark-background-web.png"
97 | #branding_android: assets/brand-android.png
98 | #branding_dark_android: assets/dart_dark-android.png
99 | #branding_ios: assets/brand-ios.gif
100 | #branding_dark_ios: assets/dart_dark-ios.gif
101 |
102 | # The position of the splash image can be set with android_gravity, ios_content_mode, and
103 | # web_image_mode parameters. All default to center.
104 | #
105 | # android_gravity can be one of the following Android Gravity (see
106 | # https://developer.android.com/reference/android/view/Gravity): bottom, center,
107 | # center_horizontal, center_vertical, clip_horizontal, clip_vertical, end, fill, fill_horizontal,
108 | # fill_vertical, left, right, start, or top.
109 | #android_gravity: center
110 | #
111 | # ios_content_mode can be one of the following iOS UIView.ContentMode (see
112 | # https://developer.apple.com/documentation/uikit/uiview/contentmode): scaleToFill,
113 | # scaleAspectFit, scaleAspectFill, center, top, bottom, left, right, topLeft, topRight,
114 | # bottomLeft, or bottomRight.
115 | #ios_content_mode: center
116 | #
117 | # web_image_mode can be one of the following modes: center, contain, stretch, and cover.
118 | #web_image_mode: center
119 |
120 | # The screen orientation can be set in Android with the android_screen_orientation parameter.
121 | # Valid parameters can be found here:
122 | # https://developer.android.com/guide/topics/manifest/activity-element#screen
123 | #android_screen_orientation: sensorLandscape
124 |
125 | # To hide the notification bar, use the fullscreen parameter. Has no effect in web since web
126 | # has no notification bar. Defaults to false.
127 | # NOTE: Unlike Android, iOS will not automatically show the notification bar when the app loads.
128 | # To show the notification bar, add the following code to your Flutter app:
129 | # WidgetsFlutterBinding.ensureInitialized();
130 | # SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top], );
131 | #fullscreen: true
132 |
133 | # If you have changed the name(s) of your info.plist file(s), you can specify the filename(s)
134 | # with the info_plist_files parameter. Remove only the # characters in the three lines below,
135 | # do not remove any spaces:
136 | #info_plist_files:
137 | # - 'ios/Runner/Info-Debug.plist'
138 | # - 'ios/Runner/Info-Release.plist'
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
41 |
42 |
52 |
54 |
60 |
61 |
62 |
63 |
69 |
71 |
77 |
78 |
79 |
80 |
82 |
83 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"idiom":"watch","filename":"172.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"86x86","expected-size":"172","role":"quickLook"},{"idiom":"watch","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"40x40","expected-size":"80","role":"appLauncher"},{"idiom":"watch","filename":"88.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"40mm","scale":"2x","size":"44x44","expected-size":"88","role":"appLauncher"},{"idiom":"watch","filename":"102.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"41mm","scale":"2x","size":"45x45","expected-size":"102","role":"appLauncher"},{"idiom":"watch","filename":"92.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"41mm","scale":"2x","size":"46x46","expected-size":"92","role":"appLauncher"},{"idiom":"watch","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"44mm","scale":"2x","size":"50x50","expected-size":"100","role":"appLauncher"},{"idiom":"watch","filename":"196.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"42mm","scale":"2x","size":"98x98","expected-size":"196","role":"quickLook"},{"idiom":"watch","filename":"216.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"44mm","scale":"2x","size":"108x108","expected-size":"216","role":"quickLook"},{"idiom":"watch","filename":"48.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"24x24","expected-size":"48","role":"notificationCenter"},{"idiom":"watch","filename":"55.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"42mm","scale":"2x","size":"27.5x27.5","expected-size":"55","role":"notificationCenter"},{"idiom":"watch","filename":"66.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"45mm","scale":"2x","size":"33x33","expected-size":"66","role":"notificationCenter"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch","role":"companionSettings","scale":"3x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch","role":"companionSettings","scale":"2x"},{"size":"1024x1024","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch-marketing","scale":"1x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]}
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "background.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "LaunchImage.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "LaunchImage@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "LaunchImage@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsD4n73/Flutter-TV/8e6e2740c0cee10f0f11283188798974a86e3ca0/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Flutter Tv
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | flutter_tv
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 | UIStatusBarHidden
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/commons/vars.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | const TextStyle dropdownMenuItem = TextStyle(color: Colors.black, fontSize: 18);
4 |
5 | const Color bgColor = Color(0xff202020);
6 |
7 | const primary = Color.fromARGB(255, 114, 158, 105);
8 | const secondary = Color.fromARGB(255, 114, 158, 105);
9 |
10 | String noImg =
11 | "https://upload.wikimedia.org/wikipedia/commons/1/14/No_Image_Available.jpg?20200913095930";
12 |
13 | var filmPopolari = [];
14 | var seriePopolari = [];
15 |
16 | var filmCercati = [];
17 | var serieCercati = [];
18 |
19 | String apiKey = "7e438eba5e1c995839ac0bacf9f33f23";
20 | String urlTv = "https://api.themoviedb.org/3/tv/";
21 |
22 | const appcastURL =
23 | 'https://raw.githubusercontent.com/IsD4n73/IsD4n73/file/Upgrade.xml';
24 |
25 | String userAgent =
26 | "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36";
27 |
--------------------------------------------------------------------------------
/lib/controller/get_channel.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:http/http.dart' as http;
3 | import 'package:http/http.dart';
4 |
5 | Future getChannels() async {
6 | var url = Uri.parse(
7 | "https://raw.githubusercontent.com/IsD4n73/IsD4n73/file/channel.json");
8 | Response response = await http.get(url);
9 |
10 | String data = response.body;
11 |
12 | return data;
13 | }
14 |
--------------------------------------------------------------------------------
/lib/controller/get_episode.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:flutter_tv/commons/vars.dart';
4 | import 'package:flutter_tv/model/episodio_model.dart';
5 | import 'package:http/http.dart' as http;
6 | import 'package:flutter_tv/model/season_model.dart';
7 |
8 | Future fetchEpisode(int id) async {
9 | final response =
10 | await http.get(Uri.parse("$urlTv$id?api_key=$apiKey&language=it"));
11 |
12 | if (response.statusCode == 200) {
13 | return SeasonModel.fromJson(jsonDecode(response.body));
14 | } else {
15 | throw Exception('Failed to load season');
16 | }
17 | }
18 |
19 | Future> fetchListEpisode(int id, String? season) async {
20 | season = season ?? "1";
21 | season = season.replaceAll("Stagione ", "");
22 | final response =
23 | await http.get(Uri.parse("$urlTv$id/season/$season?api_key=$apiKey&language=it"));
24 |
25 | if (response.statusCode == 200) {
26 | List list = [];
27 | var ris = jsonDecode(response.body);
28 |
29 | for (var episodio in ris["episodes"]) {
30 | list.add(EpisodioModel(episodio["episode_number"], episodio["name"],
31 | "https://image.tmdb.org/t/p/w500/${episodio["still_path"]}"));
32 | }
33 |
34 | return list;
35 | } else {
36 | throw Exception('Failed to load episodes');
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/controller/provider/altadefinizione.dart:
--------------------------------------------------------------------------------
1 | import 'package:bot_toast/bot_toast.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:loader_overlay/loader_overlay.dart';
4 | import 'package:tmdb_dart/tmdb_dart.dart';
5 | import 'package:html/parser.dart';
6 | import '../../commons/vars.dart';
7 | import 'package:flutter_tv/widget/channel_list.dart';
8 | import 'package:http/http.dart' as http;
9 |
10 | String urlAltadefinizione =
11 | "https://altadefinizione.haus/index.php?do=search&subaction=search&story=";
12 |
13 | Future altadefinizioneProvider(
14 | BuildContext context, MovieBase movie) async {
15 | context.loaderOverlay.show();
16 | String query = movie.title.replaceAll(" ", "%20");
17 | query = query.replaceAll("'", "%27");
18 |
19 | final filmResponse = await http.get(
20 | Uri.parse('$urlAltadefinizione$query&sortby=news_read'),
21 | headers: {"user-agent": userAgent},
22 | );
23 |
24 | if (filmResponse.statusCode == 200) {
25 | var document = parse(filmResponse.body);
26 | var link = document.getElementsByClassName("titleFilm").first;
27 |
28 | String? filmPageUrl = link.children.first.attributes["href"];
29 | if (filmPageUrl != null) {
30 | final channelResponse = await http
31 | .get(Uri.parse(filmPageUrl), headers: {"user-agent": userAgent});
32 | if (channelResponse.statusCode == 200) {
33 | document = parse(channelResponse.body);
34 | var link = document
35 | .getElementsByClassName("player-container-wrap guardahd-player")
36 | .first
37 | .children
38 | .first
39 | .attributes["src"];
40 |
41 | if (link != null) {
42 | final videoResponse = await http
43 | .get(Uri.parse(link), headers: {"user-agent": userAgent});
44 | if (videoResponse.statusCode == 200) {
45 | document = parse(videoResponse.body);
46 | var links = document
47 | .getElementsByClassName("_player-mirrors")
48 | .first
49 | .children;
50 | List canaliNomi = [];
51 | List canaliLink = [];
52 | for (var canale in links) {
53 | canaliNomi.add(canale.text);
54 | canaliLink.add(canale.attributes["data-link"]);
55 | }
56 |
57 | showChannelMenu(context, canaliNomi, canaliLink);
58 | } else {
59 | BotToast.showSimpleNotification(
60 | title:
61 | "C'è stato un errore nel recuperare i link - Errore: ${videoResponse.statusCode}",
62 | backgroundColor: Colors.white,
63 | );
64 | }
65 | } else {
66 | BotToast.showSimpleNotification(
67 | title: "Non sono stati trovati link",
68 | backgroundColor: Colors.white,
69 | );
70 | }
71 | } else {
72 | BotToast.showSimpleNotification(
73 | title:
74 | "C'è stato un errore nel recuperare il film - Errore: ${channelResponse.statusCode}",
75 | backgroundColor: Colors.white,
76 | );
77 | }
78 | } else {
79 | BotToast.showSimpleNotification(
80 | title: "Non è stato trovato il link del film.",
81 | backgroundColor: Colors.white,
82 | );
83 | }
84 | } else {
85 | BotToast.showSimpleNotification(
86 | title:
87 | "C'è stato un errore nel recuperare il film - Errore: ${filmResponse.statusCode}",
88 | backgroundColor: Colors.white,
89 | );
90 | }
91 | context.loaderOverlay.hide();
92 | }
93 |
--------------------------------------------------------------------------------
/lib/controller/provider/cb01_film.dart:
--------------------------------------------------------------------------------
1 | import 'package:bot_toast/bot_toast.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:loader_overlay/loader_overlay.dart';
4 | import 'package:tmdb_dart/tmdb_dart.dart';
5 | import 'package:html/parser.dart';
6 | import '../../commons/vars.dart';
7 | import 'package:flutter_tv/widget/channel_list.dart';
8 | import 'package:http/http.dart' as http;
9 |
10 | String urlCB01 = "https://cb01.institute/?s=";
11 |
12 | Future cb01FilmProvider(BuildContext context, MovieBase movie) async {
13 | context.loaderOverlay.show();
14 |
15 | String query = movie.title.replaceAll(" ", "+");
16 | query = query.replaceAll("'", "%27");
17 |
18 | final filmResponse = await http.get(
19 | Uri.parse('$urlCB01$query'),
20 | headers: {"user-agent": userAgent},
21 | );
22 |
23 | if (filmResponse.statusCode == 200) {
24 | var document = parse(filmResponse.body);
25 | var link = document.getElementsByClassName("sequex-one-columns");
26 |
27 | String? linkPage;
28 |
29 | for (var tile in link) {
30 | for (var anchor in tile.querySelectorAll("a").where(
31 | (element) => element.text.contains(movie.title),
32 | )) {
33 | linkPage = anchor.attributes["href"];
34 | }
35 | }
36 |
37 | print(linkPage);
38 |
39 | if (linkPage != null) {
40 | final pageResponse = await http.get(
41 | Uri.parse(linkPage),
42 | headers: {"user-agent": userAgent},
43 | );
44 | var doc = parse(pageResponse.body);
45 |
46 | try {} catch (_) {
47 | BotToast.showSimpleNotification(
48 | title: "Non sono stati trovati link a questo episodio",
49 | backgroundColor: Colors.white,
50 | );
51 | }
52 |
53 | ///
54 | } else {
55 | BotToast.showSimpleNotification(
56 | title: "Non è stata trovata la pagina della serie",
57 | backgroundColor: Colors.white,
58 | );
59 | }
60 | } else {
61 | BotToast.showSimpleNotification(
62 | title:
63 | "C'è stato un errore nel recuperare il film - Errore: ${filmResponse.statusCode}",
64 | backgroundColor: Colors.white,
65 | );
66 | }
67 | context.loaderOverlay.hide();
68 | }
69 |
--------------------------------------------------------------------------------
/lib/controller/provider/guardaserie.dart:
--------------------------------------------------------------------------------
1 | import 'package:bot_toast/bot_toast.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:loader_overlay/loader_overlay.dart';
4 | import 'package:tmdb_dart/tmdb_dart.dart';
5 | import 'package:html/parser.dart';
6 | import '../../commons/vars.dart';
7 | import 'package:flutter_tv/widget/channel_list.dart';
8 | import 'package:http/http.dart' as http;
9 |
10 | String urlGuardaserie =
11 | "https://guardaserie.one/index.php?do=search&subaction=search&story=";
12 | String urlGuardaserieShort = "https://guardaserie.one";
13 |
14 | Future guardaserieProvider(
15 | BuildContext context, TvBase movie, int episode, String season) async {
16 | context.loaderOverlay.show();
17 |
18 | String query = movie.name.replaceAll(" ", "%20");
19 | query = query.replaceAll("'", "%27");
20 |
21 | final filmResponse = await http.get(
22 | Uri.parse('$urlGuardaserie$query'),
23 | headers: {"user-agent": userAgent},
24 | );
25 |
26 | if (filmResponse.statusCode == 200) {
27 | var document = parse(filmResponse.body);
28 | var link = document.getElementsByClassName("mlnew-list");
29 |
30 | String? linkPage;
31 |
32 | for (var tile in link) {
33 | for (var anchor in tile.querySelectorAll("a").where(
34 | (element) => element.text.contains(movie.name),
35 | )) {
36 | linkPage = anchor.attributes["href"];
37 | }
38 | }
39 |
40 | if (linkPage != null) {
41 | final pageResponse = await http.get(
42 | Uri.parse(linkPage),
43 | headers: {"user-agent": userAgent},
44 | );
45 | var doc = parse(pageResponse.body);
46 |
47 | try {
48 | var episodes = doc.getElementsByClassName("tt_series").first;
49 | var episodesSeason = episodes.children.last.children;
50 |
51 | var seasonLinks = episodesSeason
52 | .where((element) => element.attributes["id"] == "season-$season");
53 |
54 | var links = seasonLinks.first.children.first.children
55 | .where((element) => element.children.first.text == "$episode")
56 | .first
57 | .children
58 | .last
59 | .children;
60 |
61 | List canaliNomi = [];
62 | List canaliLink = [];
63 |
64 | canaliNomi = links.map((e) => e.text).toList();
65 | canaliLink = links.map((e) {
66 | if (e.attributes["data-link"] == null) {
67 | return urlGuardaserie;
68 | } else {
69 | if (e.attributes["data-link"]!.contains("http")) {
70 | return e.attributes["data-link"];
71 | } else {
72 | return "$urlGuardaserieShort${e.attributes["data-link"]}";
73 | }
74 | }
75 | }).toList();
76 |
77 | showChannelMenu(context, canaliNomi, canaliLink);
78 | } catch (_) {
79 | BotToast.showSimpleNotification(
80 | title: "Non sono stati trovati link a questo episodio",
81 | backgroundColor: Colors.white,
82 | );
83 | }
84 |
85 | ///
86 | } else {
87 | BotToast.showSimpleNotification(
88 | title: "Non è stata trovata la pagina della serie",
89 | backgroundColor: Colors.white,
90 | );
91 | }
92 | } else {
93 | BotToast.showSimpleNotification(
94 | title:
95 | "C'è stato un errore nel recuperare il film - Errore: ${filmResponse.statusCode}",
96 | backgroundColor: Colors.white,
97 | );
98 | }
99 | context.loaderOverlay.hide();
100 | }
101 |
--------------------------------------------------------------------------------
/lib/controller/tmdb.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_tv/commons/vars.dart';
2 | import 'package:tmdb_dart/tmdb_dart.dart';
3 |
4 | class MoviePopular {
5 | static List movieResult = [];
6 | static List serieResult = [];
7 | }
8 |
9 | Future tmdbFilm() async {
10 | TmdbService service = TmdbService(apiKey);
11 | await service.initConfiguration();
12 |
13 | var pageMovieResult = await service.movie
14 | .getPopular(page: 1, settings: const MovieSearchSettings(language: "it"));
15 | MoviePopular.movieResult = pageMovieResult.results;
16 | }
17 |
18 | Future tmdbSerie() async {
19 | TmdbService service = TmdbService(apiKey);
20 | await service.initConfiguration();
21 |
22 | var pagedTvResult = await service.tv
23 | .getTopRated(page: 1, settings: const TvSearchSettings(language: "it"));
24 |
25 | MoviePopular.serieResult = pagedTvResult.results;
26 | }
27 |
28 | Future tmdbSeriePage(int pagina) async {
29 | await Future.delayed(const Duration(seconds: 2));
30 | TmdbService service = TmdbService(apiKey);
31 | await service.initConfiguration();
32 |
33 | var pagedTvResult = await service.tv.getTopRated(
34 | page: pagina, settings: const TvSearchSettings(language: "it"));
35 |
36 | MoviePopular.serieResult = pagedTvResult.results;
37 | }
38 |
39 | Future tmdbFilmPage(int pagina) async {
40 | TmdbService service = TmdbService(apiKey);
41 | await service.initConfiguration();
42 |
43 | var pageMovieResult = await service.movie.getPopular(
44 | page: pagina, settings: const MovieSearchSettings(language: "it"));
45 |
46 | MoviePopular.movieResult = pageMovieResult.results;
47 | }
48 |
49 | Future cercaFilmVal(String film) async {
50 | TmdbService service = TmdbService(apiKey);
51 | await service.initConfiguration();
52 |
53 | var pageMovieResult = await service.movie.search(film);
54 |
55 | MoviePopular.movieResult = pageMovieResult.results;
56 | }
57 |
58 | Future cercaSerieVal(String serie) async {
59 | TmdbService service = TmdbService(apiKey);
60 | await service.initConfiguration();
61 |
62 | var pageMovieResult = await service.tv.search(serie);
63 |
64 | MoviePopular.serieResult = pageMovieResult.results;
65 | }
66 |
--------------------------------------------------------------------------------
/lib/controller/web_loader.dart:
--------------------------------------------------------------------------------
1 | import 'package:bot_toast/bot_toast.dart';
2 | import 'package:flutter_inappwebview/flutter_inappwebview.dart';
3 |
4 | Future> getEntriesFrom(String url) async {
5 | List entries = [];
6 |
7 | print("URL: $url");
8 |
9 | String javaScript = '''var resource = window.performance.getEntries();
10 |
11 | resource.forEach(function(x) {
12 | console.log(x.name);
13 | });
14 | ''';
15 |
16 | HeadlessInAppWebView headlessWebView = HeadlessInAppWebView(
17 | initialUrlRequest: URLRequest(url: Uri.parse(url)),
18 | onProgressChanged: (controller, progress) =>
19 | BotToast.showText(text: "$progress%", onlyOne: false),
20 | onConsoleMessage: (controller, consoleMessage) {
21 | print(consoleMessage.message);
22 | },
23 | onLoadStop: (controller, url) async {
24 | print("Caricato $url");
25 | controller.evaluateJavascript(source: javaScript);
26 | },
27 | );
28 |
29 | await headlessWebView.run();
30 |
31 | await headlessWebView.webViewController
32 | .evaluateJavascript(source: javaScript);
33 |
34 | headlessWebView.dispose();
35 | return entries;
36 | }
37 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'package:bot_toast/bot_toast.dart';
3 | import 'package:flutter/foundation.dart';
4 | import 'package:flutter_inappwebview/flutter_inappwebview.dart';
5 | import 'package:flutter_native_splash/flutter_native_splash.dart';
6 |
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_tv/commons/vars.dart';
9 | import 'package:flutter_tv/pages/home_page.dart';
10 | import 'package:upgrader/upgrader.dart';
11 |
12 | void main(List args) {
13 | WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
14 | FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
15 | HttpOverrides.global = MyHttpOverrides();
16 |
17 | runApp(const MainApp());
18 | }
19 |
20 | class MainApp extends StatelessWidget {
21 | const MainApp({Key? key}) : super(key: key);
22 |
23 | @override
24 | Widget build(BuildContext context) {
25 | final cfg = AppcastConfiguration(url: appcastURL, supportedOS: ['android']);
26 |
27 | return MaterialApp(
28 | builder: BotToastInit(),
29 | navigatorObservers: [BotToastNavigatorObserver()],
30 | home: UpgradeAlert(
31 | upgrader: Upgrader(
32 | countryCode: "it",
33 | languageCode: "it",
34 | appcastConfig: cfg,
35 | durationUntilAlertAgain: const Duration(seconds: 5),
36 | messages: UpgraderMessages(code: 'it'),
37 | showIgnore: false,
38 | ),
39 | child: const HomePage(),
40 | ),
41 | title: "Flutter TV",
42 | theme: ThemeData(
43 | primarySwatch: Colors.green,
44 | ),
45 | );
46 | }
47 | }
48 |
49 | class MyHttpOverrides extends HttpOverrides {
50 | @override
51 | HttpClient createHttpClient(SecurityContext? context) {
52 | return super.createHttpClient(context)
53 | ..badCertificateCallback = (cert, host, port) => true;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/model/channel_model.dart:
--------------------------------------------------------------------------------
1 | class ChannelModel {
2 | String nome;
3 | String link;
4 | String image;
5 |
6 | ChannelModel({
7 | this.nome = ":(",
8 | this.image =
9 | "https://www.messoanuovo.it/wp-content/uploads/2022/05/watch-free-iptv-online-with-tablet-pc-smartphone-laptop-tv-min.jpg",
10 | required this.link,
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/lib/model/episodio_model.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: non_constant_identifier_names
2 |
3 | class EpisodioModel {
4 | int episode_number;
5 | String name;
6 | String poster;
7 |
8 | EpisodioModel(this.episode_number, this.name, [this.poster = ""]);
9 | }
10 |
--------------------------------------------------------------------------------
/lib/model/film_model.dart:
--------------------------------------------------------------------------------
1 | class FilmModel{
2 |
3 | }
--------------------------------------------------------------------------------
/lib/model/popular_serie.dart:
--------------------------------------------------------------------------------
1 | class PopularSerieModel {
2 | int? page;
3 | List? results;
4 | int? totalPages;
5 | int? totalResults;
6 |
7 | PopularSerieModel(
8 | {this.page, this.results, this.totalPages, this.totalResults});
9 |
10 | PopularSerieModel.fromJson(Map json) {
11 | page = json['page'];
12 | if (json['results'] != null) {
13 | results = [];
14 | json['results'].forEach((v) {
15 | results!.add(Results.fromJson(v));
16 | });
17 | }
18 | totalPages = json['total_pages'];
19 | totalResults = json['total_results'];
20 | }
21 |
22 | Map toJson() {
23 | final Map data = {};
24 | data['page'] = page;
25 | if (results != null) {
26 | data['results'] = results!.map((v) => v.toJson()).toList();
27 | }
28 | data['total_pages'] = totalPages;
29 | data['total_results'] = totalResults;
30 | return data;
31 | }
32 | }
33 |
34 | class Results {
35 | String? backdropPath;
36 | String? firstAirDate;
37 | List? genreIds;
38 | int? id;
39 | String? name;
40 | List? originCountry;
41 | String? originalLanguage;
42 | String? originalName;
43 | String? overview;
44 | double? popularity;
45 | String? posterPath;
46 | double? voteAverage;
47 | int? voteCount;
48 |
49 | Results(
50 | {this.backdropPath,
51 | this.firstAirDate,
52 | this.genreIds,
53 | this.id,
54 | this.name,
55 | this.originCountry,
56 | this.originalLanguage,
57 | this.originalName,
58 | this.overview,
59 | this.popularity,
60 | this.posterPath,
61 | this.voteAverage,
62 | this.voteCount});
63 |
64 | Results.fromJson(Map json) {
65 | backdropPath = json['backdrop_path'];
66 | firstAirDate = json['first_air_date'];
67 | genreIds = json['genre_ids'].cast();
68 | id = json['id'];
69 | name = json['name'];
70 | originCountry = json['origin_country'].cast();
71 | originalLanguage = json['original_language'];
72 | originalName = json['original_name'];
73 | overview = json['overview'];
74 | popularity = json['popularity'];
75 | posterPath = json['poster_path'];
76 | voteAverage = json['vote_average'];
77 | voteCount = json['vote_count'];
78 | }
79 |
80 | Map toJson() {
81 | final Map data = {};
82 | data['backdrop_path'] = backdropPath;
83 | data['first_air_date'] = firstAirDate;
84 | data['genre_ids'] = genreIds;
85 | data['id'] = id;
86 | data['name'] = name;
87 | data['origin_country'] = originCountry;
88 | data['original_language'] = originalLanguage;
89 | data['original_name'] = originalName;
90 | data['overview'] = overview;
91 | data['popularity'] = popularity;
92 | data['poster_path'] = posterPath;
93 | data['vote_average'] = voteAverage;
94 | data['vote_count'] = voteCount;
95 | return data;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/lib/model/season_model.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: non_constant_identifier_names
2 |
3 | class SeasonModel {
4 | int number_of_seasons;
5 | int number_of_episodes;
6 | bool in_production;
7 | List seasons;
8 |
9 | SeasonModel(this.number_of_episodes, this.number_of_seasons, this.seasons,
10 | this.in_production);
11 |
12 | factory SeasonModel.fromJson(Map json) {
13 | return SeasonModel(json["number_of_episodes"], json["number_of_seasons"],
14 | json["seasons"], json["in_production"]);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/pages/film/film_details.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: must_be_immutable, use_build_context_synchronously
2 |
3 | import 'dart:ui' as ui;
4 |
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter_tv/commons/vars.dart';
7 | import 'package:loader_overlay/loader_overlay.dart';
8 | import 'package:tmdb_dart/tmdb_dart.dart';
9 |
10 | import '../../controller/provider/altadefinizione.dart';
11 | import '../../controller/provider/cb01_film.dart';
12 |
13 | class MoviePage extends StatelessWidget {
14 | final MovieBase movie;
15 |
16 | const MoviePage(this.movie, {super.key});
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Scaffold(
21 | backgroundColor: bgColor,
22 | body: MediaQuery.removePadding(
23 | removeTop: true,
24 | context: context,
25 | child: LoaderOverlay(
26 | overlayColor: Colors.black,
27 | overlayOpacity: 0.8,
28 | child: ListView(
29 | children: [
30 | MovieThumbnail(movie.backdropPath),
31 | MovieHeaderWithPoster(movie),
32 | const HorizontalLine(),
33 | MoviePeople(movie),
34 | MovieFeedback(movie),
35 | ],
36 | ),
37 | ),
38 | ),
39 | );
40 | }
41 | }
42 |
43 | class MovieThumbnail extends StatelessWidget {
44 | final String? thumbnail;
45 |
46 | const MovieThumbnail(this.thumbnail, {super.key});
47 |
48 | @override
49 | Widget build(BuildContext context) {
50 | return Stack(
51 | alignment: Alignment.bottomCenter,
52 | children: [
53 | Stack(
54 | alignment: Alignment.center,
55 | children: [
56 | Padding(
57 | padding: const EdgeInsets.only(bottom: 1),
58 | child: Image.network(thumbnail!),
59 | ),
60 | // const Icon(
61 | // Icons.play_circle_outline,
62 | // size: 100,
63 | // color: Colors.white,
64 | // ),
65 | ],
66 | ),
67 | Container(
68 | decoration: const BoxDecoration(
69 | gradient: LinearGradient(
70 | colors: [ui.Color.fromARGB(17, 114, 158, 105), bgColor],
71 | begin: Alignment.topCenter,
72 | end: Alignment.bottomCenter,
73 | ),
74 | ),
75 | height: 80,
76 | )
77 | ],
78 | );
79 | }
80 | }
81 |
82 | class MovieHeaderWithPoster extends StatelessWidget {
83 | final MovieBase movie;
84 |
85 | const MovieHeaderWithPoster(this.movie, {super.key});
86 |
87 | @override
88 | Widget build(BuildContext context) {
89 | return Padding(
90 | padding: const EdgeInsets.symmetric(horizontal: 16),
91 | child: Row(
92 | children: [
93 | MoviePoster(movie.posterPath!),
94 | const SizedBox(width: 16),
95 | Expanded(
96 | child: MovieHeader(movie),
97 | ),
98 | ],
99 | ),
100 | );
101 | }
102 | }
103 |
104 | class MoviePoster extends StatelessWidget {
105 | final String poster;
106 |
107 | const MoviePoster(this.poster, {super.key});
108 |
109 | @override
110 | Widget build(BuildContext context) {
111 | var borderRadius = const BorderRadius.all(Radius.circular(10));
112 | return Card(
113 | shape: RoundedRectangleBorder(borderRadius: borderRadius),
114 | elevation: 8,
115 | child: ClipRRect(
116 | borderRadius: borderRadius,
117 | child: Image.network(
118 | poster,
119 | height: 160,
120 | ),
121 | ),
122 | );
123 | }
124 | }
125 |
126 | class MovieHeader extends StatelessWidget {
127 | const MovieHeader(this.movie, {super.key});
128 |
129 | final MovieBase movie;
130 |
131 | @override
132 | Widget build(BuildContext context) {
133 | return Column(
134 | crossAxisAlignment: CrossAxisAlignment.start,
135 | children: [
136 | Text(
137 | "${movie.releaseDate} · ${movie.voteAverage}".toUpperCase(),
138 | style: const TextStyle(
139 | fontWeight: FontWeight.w400,
140 | color: primary,
141 | ),
142 | ),
143 | Text(
144 | movie.title,
145 | style: const TextStyle(
146 | fontSize: 32, fontWeight: FontWeight.w500, color: Colors.white),
147 | ),
148 | //const Rating(3),
149 | Padding(
150 | padding: const EdgeInsets.symmetric(vertical: 18),
151 | child: Text.rich(
152 | TextSpan(
153 | style: const TextStyle(fontSize: 11, fontWeight: FontWeight.w300),
154 | children: [
155 | TextSpan(
156 | text: movie.overview,
157 | style: const TextStyle(color: Colors.white, fontSize: 14)),
158 | // const TextSpan(
159 | // text: "More...",
160 | // style: TextStyle(color: Colors.indigoAccent),
161 | // ),
162 | ],
163 | ),
164 | ),
165 | )
166 | ],
167 | );
168 | }
169 | }
170 |
171 | class Rating extends StatelessWidget {
172 | final int rating;
173 |
174 | const Rating(this.rating, {super.key});
175 |
176 | @override
177 | Widget build(BuildContext context) {
178 | return Row(
179 | children: Iterable.generate(
180 | 5,
181 | (i) => ShaderMask(
182 | shaderCallback: shader,
183 | child: Icon(
184 | i < rating ? Icons.star : Icons.star_border,
185 | size: 24,
186 | color: Colors.yellow,
187 | ),
188 | ),
189 | ).toList(),
190 | );
191 | }
192 |
193 | ui.Shader shader(Rect rect) => ui.Gradient.linear(
194 | const Offset(0, 0),
195 | Offset(0, rect.height),
196 | [Colors.yellowAccent, Colors.orange],
197 | );
198 | }
199 |
200 | class HorizontalLine extends StatelessWidget {
201 | const HorizontalLine({super.key});
202 |
203 | @override
204 | Widget build(BuildContext context) {
205 | return Padding(
206 | padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
207 | child: Container(
208 | height: 0.5,
209 | color: Colors.white12,
210 | ),
211 | );
212 | }
213 | }
214 |
215 | class MoviePeople extends StatelessWidget {
216 | final MovieBase movie;
217 |
218 | const MoviePeople(this.movie, {super.key});
219 |
220 | @override
221 | Widget build(BuildContext context) {
222 | return Padding(
223 | padding: const EdgeInsets.symmetric(horizontal: 16.0),
224 | child: Column(
225 | children: [
226 | MovieField("Lingua Originale: ", movie.originalLanguage),
227 | ],
228 | ),
229 | );
230 | }
231 | }
232 |
233 | class MovieField extends StatelessWidget {
234 | final String field;
235 | final String value;
236 |
237 | const MovieField(this.field, this.value, {super.key});
238 |
239 | @override
240 | Widget build(BuildContext context) {
241 | return Padding(
242 | padding: const EdgeInsets.symmetric(vertical: 8.0),
243 | child: Row(
244 | crossAxisAlignment: CrossAxisAlignment.start,
245 | children: [
246 | Text("$field: ",
247 | style: const TextStyle(
248 | color: Colors.white38,
249 | fontSize: 12,
250 | fontWeight: FontWeight.w300)),
251 | Expanded(
252 | child: Text(
253 | value,
254 | style: const TextStyle(
255 | color: Colors.white, fontSize: 12, fontWeight: FontWeight.w300),
256 | ))
257 | ],
258 | ),
259 | );
260 | }
261 | }
262 |
263 | class MovieFeedback extends StatelessWidget {
264 | MovieBase movie;
265 | MovieFeedback(this.movie, {super.key});
266 |
267 | @override
268 | Widget build(BuildContext context) {
269 | return Padding(
270 | padding: const EdgeInsets.symmetric(vertical: 12),
271 | child: Row(
272 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
273 | children: [
274 | FeedbackButton(Icons.play_arrow, "Guarda", movie),
275 | ],
276 | ),
277 | );
278 | }
279 | }
280 |
281 | class FeedbackButton extends StatelessWidget {
282 | final IconData icon;
283 | final String text;
284 | MovieBase movie;
285 |
286 | FeedbackButton(this.icon, this.text, this.movie, {super.key});
287 |
288 | @override
289 | Widget build(BuildContext context) {
290 | return InkWell(
291 | onTap: () async {
292 | await altadefinizioneProvider(context, movie);
293 | },
294 | child: Padding(
295 | padding: const EdgeInsets.all(8.0),
296 | child: Column(
297 | children: [
298 | Padding(
299 | padding: const EdgeInsets.all(8.0),
300 | child: Icon(
301 | icon,
302 | size: 32,
303 | color: primary,
304 | ),
305 | ),
306 | Text(text, style: const TextStyle(fontSize: 14, color: primary))
307 | ],
308 | ),
309 | ),
310 | );
311 | }
312 | }
313 |
--------------------------------------------------------------------------------
/lib/pages/film/film_search.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 | import 'package:flutter_tv/controller/tmdb.dart';
4 | import 'package:flutter_tv/pages/film/film_details.dart';
5 | import 'package:text_scroll/text_scroll.dart';
6 |
7 | class CercaFilm extends StatefulWidget {
8 | const CercaFilm({Key? key}) : super(key: key);
9 |
10 | @override
11 | CercaFilmState createState() => CercaFilmState();
12 | }
13 |
14 | class CercaFilmState extends State {
15 | TextEditingController ricerca = TextEditingController();
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | backgroundColor: bgColor,
21 | body: Column(
22 | children: [
23 | const SizedBox(height: 50),
24 | Material(
25 | elevation: 5.0,
26 | borderRadius: const BorderRadius.all(Radius.circular(30)),
27 | child: TextField(
28 | controller: ricerca,
29 | cursorColor: primary,
30 | style: dropdownMenuItem,
31 | onChanged: (value) async {
32 | if (value.isNotEmpty) {
33 | await cercaFilmVal(value);
34 | setState(() {
35 | filmCercati = List.of(MoviePopular.movieResult);
36 | });
37 | }
38 | },
39 | decoration: const InputDecoration(
40 | hintText: "Cerca Film",
41 | hintStyle: TextStyle(color: Colors.black38, fontSize: 16),
42 | prefixIcon: Material(
43 | elevation: 0.0,
44 | borderRadius: BorderRadius.all(Radius.circular(30)),
45 | child: Icon(Icons.search),
46 | ),
47 | border: InputBorder.none,
48 | contentPadding:
49 | EdgeInsets.symmetric(horizontal: 25, vertical: 13)),
50 | ),
51 | ),
52 | Expanded(
53 | child: GridView.builder(
54 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
55 | crossAxisCount: 2,
56 | ),
57 | itemCount: filmCercati.length,
58 | scrollDirection: Axis.vertical,
59 | shrinkWrap: true,
60 | itemBuilder: (context, index) {
61 | return Padding(
62 | padding: const EdgeInsets.all(10),
63 | child: InkWell(
64 | onTap: () {
65 | Navigator.push(
66 | context,
67 | MaterialPageRoute(
68 | builder: (context) =>
69 | MoviePage(filmCercati[index])),
70 | );
71 | },
72 | child: Container(
73 | decoration: BoxDecoration(
74 | color: primary,
75 | borderRadius: BorderRadius.circular(10.0),
76 | image: DecorationImage(
77 | image: NetworkImage(
78 | filmCercati[index].posterPath ?? noImg),
79 | fit: BoxFit.cover,
80 | ),
81 | ),
82 | child: Container(
83 | color: Colors.black.withOpacity(0.5),
84 | width: double.infinity,
85 | child: Row(
86 | crossAxisAlignment: CrossAxisAlignment.end,
87 | mainAxisAlignment: MainAxisAlignment.center,
88 | children: [
89 | Flexible(
90 | child: Padding(
91 | padding: const EdgeInsets.all(10),
92 | child: TextScroll(
93 | "${filmCercati[index].title} ",
94 | textAlign: TextAlign.center,
95 | velocity: const Velocity(
96 | pixelsPerSecond: Offset(50, 0)),
97 | style: const TextStyle(
98 | color: Colors.white,
99 | fontSize: 20,
100 | fontWeight: FontWeight.bold),
101 | ),
102 | ),
103 | ),
104 | ],
105 | ),
106 | )),
107 | ),
108 | );
109 | },
110 | ),
111 | ),
112 | ],
113 | ),
114 | );
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/lib/pages/film/film_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 | import 'package:flutter_tv/controller/tmdb.dart';
4 | import 'package:flutter_tv/widget/film_field.dart';
5 | import 'package:loader_overlay/loader_overlay.dart';
6 |
7 | class FilmPopolari extends StatefulWidget {
8 | const FilmPopolari({Key? key}) : super(key: key);
9 |
10 | @override
11 | FilmPopolariState createState() => FilmPopolariState();
12 | }
13 |
14 | class FilmPopolariState extends State {
15 | int pagina = 1;
16 | TextEditingController ricerca = TextEditingController();
17 |
18 | @override
19 | void initState() {
20 | super.initState();
21 | Future.delayed(Duration.zero, () async {
22 | await tmdbFilm();
23 | setState(() {
24 | filmPopolari = List.of(MoviePopular.movieResult);
25 | });
26 | });
27 | }
28 |
29 | @override
30 | Widget build(BuildContext context) {
31 | return LoaderOverlay(
32 | overlayColor: Colors.black,
33 | overlayOpacity: 0.8,
34 | child: SingleChildScrollView(
35 | child: ListView.builder(
36 | itemCount: filmPopolari.length,
37 | shrinkWrap: true,
38 | physics: const NeverScrollableScrollPhysics(),
39 | itemBuilder: (BuildContext context, int index) {
40 | if (index == filmPopolari.length - 1) {
41 | return Padding(
42 | padding: const EdgeInsets.only(bottom: 30),
43 | child: ElevatedButton(
44 | style: ButtonStyle(
45 | backgroundColor: MaterialStateProperty.all(primary),
46 | shape: MaterialStateProperty.all(
47 | RoundedRectangleBorder(
48 | borderRadius: BorderRadius.circular(18.0),
49 | ),
50 | ),
51 | ),
52 | onPressed: () async {
53 | context.loaderOverlay.show();
54 | pagina = pagina + 1;
55 | await tmdbFilmPage(pagina);
56 | setState(() {
57 | filmPopolari.addAll(MoviePopular.movieResult);
58 | });
59 | await Future.delayed(const Duration(seconds: 2));
60 | context.loaderOverlay.hide();
61 | },
62 | child: const Text(
63 | "Carica Altro",
64 | style: TextStyle(color: Colors.white),
65 | ),
66 | ),
67 | );
68 | } else {
69 | return BuildMovie(
70 | index: index,
71 | channelList: filmPopolari,
72 | );
73 | }
74 | },
75 | ),
76 | ),
77 | );
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/lib/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_native_splash/flutter_native_splash.dart';
4 | import 'package:flutter_tv/commons/vars.dart';
5 | import 'package:flutter_tv/controller/provider/guardaserie.dart';
6 | import 'package:flutter_tv/pages/film/film_search.dart';
7 | import 'package:flutter_tv/pages/film/film_view.dart';
8 | import 'package:flutter_tv/pages/serie/serie_search.dart';
9 | import 'package:flutter_tv/pages/serie/series_view.dart';
10 | import 'package:flutter_tv/pages/settings_page.dart';
11 |
12 | class HomePage extends StatefulWidget {
13 | const HomePage({Key? key}) : super(key: key);
14 |
15 | @override
16 | HomePageState createState() => HomePageState();
17 | }
18 |
19 | class HomePageState extends State {
20 | int _bottomNavIndex = 0;
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | FlutterNativeSplash.remove();
25 | return Scaffold(
26 | backgroundColor: bgColor,
27 | appBar: AppBar(
28 | backgroundColor: primary,
29 | shape: const RoundedRectangleBorder(
30 | borderRadius: BorderRadius.vertical(
31 | bottom: Radius.circular(20),
32 | ),
33 | ),
34 | centerTitle: true,
35 | leading: IconButton(
36 | onPressed: () {
37 | if (_bottomNavIndex == 0) {
38 | Navigator.push(
39 | context,
40 | MaterialPageRoute(
41 | builder: (context) => const CercaFilm(),
42 | ),
43 | );
44 | } else {
45 | Navigator.push(
46 | context,
47 | MaterialPageRoute(
48 | builder: (context) => const CercaSerie(),
49 | ),
50 | );
51 | }
52 | },
53 | icon: const Icon(
54 | Icons.search,
55 | ),
56 | ),
57 | title: const Text(
58 | "Flutter TV",
59 | style: TextStyle(color: Colors.white),
60 | ),
61 | ),
62 | bottomNavigationBar: AnimatedBottomNavigationBar(
63 | icons: const [Icons.movie, Icons.tv],
64 | activeColor: primary,
65 | activeIndex: _bottomNavIndex,
66 | gapLocation: GapLocation.center,
67 | notchSmoothness: NotchSmoothness.verySmoothEdge,
68 | onTap: (index) => setState(() => _bottomNavIndex = index),
69 | ),
70 | floatingActionButton: FloatingActionButton(
71 | onPressed: () {
72 | Navigator.push(
73 | context,
74 | MaterialPageRoute(
75 | builder: (context) => const SettingsPage(),
76 | ),
77 | );
78 | },
79 | backgroundColor: primary,
80 | child: const Icon(Icons.settings),
81 | ),
82 | floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
83 | body: _bottomNavIndex == 0 ? const FilmPopolari() : const SeriePopolari(),
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/lib/pages/serie/serie_search.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 | import 'package:flutter_tv/controller/tmdb.dart';
4 | import 'package:flutter_tv/pages/serie/serie_details.dart';
5 | import 'package:text_scroll/text_scroll.dart';
6 |
7 | class CercaSerie extends StatefulWidget {
8 | const CercaSerie({Key? key}) : super(key: key);
9 |
10 | @override
11 | CercaSerieState createState() => CercaSerieState();
12 | }
13 |
14 | class CercaSerieState extends State {
15 | TextEditingController ricerca = TextEditingController();
16 |
17 | @override
18 | void initState() {
19 | super.initState();
20 | }
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | backgroundColor: bgColor,
26 | body: Column(
27 | children: [
28 | const SizedBox(height: 50),
29 | Material(
30 | elevation: 5.0,
31 | borderRadius: const BorderRadius.all(Radius.circular(30)),
32 | child: TextField(
33 | controller: ricerca,
34 | cursorColor: primary,
35 | style: dropdownMenuItem,
36 | onChanged: (value) async {
37 | if (value.isNotEmpty) {
38 | await cercaSerieVal(value);
39 | setState(() {
40 | serieCercati = List.of(MoviePopular.serieResult);
41 | });
42 | }
43 | },
44 | decoration: const InputDecoration(
45 | hintText: "Cerca Serie TV",
46 | hintStyle: TextStyle(color: Colors.black38, fontSize: 16),
47 | prefixIcon: Material(
48 | elevation: 0.0,
49 | borderRadius: BorderRadius.all(Radius.circular(30)),
50 | child: Icon(Icons.search),
51 | ),
52 | border: InputBorder.none,
53 | contentPadding:
54 | EdgeInsets.symmetric(horizontal: 25, vertical: 13),
55 | ),
56 | ),
57 | ),
58 | Expanded(
59 | child: GridView.builder(
60 | gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
61 | crossAxisCount: 2,
62 | ),
63 | itemCount: serieCercati.length,
64 | scrollDirection: Axis.vertical,
65 | shrinkWrap: true,
66 | itemBuilder: (context, index) {
67 | return Padding(
68 | padding: const EdgeInsets.all(10),
69 | child: InkWell(
70 | onTap: () {
71 | Navigator.push(
72 | context,
73 | MaterialPageRoute(
74 | builder: (context) =>
75 | SeriePage(serieCercati[index])),
76 | );
77 | },
78 | child: Container(
79 | decoration: BoxDecoration(
80 | color: primary,
81 | borderRadius: BorderRadius.circular(10.0),
82 | image: DecorationImage(
83 | image: NetworkImage(
84 | serieCercati[index].posterPath ?? noImg),
85 | fit: BoxFit.cover,
86 | ),
87 | ),
88 | child: Container(
89 | color: Colors.black.withOpacity(0.5),
90 | width: double.infinity,
91 | child: Row(
92 | crossAxisAlignment: CrossAxisAlignment.end,
93 | mainAxisAlignment: MainAxisAlignment.center,
94 | children: [
95 | Flexible(
96 | child: Padding(
97 | padding: const EdgeInsets.all(10),
98 | child: TextScroll(
99 | "${serieCercati[index].name} ",
100 | textAlign: TextAlign.center,
101 | velocity: const Velocity(
102 | pixelsPerSecond: Offset(50, 0)),
103 | style: const TextStyle(
104 | color: Colors.white,
105 | fontSize: 20,
106 | fontWeight: FontWeight.bold),
107 | ),
108 | ),
109 | ),
110 | ],
111 | ),
112 | ),
113 | ),
114 | ),
115 | );
116 | },
117 | ),
118 | ),
119 | ],
120 | ),
121 | );
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/lib/pages/serie/series_view.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 | import 'package:flutter_tv/controller/tmdb.dart';
4 | import 'package:flutter_tv/widget/serie_field.dart';
5 | import 'package:loader_overlay/loader_overlay.dart';
6 | import 'package:tmdb_dart/tmdb_dart.dart';
7 |
8 | class SeriePopolari extends StatefulWidget {
9 | const SeriePopolari({Key? key}) : super(key: key);
10 |
11 | @override
12 | SeriePopolariState createState() => SeriePopolariState();
13 | }
14 |
15 | class SeriePopolariState extends State {
16 | int pagina = 1;
17 | List seriePopolari = [];
18 |
19 | @override
20 | void initState() {
21 | super.initState();
22 | Future.delayed(Duration.zero, () async {
23 | await tmdbSerie();
24 | setState(() {
25 | seriePopolari = List.of(MoviePopular.serieResult);
26 | });
27 | });
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return LoaderOverlay(
33 | overlayColor: Colors.black,
34 | overlayOpacity: 0.8,
35 | child: SingleChildScrollView(
36 | child: ListView.builder(
37 | itemCount: seriePopolari.length,
38 | shrinkWrap: true,
39 | physics: const NeverScrollableScrollPhysics(),
40 | itemBuilder: (BuildContext context, int index) {
41 | if (index == seriePopolari.length - 1) {
42 | return Padding(
43 | padding: const EdgeInsets.only(bottom: 30),
44 | child: ElevatedButton(
45 | style: ButtonStyle(
46 | backgroundColor: MaterialStateProperty.all(primary),
47 | shape: MaterialStateProperty.all(
48 | RoundedRectangleBorder(
49 | borderRadius: BorderRadius.circular(18.0),
50 | ))),
51 | onPressed: () async {
52 | context.loaderOverlay.show();
53 |
54 | pagina = pagina + 1;
55 |
56 | await tmdbSeriePage(pagina);
57 | setState(() {
58 | seriePopolari.addAll(MoviePopular.serieResult);
59 | });
60 | await Future.delayed(const Duration(seconds: 2));
61 | context.loaderOverlay.hide();
62 | },
63 | child: const Text(
64 | "Carica Altro",
65 | style: TextStyle(color: Colors.white),
66 | ),
67 | ),
68 | );
69 | } else {
70 | return BuildSerie(
71 | index: index,
72 | channelList: seriePopolari,
73 | );
74 | }
75 | },
76 | ),
77 | ),
78 | );
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/lib/pages/settings_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../commons/vars.dart';
4 |
5 | class SettingsPage extends StatefulWidget {
6 | const SettingsPage({Key? key}) : super(key: key);
7 |
8 | @override
9 | State createState() => _SettingsPageState();
10 | }
11 |
12 | class _SettingsPageState extends State {
13 | @override
14 | Widget build(BuildContext context) {
15 | return Scaffold(
16 | appBar: AppBar(
17 | backgroundColor: primary,
18 | shape: const RoundedRectangleBorder(
19 | borderRadius: BorderRadius.vertical(
20 | bottom: Radius.circular(20),
21 | ),
22 | ),
23 | centerTitle: true,
24 | leading: IconButton(
25 | onPressed: () {
26 | Navigator.pop(context);
27 | },
28 | icon: const Icon(
29 | Icons.arrow_back_ios_new,
30 | ),
31 | ),
32 | title: const Text(
33 | "Impostazioni",
34 | style: TextStyle(color: Colors.white),
35 | ),
36 | ),
37 | body: Placeholder(),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/pages/video_player.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:video_player/video_player.dart';
3 |
4 | class VideoPlayerWidget extends StatefulWidget {
5 | final String link;
6 | const VideoPlayerWidget({Key? key, required this.link}) : super(key: key);
7 |
8 | @override
9 | State createState() => _VideoPlayerWidgetState();
10 | }
11 |
12 | class _VideoPlayerWidgetState extends State {
13 | late VideoPlayerController controller;
14 |
15 | @override
16 | void initState() {
17 | super.initState();
18 | controller = VideoPlayerController.network(widget.link)
19 | ..initialize().then((_) {
20 | setState(() {});
21 | });
22 | }
23 |
24 | @override
25 | Widget build(BuildContext context) {
26 | return Scaffold(
27 | body: VideoPlayer(controller),
28 | );
29 | }
30 |
31 | @override
32 | void dispose() {
33 | super.dispose();
34 | controller.dispose();
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/widget/barra_ricerca.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 |
4 | Widget barraRIcerca(TextEditingController textController) {
5 | return Padding(
6 | padding: const EdgeInsets.symmetric(horizontal: 20),
7 | child: Material(
8 | elevation: 5.0,
9 | borderRadius: const BorderRadius.all(Radius.circular(30)),
10 | child: TextField(
11 | controller: textController,
12 | cursorColor: primary,
13 | style: dropdownMenuItem,
14 | decoration: const InputDecoration(
15 | hintText: "Cerca",
16 | hintStyle: TextStyle(color: Colors.black38, fontSize: 16),
17 | prefixIcon: Material(
18 | elevation: 0.0,
19 | borderRadius: BorderRadius.all(Radius.circular(30)),
20 | child: Icon(Icons.search),
21 | ),
22 | border: InputBorder.none,
23 | contentPadding: EdgeInsets.symmetric(horizontal: 25, vertical: 13)),
24 | ),
25 | ),
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/lib/widget/channel_card.dart:
--------------------------------------------------------------------------------
1 | // ignore_for_file: must_be_immutable
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_tv/model/channel_model.dart';
5 | import 'package:flutter_tv/pages/video_player.dart';
6 |
7 | class ChannelCard extends StatefulWidget {
8 | ChannelModel channel;
9 |
10 | ChannelCard({super.key, required this.channel});
11 |
12 | @override
13 | State createState() => _ChannelCardState();
14 | }
15 |
16 | class _ChannelCardState extends State {
17 | @override
18 | Widget build(BuildContext context) {
19 | return InkWell(
20 | onTap: () {
21 | Navigator.push(
22 | context,
23 | MaterialPageRoute(
24 | builder: (context) => VideoPlayerWidget(
25 | link: widget.channel.link,
26 | ),
27 | ),
28 | );
29 | },
30 | child: Card(
31 | margin: const EdgeInsets.all(4),
32 | color: const Color(0xffffffff),
33 | shadowColor: const Color(0xff000000),
34 | elevation: 4,
35 | shape: RoundedRectangleBorder(
36 | borderRadius: BorderRadius.circular(12.0),
37 | ),
38 | child: Padding(
39 | padding: const EdgeInsets.all(8),
40 | child: Column(
41 | mainAxisAlignment: MainAxisAlignment.start,
42 | crossAxisAlignment: CrossAxisAlignment.start,
43 | mainAxisSize: MainAxisSize.min,
44 | children: [
45 | Image(
46 | image: NetworkImage(widget.channel.image),
47 | height: MediaQuery.of(context).size.height * 0.15,
48 | width: MediaQuery.of(context).size.width,
49 | fit: BoxFit.cover,
50 | ),
51 | Expanded(
52 | flex: 1,
53 | child: Padding(
54 | padding: const EdgeInsets.fromLTRB(0, 8, 0, 0),
55 | child: Column(
56 | mainAxisAlignment: MainAxisAlignment.start,
57 | crossAxisAlignment: CrossAxisAlignment.start,
58 | mainAxisSize: MainAxisSize.min,
59 | children: [
60 | Text(
61 | widget.channel.nome,
62 | textAlign: TextAlign.start,
63 | maxLines: 1,
64 | overflow: TextOverflow.clip,
65 | style: const TextStyle(
66 | fontWeight: FontWeight.w700,
67 | fontStyle: FontStyle.normal,
68 | fontSize: 16,
69 | color: Color(0xff000000),
70 | ),
71 | ),
72 | /*Expanded(
73 | flex: 1,
74 | child: Row(
75 | mainAxisAlignment: MainAxisAlignment.start,
76 | crossAxisAlignment: CrossAxisAlignment.center,
77 | mainAxisSize: MainAxisSize.max,
78 | children: [
79 | Container(
80 | alignment: Alignment.center,
81 | margin: const EdgeInsets.all(0),
82 | padding: const EdgeInsets.all(0),
83 | width: 40,
84 | height: 20,
85 | decoration: BoxDecoration(
86 | color: primary,
87 | shape: BoxShape.rectangle,
88 | borderRadius: BorderRadius.zero,
89 | border: Border.all(
90 | color: const Color(0x4d9e9e9e), width: 1),
91 | ),
92 | child: const Text(
93 | "50%",
94 | textAlign: TextAlign.start,
95 | overflow: TextOverflow.clip,
96 | style: TextStyle(
97 | fontWeight: FontWeight.w400,
98 | fontStyle: FontStyle.normal,
99 | fontSize: 11,
100 | color: Color(0xffffffff),
101 | ),
102 | ),
103 | ),
104 | ],
105 | ),
106 | ),*/
107 | ],
108 | ),
109 | ),
110 | ),
111 | ],
112 | ),
113 | ),
114 | ),
115 | );
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/lib/widget/channel_list.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/commons/vars.dart';
3 | import 'package:flutter_tv/controller/web_loader.dart';
4 |
5 | showChannelMenu(
6 | BuildContext parentContext, List canali, List links) {
7 | showModalBottomSheet(
8 | context: parentContext,
9 | backgroundColor: Colors.transparent,
10 | isScrollControlled: true,
11 | builder: (BuildContext context) {
12 | return Column(
13 | mainAxisSize: MainAxisSize.min,
14 | crossAxisAlignment: CrossAxisAlignment.end,
15 | children: [
16 | Container(
17 | height: 36,
18 | ),
19 | SizedBox(
20 | height: (56 * 6).toDouble(),
21 | child: Container(
22 | decoration: const BoxDecoration(
23 | borderRadius: BorderRadius.only(
24 | topLeft: Radius.circular(16.0),
25 | topRight: Radius.circular(16.0),
26 | ),
27 | color: bgColor,
28 | ),
29 | child: Stack(
30 | alignment: const Alignment(0, 0),
31 | children: [
32 | Positioned(
33 | child: ListView.builder(
34 | itemCount: canali.length,
35 | physics: const ClampingScrollPhysics(),
36 | itemBuilder: (contextChild, index) {
37 | return ListTile(
38 | title: Text(
39 | canali[index].trim(),
40 | style: const TextStyle(color: Colors.white),
41 | ),
42 | leading: const Icon(
43 | Icons.mail_outline,
44 | color: Colors.white,
45 | ),
46 | onTap: () async {
47 | if (links[index] != null) {
48 | List names =
49 | await getEntriesFrom("${links[index]}");
50 | /*Navigator.of(context).push(
51 | MaterialPageRoute(
52 | builder: (context) => VideoPlayerWidget(
53 | link: "https:${links[index]!}"),
54 | ),
55 | );*/
56 | //todo: link to player
57 | } else {
58 | ScaffoldMessenger.of(context).showSnackBar(
59 | const SnackBar(
60 | content: Text(
61 | "Questo link non è disponibile."),
62 | ),
63 | );
64 | }
65 | },
66 | );
67 | },
68 | ),
69 | )
70 | ],
71 | ))),
72 | ],
73 | );
74 | });
75 | }
76 |
77 | /*
78 |
79 |
80 | ListTile(
81 | title: const Text(
82 | "Drafts",
83 | style: TextStyle(color: Colors.white),
84 | ),
85 | leading: const Icon(
86 | Icons.mail_outline,
87 | color: Colors.white,
88 | ),
89 | onTap: () {},
90 | ),
91 |
92 |
93 |
94 | */
95 |
--------------------------------------------------------------------------------
/lib/widget/film_field.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_tv/pages/film/film_details.dart';
3 |
4 | import '../commons/vars.dart';
5 |
6 | class BuildMovie extends StatelessWidget {
7 | final int index;
8 | final List channelList;
9 | const BuildMovie({Key? key, required this.index, required this.channelList})
10 | : super(key: key);
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Padding(
15 | padding: const EdgeInsets.all(10),
16 | child: ListTile(
17 | shape: const RoundedRectangleBorder(
18 | borderRadius: BorderRadius.all(
19 | Radius.circular(10),
20 | ),
21 | ),
22 | onTap: () async {
23 | Navigator.push(
24 | context,
25 | MaterialPageRoute(
26 | builder: (context) => MoviePage(channelList[index]),
27 | ),
28 | );
29 | },
30 | leading: Container(
31 | width: 60,
32 | height: 60,
33 | margin: const EdgeInsets.only(right: 15),
34 | decoration: BoxDecoration(
35 | borderRadius: BorderRadius.circular(60),
36 | border: Border.all(width: 3, color: secondary),
37 | image: DecorationImage(
38 | image: NetworkImage(channelList[index].posterPath),
39 | fit: BoxFit.fill),
40 | ),
41 | ),
42 | tileColor: Colors.white,
43 | title: Text(
44 | channelList[index].title,
45 | style: const TextStyle(
46 | color: primary, fontWeight: FontWeight.bold, fontSize: 18),
47 | ),
48 | subtitle: RichText(
49 | text: TextSpan(
50 | children: [
51 | const WidgetSpan(
52 | child: Icon(
53 | Icons.tag,
54 | size: 14,
55 | color: Colors.black,
56 | ),
57 | ),
58 | TextSpan(
59 | text: " ${channelList[index].releaseDate}",
60 | style: const TextStyle(color: Colors.black),
61 | ),
62 | ],
63 | ),
64 | ),
65 | ),
66 | );
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/lib/widget/home_field.dart:
--------------------------------------------------------------------------------
1 | import 'package:bot_toast/bot_toast.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_tv/pages/film/film_view.dart';
4 | import 'package:flutter_tv/pages/serie/series_view.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 |
7 | import '../commons/vars.dart';
8 |
9 | class BuildList extends StatelessWidget {
10 | final int index;
11 | final List