├── ios
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
└── .gitignore
├── images
├── logo.png
└── app_logo.jpg
├── android
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── ic_launcher-playstore.png
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_round.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_round.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_round.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_round.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_round.png
│ │ │ │ │ └── ic_launcher_foreground.png
│ │ │ │ ├── values
│ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ └── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── alamedapps
│ │ │ │ │ └── flowpdc_app
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
└── build.gradle
├── lib
├── app
│ ├── shared
│ │ ├── utils
│ │ │ └── constants.dart
│ │ ├── repositories
│ │ │ ├── localstorage
│ │ │ │ ├── local_storage_interface.dart
│ │ │ │ └── local_storage_shared_prefs.dart
│ │ │ └── podcast_repository.dart
│ │ └── models
│ │ │ └── podcast.dart
│ ├── status
│ │ └── status_podcast.dart
│ ├── widgets
│ │ ├── podcast_card
│ │ │ ├── podcast_card_controller.dart
│ │ │ ├── podcast_card_controller.g.dart
│ │ │ └── podcast_card_widget.dart
│ │ ├── player
│ │ │ ├── player_controller.dart
│ │ │ ├── player_controller.g.dart
│ │ │ ├── position_seek_widget.dart
│ │ │ └── player_widget.dart
│ │ ├── podcast_thumbnail.dart
│ │ └── podcast_description_dialog.dart
│ ├── app_controller.dart
│ ├── pages
│ │ └── podcast_selected
│ │ │ ├── podcast_selected_controller.dart
│ │ │ ├── podcast_selected_page.dart
│ │ │ └── podcast_selected_controller.g.dart
│ ├── app_widget.dart
│ ├── modules
│ │ └── home
│ │ │ ├── home_module.dart
│ │ │ ├── home_controller.dart
│ │ │ ├── home_controller.g.dart
│ │ │ └── home_page.dart
│ ├── app_module.dart
│ └── app_controller.g.dart
└── main.dart
├── README.md
├── test
└── app
│ ├── widgets
│ ├── player
│ │ ├── player_widget_test.dart
│ │ └── player_controller_test.dart
│ └── podcast_card
│ │ ├── podcast_card_widget_test.dart
│ │ └── podcast_card_controller_test.dart
│ ├── modules
│ └── home
│ │ ├── home_page_test.dart
│ │ └── home_controller_test.dart
│ ├── pages
│ └── podcast_selected
│ │ ├── podcast_selected_page_test.dart
│ │ └── podcast_selected_controller_test.dart
│ └── app_controller_test.dart
├── .metadata
├── .gitignore
├── pubspec.yaml
└── pubspec.lock
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/images/logo.png
--------------------------------------------------------------------------------
/images/app_logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/images/app_logo.jpg
--------------------------------------------------------------------------------
/android/app/src/main/ic_launcher-playstore.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/ic_launcher-playstore.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/app/shared/utils/constants.dart:
--------------------------------------------------------------------------------
1 | // ignore: non_constant_identifier_names
2 | final String FLOWPDC_API =
3 | 'https://flow3r-api-master-2eqj3fl3la-ue.a.run.app/v2/';
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #000000
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flow Podcast mobile app
2 |
3 | _*Removed from PlayStore_ 😢
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 | android.enableR8=true
5 | android.bundle.enableUncompressedNativeLibs=false
6 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joaoGabriel55/flow-podcast-mobile-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/alamedapps/flowpdc_app/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.alamedapps.flowpdc_app
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flowpdc_app/app/app_module.dart';
3 | import 'package:flutter_modular/flutter_modular.dart';
4 |
5 | void main() => runApp(ModularApp(module: AppModule()));
6 |
--------------------------------------------------------------------------------
/lib/app/shared/repositories/localstorage/local_storage_interface.dart:
--------------------------------------------------------------------------------
1 | abstract class ILocalStorage {
2 | Future> get(String value);
3 | Future put(String key, List value);
4 | Future delete(String key);
5 | }
6 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/app/status/status_podcast.dart:
--------------------------------------------------------------------------------
1 | enum StatusPodcast { ERROR, SUCCESS, LOADING, INITIAL }
2 |
3 | extension StatusPodcastExt on StatusPodcast {
4 | static String _mensagem;
5 | String get getMensagem => _mensagem;
6 | set setMensagem(String value) => _mensagem = value;
7 | }
8 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test/app/widgets/player/player_widget_test.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | void main() {
4 | // testWidgets('PlayerWidget has message', (tester) async {
5 | // await tester.pumpWidget(buildTestableWidget(PlayerWidget()));
6 | // final textFinder = find.text('Player');
7 | // expect(textFinder, findsOneWidget);
8 | // });
9 | }
10 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/test/app/widgets/podcast_card/podcast_card_widget_test.dart:
--------------------------------------------------------------------------------
1 |
2 |
3 | void main() {
4 | // testWidgets('PodcastCardWidget has message', (tester) async {
5 | // await tester.pumpWidget(buildTestableWidget(PodcastCardWidget()));
6 | // final textFinder = find.text('PodcastCard');
7 | // expect(textFinder, findsOneWidget);
8 | // });
9 | }
10 |
--------------------------------------------------------------------------------
/.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 and should not be manually edited.
5 |
6 | version:
7 | revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/test/app/modules/home/home_page_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 |
3 | void main() {
4 | testWidgets('HomePage has title', (tester) async {
5 | // await tester.pumpWidget(buildTestableWidget(HomePage(title: 'Home')));
6 | // final titleFinder = find.text('Home');
7 | // expect(titleFinder, findsOneWidget);
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/app/widgets/podcast_card/podcast_card_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:mobx/mobx.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 |
4 | part 'podcast_card_controller.g.dart';
5 |
6 | @Injectable()
7 | class PodcastCardController = _PodcastCardControllerBase
8 | with _$PodcastCardController;
9 |
10 | abstract class _PodcastCardControllerBase with Store {
11 | }
12 |
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/lib/app/app_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:mobx/mobx.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 |
4 | part 'app_controller.g.dart';
5 |
6 | @Injectable()
7 | class AppController = _AppControllerBase with _$AppController;
8 |
9 | abstract class _AppControllerBase with Store {
10 | @observable
11 | int value = 0;
12 |
13 | @action
14 | void increment() {
15 | value++;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/test/app/pages/podcast_selected/podcast_selected_page_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 |
3 | void main() {
4 | testWidgets('PodcastSelectedPage has title', (tester) async {
5 | // await tester.pumpWidget(buildTestableWidget(PodcastSelectedPage(title: 'PodcastSelected')));
6 | // final titleFinder = find.text('PodcastSelected');
7 | // expect(titleFinder, findsOneWidget);
8 | });
9 | }
10 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/app/pages/podcast_selected/podcast_selected_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:mobx/mobx.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 |
4 | part 'podcast_selected_controller.g.dart';
5 |
6 | @Injectable()
7 | class PodcastSelectedController = _PodcastSelectedControllerBase
8 | with _$PodcastSelectedController;
9 |
10 | abstract class _PodcastSelectedControllerBase with Store {
11 | @observable
12 | int value = 0;
13 |
14 | @action
15 | void increment() {
16 | value++;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/app/widgets/player/player_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_modular/flutter_modular.dart';
2 | import 'package:mobx/mobx.dart';
3 |
4 | part 'player_controller.g.dart';
5 |
6 | @Injectable()
7 | class PlayerController = _PlayerControllerBase with _$PlayerController;
8 |
9 | abstract class _PlayerControllerBase with Store {
10 | @observable
11 | bool isPlaying;
12 |
13 | @observable
14 | ObservableFuture audioDuration;
15 |
16 | @observable
17 | ObservableFuture audioCurrentTime;
18 |
19 | _PlayerControllerBase() {
20 | this.isPlaying = true;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/lib/app/app_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 |
4 | class AppWidget extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return MaterialApp(
8 | navigatorKey: Modular.navigatorKey,
9 | title: 'Flow Pdc',
10 | debugShowCheckedModeBanner: false,
11 | theme: ThemeData(
12 | primaryColor: Colors.black,
13 | accentColor: Colors.orangeAccent
14 | ),
15 | initialRoute: '/',
16 | onGenerateRoute: Modular.generateRoute,
17 | );
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/lib/app/modules/home/home_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flowpdc_app/app/shared/repositories/podcast_repository.dart';
3 | import 'package:flutter_modular/flutter_modular.dart';
4 |
5 | import 'home_controller.dart';
6 | import 'home_page.dart';
7 |
8 | class HomeModule extends ChildModule {
9 | @override
10 | List get binds => [
11 | $HomeController,
12 | Bind((i) => PodcastRepository(i.get())),
13 | ];
14 |
15 | @override
16 | List get routers => [
17 | ModularRouter(Modular.initialRoute, child: (_, args) => HomePage()),
18 | ];
19 |
20 | static Inject get to => Inject.of();
21 | }
22 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
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 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/test/app/app_controller_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/app_module.dart';
2 | import 'package:flutter_modular/flutter_modular_test.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | initModule(AppModule());
7 | // AppController app;
8 | //
9 | setUp(() {
10 | // app = AppModule.to.get();
11 | });
12 |
13 | group('AppController Test', () {
14 | // test("First Test", () {
15 | // expect(app, isInstanceOf());
16 | // });
17 |
18 | // test("Set Value", () {
19 | // expect(app.value, equals(0));
20 | // app.increment();
21 | // expect(app.value, equals(1));
22 | // });
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/test/app/modules/home/home_controller_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/modules/home/home_module.dart';
2 | import 'package:flutter_modular/flutter_modular_test.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | initModule(HomeModule());
7 | // HomeController home;
8 | //
9 | setUp(() {
10 | // home = HomeModule.to.get();
11 | });
12 |
13 | group('HomeController Test', () {
14 | // test("First Test", () {
15 | // expect(home, isInstanceOf());
16 | // });
17 |
18 | // test("Set Value", () {
19 | // expect(home.value, equals(0));
20 | // home.increment();
21 | // expect(home.value, equals(1));
22 | // });
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/test/app/widgets/player/player_controller_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/app_module.dart';
2 | import 'package:flutter_modular/flutter_modular_test.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | initModule(AppModule());
7 | // PlayerController player;
8 | //
9 | setUp(() {
10 | // player = AppModule.to.get();
11 | });
12 |
13 | group('PlayerController Test', () {
14 | // test("First Test", () {
15 | // expect(player, isInstanceOf());
16 | // });
17 |
18 | // test("Set Value", () {
19 | // expect(player.value, equals(0));
20 | // player.increment();
21 | // expect(player.value, equals(1));
22 | // });
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/test/app/widgets/podcast_card/podcast_card_controller_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/app_module.dart';
2 | import 'package:flutter_modular/flutter_modular_test.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | initModule(AppModule());
7 | // PodcastCardController podcastcard;
8 | //
9 | setUp(() {
10 | // podcastcard = AppModule.to.get();
11 | });
12 |
13 | group('PodcastCardController Test', () {
14 | // test("First Test", () {
15 | // expect(podcastcard, isInstanceOf());
16 | // });
17 |
18 | // test("Set Value", () {
19 | // expect(podcastcard.value, equals(0));
20 | // podcastcard.increment();
21 | // expect(podcastcard.value, equals(1));
22 | // });
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Slidy History Files
2 | .slidy/
3 |
4 | # Miscellaneous
5 | *.class
6 | *.log
7 | *.pyc
8 | *.swp
9 | .DS_Store
10 | .atom/
11 | .buildlog/
12 | .history
13 | .svn/
14 |
15 | # IntelliJ related
16 | *.iml
17 | *.ipr
18 | *.iws
19 | .idea/
20 |
21 | # The .vscode folder contains launch configuration and tasks you configure in
22 | # VS Code which you may wish to be included in version control, so this line
23 | # is commented out by default.
24 | #.vscode/
25 |
26 | # Flutter/Dart/Pub related
27 | **/doc/api/
28 | **/ios/Flutter/.last_build_id
29 | .dart_tool/
30 | .flutter-plugins
31 | .flutter-plugins-dependencies
32 | .packages
33 | .pub-cache/
34 | .pub/
35 | /build/
36 |
37 | # Web related
38 | lib/generated_plugin_registrant.dart
39 |
40 | # Symbolication related
41 | app.*.symbols
42 |
43 | # Obfuscation related
44 | app.*.map.json
--------------------------------------------------------------------------------
/lib/app/shared/models/podcast.dart:
--------------------------------------------------------------------------------
1 | class Podcast {
2 | final String id;
3 | final String title;
4 | final String description;
5 | final String thumbnailUrl;
6 | final String audioUrl;
7 | bool isFavorite;
8 |
9 | Podcast._builder(PodcastBuilder builder)
10 | : id = builder.id,
11 | title = builder.title,
12 | description = builder.description,
13 | thumbnailUrl = builder.thumbnailUrl,
14 | audioUrl = builder.audioUrl,
15 | isFavorite = builder.isFavorite;
16 | }
17 |
18 | class PodcastBuilder {
19 | final String id;
20 | final String title;
21 | final bool isFavorite;
22 |
23 | PodcastBuilder(this.id, this.title, this.isFavorite);
24 |
25 | String description;
26 | String thumbnailUrl;
27 | String audioUrl;
28 |
29 | Podcast build() {
30 | return Podcast._builder(this);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/app/pages/podcast_selected/podcast_selected_controller_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/app_module.dart';
2 | import 'package:flutter_modular/flutter_modular_test.dart';
3 | import 'package:flutter_test/flutter_test.dart';
4 |
5 | void main() {
6 | initModule(AppModule());
7 | // PodcastSelectedController podcastselected;
8 | //
9 | setUp(() {
10 | // podcastselected = AppModule.to.get();
11 | });
12 |
13 | group('PodcastSelectedController Test', () {
14 | // test("First Test", () {
15 | // expect(podcastselected, isInstanceOf());
16 | // });
17 |
18 | // test("Set Value", () {
19 | // expect(podcastselected.value, equals(0));
20 | // podcastselected.increment();
21 | // expect(podcastselected.value, equals(1));
22 | // });
23 | });
24 | }
25 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/app/pages/podcast_selected/podcast_selected_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_modular/flutter_modular.dart';
3 | import 'podcast_selected_controller.dart';
4 |
5 | class PodcastSelectedPage extends StatefulWidget {
6 | final String title;
7 | const PodcastSelectedPage({Key key, this.title = "PodcastSelected"})
8 | : super(key: key);
9 |
10 | @override
11 | _PodcastSelectedPageState createState() => _PodcastSelectedPageState();
12 | }
13 |
14 | class _PodcastSelectedPageState
15 | extends ModularState {
16 | //use 'controller' variable to access controller
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Scaffold(
21 | appBar: AppBar(
22 | title: Text(widget.title),
23 | ),
24 | body: Column(
25 | children: [],
26 | ),
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/app/widgets/podcast_thumbnail.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PodcastThumbnail extends StatelessWidget {
4 | final String url;
5 |
6 | const PodcastThumbnail({Key key, this.url}) : super(key: key);
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Image.network(
11 | this.url,
12 | width: 80,
13 | fit: BoxFit.fill,
14 | loadingBuilder: (BuildContext context, Widget child,
15 | ImageChunkEvent loadingProgress) {
16 | if (loadingProgress == null) return child;
17 | return Container(
18 | margin: EdgeInsets.all(22),
19 | child: CircularProgressIndicator(
20 | value: loadingProgress.expectedTotalBytes != null
21 | ? loadingProgress.cumulativeBytesLoaded /
22 | loadingProgress.expectedTotalBytes
23 | : null,
24 | ),
25 | );
26 | },
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/app/shared/repositories/localstorage/local_storage_shared_prefs.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:shared_preferences/shared_preferences.dart';
4 |
5 | import 'local_storage_interface.dart';
6 |
7 | class LocalStorageSharedPrefs implements ILocalStorage {
8 | Completer _instance = Completer();
9 |
10 | _init() async {
11 | _instance.complete(await SharedPreferences.getInstance());
12 | }
13 |
14 | LocalStorageSharedPrefs() {
15 | _init();
16 | }
17 |
18 | @override
19 | Future delete(String key) async {
20 | var shared = await _instance.future;
21 | shared.remove(key);
22 | }
23 |
24 | @override
25 | Future> get(String value) async {
26 | var shared = await _instance.future;
27 | return shared.getStringList(value);
28 | }
29 |
30 | @override
31 | Future put(String key, List value) async {
32 | var shared = await _instance.future;
33 | shared.setStringList(key, value);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/lib/app/widgets/podcast_card/podcast_card_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'podcast_card_controller.dart';
4 |
5 | // **************************************************************************
6 | // InjectionGenerator
7 | // **************************************************************************
8 |
9 | final $PodcastCardController = BindInject(
10 | (i) => PodcastCardController(),
11 | singleton: true,
12 | lazy: true,
13 | );
14 |
15 | // **************************************************************************
16 | // StoreGenerator
17 | // **************************************************************************
18 |
19 | // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
20 |
21 | mixin _$PodcastCardController on _PodcastCardControllerBase, Store {
22 | @override
23 | String toString() {
24 | return '''
25 |
26 | ''';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/app/app_module.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flowpdc_app/app/shared/repositories/localstorage/local_storage_interface.dart';
3 | import 'package:flowpdc_app/app/shared/repositories/localstorage/local_storage_shared_prefs.dart';
4 | import 'package:flowpdc_app/app/shared/utils/constants.dart';
5 |
6 | import 'widgets/podcast_card/podcast_card_controller.dart';
7 | import 'widgets/player/player_controller.dart';
8 | import 'pages/podcast_selected/podcast_selected_controller.dart';
9 | import 'app_controller.dart';
10 | import 'package:flutter_modular/flutter_modular.dart';
11 | import 'package:flutter/material.dart';
12 | import 'package:flowpdc_app/app/app_widget.dart';
13 | import 'package:flowpdc_app/app/modules/home/home_module.dart';
14 |
15 | class AppModule extends MainModule {
16 | @override
17 | List get binds => [
18 | $PodcastCardController,
19 | $PlayerController,
20 | $PodcastSelectedController,
21 | $AppController,
22 | Bind((i) => LocalStorageSharedPrefs()),
23 | Bind((i) => Dio(BaseOptions(baseUrl: FLOWPDC_API)))
24 | ];
25 |
26 | @override
27 | List get routers => [
28 | ModularRouter(Modular.initialRoute, module: HomeModule()),
29 | ];
30 |
31 | @override
32 | Widget get bootstrap => AppWidget();
33 |
34 | static Inject get to => Inject.of();
35 | }
36 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/app/app_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'app_controller.dart';
4 |
5 | // **************************************************************************
6 | // InjectionGenerator
7 | // **************************************************************************
8 |
9 | final $AppController = BindInject(
10 | (i) => AppController(),
11 | singleton: true,
12 | lazy: true,
13 | );
14 |
15 | // **************************************************************************
16 | // StoreGenerator
17 | // **************************************************************************
18 |
19 | // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
20 |
21 | mixin _$AppController on _AppControllerBase, Store {
22 | final _$valueAtom = Atom(name: '_AppControllerBase.value');
23 |
24 | @override
25 | int get value {
26 | _$valueAtom.reportRead();
27 | return super.value;
28 | }
29 |
30 | @override
31 | set value(int value) {
32 | _$valueAtom.reportWrite(value, super.value, () {
33 | super.value = value;
34 | });
35 | }
36 |
37 | final _$_AppControllerBaseActionController =
38 | ActionController(name: '_AppControllerBase');
39 |
40 | @override
41 | void increment() {
42 | final _$actionInfo = _$_AppControllerBaseActionController.startAction(
43 | name: '_AppControllerBase.increment');
44 | try {
45 | return super.increment();
46 | } finally {
47 | _$_AppControllerBaseActionController.endAction(_$actionInfo);
48 | }
49 | }
50 |
51 | @override
52 | String toString() {
53 | return '''
54 | value: ${value}
55 | ''';
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lib/app/pages/podcast_selected/podcast_selected_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'podcast_selected_controller.dart';
4 |
5 | // **************************************************************************
6 | // InjectionGenerator
7 | // **************************************************************************
8 |
9 | final $PodcastSelectedController = BindInject(
10 | (i) => PodcastSelectedController(),
11 | singleton: true,
12 | lazy: true,
13 | );
14 |
15 | // **************************************************************************
16 | // StoreGenerator
17 | // **************************************************************************
18 |
19 | // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
20 |
21 | mixin _$PodcastSelectedController on _PodcastSelectedControllerBase, Store {
22 | final _$valueAtom = Atom(name: '_PodcastSelectedControllerBase.value');
23 |
24 | @override
25 | int get value {
26 | _$valueAtom.reportRead();
27 | return super.value;
28 | }
29 |
30 | @override
31 | set value(int value) {
32 | _$valueAtom.reportWrite(value, super.value, () {
33 | super.value = value;
34 | });
35 | }
36 |
37 | final _$_PodcastSelectedControllerBaseActionController =
38 | ActionController(name: '_PodcastSelectedControllerBase');
39 |
40 | @override
41 | void increment() {
42 | final _$actionInfo = _$_PodcastSelectedControllerBaseActionController
43 | .startAction(name: '_PodcastSelectedControllerBase.increment');
44 | try {
45 | return super.increment();
46 | } finally {
47 | _$_PodcastSelectedControllerBaseActionController.endAction(_$actionInfo);
48 | }
49 | }
50 |
51 | @override
52 | String toString() {
53 | return '''
54 | value: ${value}
55 | ''';
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | Flow Podcast
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 | NSAppTransportSecurity
45 |
46 | NSAllowsArbitraryLoads
47 |
48 |
49 | UIBackgroundModes
50 |
51 | audio
52 | fetch
53 |
54 | com.apple.security.network.client
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/lib/app/widgets/player/player_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'player_controller.dart';
4 |
5 | // **************************************************************************
6 | // InjectionGenerator
7 | // **************************************************************************
8 |
9 | final $PlayerController = BindInject(
10 | (i) => PlayerController(),
11 | singleton: true,
12 | lazy: true,
13 | );
14 |
15 | // **************************************************************************
16 | // StoreGenerator
17 | // **************************************************************************
18 |
19 | // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
20 |
21 | mixin _$PlayerController on _PlayerControllerBase, Store {
22 | final _$isPlayingAtom = Atom(name: '_PlayerControllerBase.isPlaying');
23 |
24 | @override
25 | bool get isPlaying {
26 | _$isPlayingAtom.reportRead();
27 | return super.isPlaying;
28 | }
29 |
30 | @override
31 | set isPlaying(bool value) {
32 | _$isPlayingAtom.reportWrite(value, super.isPlaying, () {
33 | super.isPlaying = value;
34 | });
35 | }
36 |
37 | final _$audioDurationAtom = Atom(name: '_PlayerControllerBase.audioDuration');
38 |
39 | @override
40 | ObservableFuture get audioDuration {
41 | _$audioDurationAtom.reportRead();
42 | return super.audioDuration;
43 | }
44 |
45 | @override
46 | set audioDuration(ObservableFuture value) {
47 | _$audioDurationAtom.reportWrite(value, super.audioDuration, () {
48 | super.audioDuration = value;
49 | });
50 | }
51 |
52 | final _$audioCurrentTimeAtom =
53 | Atom(name: '_PlayerControllerBase.audioCurrentTime');
54 |
55 | @override
56 | ObservableFuture get audioCurrentTime {
57 | _$audioCurrentTimeAtom.reportRead();
58 | return super.audioCurrentTime;
59 | }
60 |
61 | @override
62 | set audioCurrentTime(ObservableFuture value) {
63 | _$audioCurrentTimeAtom.reportWrite(value, super.audioCurrentTime, () {
64 | super.audioCurrentTime = value;
65 | });
66 | }
67 |
68 | @override
69 | String toString() {
70 | return '''
71 | isPlaying: ${isPlaying},
72 | audioDuration: ${audioDuration},
73 | audioCurrentTime: ${audioCurrentTime}
74 | ''';
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/app/shared/repositories/podcast_repository.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart';
2 | import 'package:flowpdc_app/app/shared/models/podcast.dart';
3 |
4 | class PodcastResponse {
5 | String next;
6 | Map podcastMap;
7 |
8 | PodcastResponse(String next, Map podcastMap) {
9 | this.next = next;
10 | this.podcastMap = podcastMap;
11 | }
12 | }
13 |
14 | class PodcastRepository {
15 | final Dio dio;
16 |
17 | PodcastRepository(this.dio);
18 |
19 | Future getAllPodcasts() async {
20 | try {
21 | var pagingParams = {
22 | "params": {"filter": "episodes"}
23 | };
24 | return await _loadPodcasts(pagingParams);
25 | } catch (e) {
26 | throw Exception(e.toString());
27 | }
28 | }
29 |
30 | Future loadMorePodcasts(String nextPaging) async {
31 | try {
32 | var pagingParams = {
33 | "params": {
34 | "filter": "episodes",
35 | "paging": {"next": nextPaging, "previous": null}
36 | }
37 | };
38 | PodcastResponse result = await _loadPodcasts(pagingParams);
39 | return result;
40 | } catch (e) {
41 | throw Exception(e.toString());
42 | }
43 | }
44 |
45 | Future _loadPodcasts(pagingParams) async {
46 | try {
47 | var response = await dio.post("episodes/list", data: pagingParams);
48 | Map podcastMap = {};
49 | for (var json in (response.data['episodes'] as List)) {
50 | Podcast podcast = (PodcastBuilder(json['id'], json['title'], false)
51 | ..description = json['description']
52 | ..thumbnailUrl = json['artwork']
53 | ..audioUrl = json['mp3'])
54 | .build();
55 | podcastMap[podcast.id] = podcast;
56 | }
57 | String nextParameter = response.data["paging"]["next"];
58 | PodcastResponse result = PodcastResponse(nextParameter, podcastMap);
59 | return result;
60 | } catch (e) {
61 | throw Exception(e.toString());
62 | }
63 | }
64 |
65 | Future getPodcast(String id) async {
66 | try {
67 | var response = await dio.get("episodes/view/$id");
68 | var episode = response.data['episode'];
69 | Podcast podcast = (PodcastBuilder(episode['id'], episode['title'], false)
70 | ..description = episode['description']
71 | ..thumbnailUrl = episode['artwork']
72 | ..audioUrl = episode['mp3'])
73 | .build();
74 |
75 | return podcast;
76 | } catch (e) {
77 | throw Exception(e.toString());
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/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 | def keystoreProperties = new Properties()
29 | def keystorePropertiesFile = rootProject.file('key.properties')
30 | if (keystorePropertiesFile.exists()) {
31 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
32 | }
33 |
34 | android {
35 | compileSdkVersion 29
36 |
37 | sourceSets {
38 | main.java.srcDirs += 'src/main/kotlin'
39 | }
40 |
41 | lintOptions {
42 | disable 'InvalidPackage'
43 | }
44 |
45 | defaultConfig {
46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
47 | applicationId "com.alamedapps.flowpdc_app"
48 | minSdkVersion 16
49 | targetSdkVersion 29
50 | versionCode flutterVersionCode.toInteger()
51 | versionName flutterVersionName
52 | }
53 |
54 | signingConfigs {
55 | release {
56 | storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
57 | keyAlias keystoreProperties['keyAlias']
58 | keyPassword keystoreProperties['keyPassword']
59 | storePassword keystoreProperties['storePassword']
60 | }
61 | }
62 |
63 | buildTypes {
64 | release {
65 | // TODO: Add your own signing config for the release build.
66 | // Signing with the debug keys for now, so `flutter run --release` works.
67 | signingConfig signingConfigs.release
68 | }
69 | }
70 | }
71 |
72 | flutter {
73 | source '../..'
74 | }
75 |
76 | dependencies {
77 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
78 | }
79 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
28 |
33 |
37 |
38 |
39 |
40 |
41 |
42 |
44 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/lib/app/widgets/podcast_description_dialog.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/widgets/podcast_thumbnail.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class PodcastDescriptionDialog extends StatefulWidget {
5 | final String title;
6 | final String description;
7 | final String thumbnail;
8 |
9 | const PodcastDescriptionDialog({
10 | Key key,
11 | this.title,
12 | this.description,
13 | this.thumbnail,
14 | }) : super(key: key);
15 |
16 | @override
17 | _PodcastDescriptionDialogState createState() =>
18 | _PodcastDescriptionDialogState();
19 | }
20 |
21 | class _PodcastDescriptionDialogState extends State {
22 | @override
23 | Widget build(BuildContext context) {
24 | return Dialog(
25 | shape: RoundedRectangleBorder(
26 | borderRadius: BorderRadius.circular(8),
27 | ),
28 | elevation: 0,
29 | backgroundColor: Colors.transparent,
30 | child: contentBox(context),
31 | );
32 | }
33 |
34 | contentBox(context) {
35 | return Stack(
36 | children: [
37 | Container(
38 | padding: EdgeInsets.only(left: 18, top: 28, right: 18, bottom: 18),
39 | margin: EdgeInsets.only(top: 8),
40 | decoration: BoxDecoration(
41 | shape: BoxShape.rectangle,
42 | color: Colors.black,
43 | borderRadius: BorderRadius.circular(8),
44 | border: Border.all(
45 | color: Theme.of(context).accentColor
46 | ),
47 | boxShadow: [
48 | BoxShadow(
49 | color: Colors.black, offset: Offset(0, 10), blurRadius: 10),
50 | ],
51 | ),
52 | child: Column(
53 | mainAxisSize: MainAxisSize.min,
54 | children: [
55 | Container(
56 | padding: EdgeInsets.only(left: 78),
57 | child: Text(
58 | widget.title,
59 | style: TextStyle(
60 | fontSize: 18,
61 | fontWeight: FontWeight.w600,
62 | color: Colors.white,
63 | ),
64 | ),
65 | ),
66 | SizedBox(
67 | height: 15,
68 | ),
69 | Text(
70 | widget.description,
71 | style: TextStyle(
72 | fontSize: 14,
73 | color: Colors.white,
74 | ),
75 | ),
76 | ],
77 | ),
78 | ),
79 | Container(
80 | padding: EdgeInsets.only(left: 8),
81 | child: widget.thumbnail != null
82 | ? PodcastThumbnail(url: this.widget.thumbnail)
83 | : Container(
84 | width: 80,
85 | child: Icon(
86 | Icons.audiotrack,
87 | color: Theme.of(context).accentColor,
88 | size: 48,
89 | ),
90 | ),
91 | )
92 | ],
93 | );
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/lib/app/widgets/podcast_card/podcast_card_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import '../podcast_thumbnail.dart';
4 |
5 | class PodcastCard extends StatefulWidget {
6 | final String thumbnail;
7 | final String title;
8 | final bool isFavorite;
9 | final Function addFavorite;
10 |
11 | const PodcastCard({
12 | Key key,
13 | this.title,
14 | this.thumbnail,
15 | this.addFavorite,
16 | this.isFavorite,
17 | }) : super(key: key);
18 | @override
19 | _PodcastCard createState() => new _PodcastCard();
20 | }
21 |
22 | class _PodcastCard extends State {
23 | @override
24 | Widget build(BuildContext context) {
25 | return Card(
26 | color: Color.fromARGB(255, 27, 27, 27),
27 | shape: RoundedRectangleBorder(
28 | borderRadius: BorderRadius.circular(10.0),
29 | side: BorderSide(
30 | color: Color.fromARGB(100, 255, 184, 0),
31 | width: 0.8,
32 | ),
33 | ),
34 | margin: EdgeInsets.only(top: 8, left: 18, right: 18, bottom: 8),
35 | child: Container(
36 | margin: EdgeInsets.all(14),
37 | child: Row(
38 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
39 | children: [
40 | widget.thumbnail != null
41 | ? PodcastThumbnail(url: this.widget.thumbnail)
42 | : Container(
43 | width: 80,
44 | child: Icon(
45 | Icons.audiotrack,
46 | color: Theme.of(context).accentColor,
47 | size: 48,
48 | ),
49 | ),
50 | Expanded(
51 | child: Container(
52 | margin: EdgeInsets.only(left: 18),
53 | child: Column(
54 | mainAxisAlignment: MainAxisAlignment.start,
55 | crossAxisAlignment: CrossAxisAlignment.start,
56 | children: [
57 | Container(
58 | padding: EdgeInsets.only(top: 8),
59 | width: MediaQuery.of(context).size.width * 0.5,
60 | child: Text(
61 | widget.title,
62 | overflow: TextOverflow.fade,
63 | style: TextStyle(
64 | color: Colors.white,
65 | fontSize: 18,
66 | fontWeight: FontWeight.w700,
67 | ),
68 | ),
69 | ),
70 | ],
71 | ),
72 | ),
73 | ),
74 | Container(
75 | margin: EdgeInsets.all(8),
76 | child: IconButton(
77 | icon: Icon(
78 | this.widget.isFavorite
79 | ? Icons.favorite
80 | : Icons.favorite_border,
81 | color: Theme.of(context).accentColor,
82 | size: 28,
83 | ),
84 | onPressed: this.widget.addFavorite,
85 | ),
86 | )
87 | ],
88 | ),
89 | ),
90 | );
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/lib/app/widgets/player/position_seek_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class PositionSeekWidget extends StatefulWidget {
4 | final Duration currentPosition;
5 | final Duration duration;
6 | final Function(Duration) seekTo;
7 |
8 | const PositionSeekWidget({
9 | @required this.currentPosition,
10 | @required this.duration,
11 | @required this.seekTo,
12 | });
13 |
14 | @override
15 | _PositionSeekWidgetState createState() => _PositionSeekWidgetState();
16 | }
17 |
18 | class _PositionSeekWidgetState extends State {
19 | Duration _visibleValue;
20 | bool listenOnlyUserInterraction = false;
21 | double get percent => widget.duration.inMilliseconds == 0
22 | ? 0
23 | : _visibleValue.inMilliseconds / widget.duration.inMilliseconds;
24 |
25 | @override
26 | void initState() {
27 | super.initState();
28 | _visibleValue = widget.currentPosition;
29 | }
30 |
31 | @override
32 | void didUpdateWidget(PositionSeekWidget oldWidget) {
33 | super.didUpdateWidget(oldWidget);
34 | if (!listenOnlyUserInterraction) {
35 | _visibleValue = widget.currentPosition;
36 | }
37 | }
38 |
39 | @override
40 | Widget build(BuildContext context) {
41 | return Row(
42 | mainAxisAlignment: MainAxisAlignment.center,
43 | children: [
44 | Expanded(
45 | child: SliderTheme(
46 | data: SliderThemeData(
47 | thumbColor: Colors.green,
48 | trackHeight: 2.0,
49 | thumbShape: RoundSliderThumbShape(enabledThumbRadius: 6),
50 | ),
51 | child: Slider(
52 | min: 0,
53 | max: widget.duration.inMilliseconds.toDouble(),
54 | value: percent * widget.duration.inMilliseconds.toDouble(),
55 | activeColor: Theme.of(context).accentColor,
56 | onChangeEnd: (newValue) {
57 | setState(() {
58 | listenOnlyUserInterraction = false;
59 | widget.seekTo(_visibleValue);
60 | });
61 | },
62 | onChangeStart: (_) {
63 | setState(() {
64 | listenOnlyUserInterraction = true;
65 | });
66 | },
67 | onChanged: (newValue) {
68 | setState(() {
69 | final to = Duration(milliseconds: newValue.floor());
70 | _visibleValue = to;
71 | });
72 | },
73 | ),
74 | ),
75 | ),
76 | Text(
77 | durationToString(widget.currentPosition) +
78 | "/" +
79 | durationToString(widget.duration),
80 | style: TextStyle(color: Colors.white, fontSize: 10),
81 | ),
82 | ],
83 | );
84 | }
85 | }
86 | // Text(
87 | // durationToString(widget.duration),
88 | // style: TextStyle(color: Colors.white, fontSize: 10),
89 | // ),
90 |
91 | String durationToString(Duration duration) {
92 | String twoDigits(int n) {
93 | if (n >= 10) return "$n";
94 | return "0$n";
95 | }
96 |
97 | String twoDigitHours =
98 | twoDigits(duration.inHours.remainder(Duration.hoursPerDay));
99 | String twoDigitMinutes =
100 | twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
101 | String twoDigitSeconds =
102 | twoDigits(duration.inSeconds.remainder(Duration.secondsPerMinute));
103 | return "$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds";
104 | }
105 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images":[
3 | {
4 | "idiom":"iphone",
5 | "size":"20x20",
6 | "scale":"2x",
7 | "filename":"Icon-App-20x20@2x.png"
8 | },
9 | {
10 | "idiom":"iphone",
11 | "size":"20x20",
12 | "scale":"3x",
13 | "filename":"Icon-App-20x20@3x.png"
14 | },
15 | {
16 | "idiom":"iphone",
17 | "size":"29x29",
18 | "scale":"1x",
19 | "filename":"Icon-App-29x29@1x.png"
20 | },
21 | {
22 | "idiom":"iphone",
23 | "size":"29x29",
24 | "scale":"2x",
25 | "filename":"Icon-App-29x29@2x.png"
26 | },
27 | {
28 | "idiom":"iphone",
29 | "size":"29x29",
30 | "scale":"3x",
31 | "filename":"Icon-App-29x29@3x.png"
32 | },
33 | {
34 | "idiom":"iphone",
35 | "size":"40x40",
36 | "scale":"2x",
37 | "filename":"Icon-App-40x40@2x.png"
38 | },
39 | {
40 | "idiom":"iphone",
41 | "size":"40x40",
42 | "scale":"3x",
43 | "filename":"Icon-App-40x40@3x.png"
44 | },
45 | {
46 | "idiom":"iphone",
47 | "size":"60x60",
48 | "scale":"2x",
49 | "filename":"Icon-App-60x60@2x.png"
50 | },
51 | {
52 | "idiom":"iphone",
53 | "size":"60x60",
54 | "scale":"3x",
55 | "filename":"Icon-App-60x60@3x.png"
56 | },
57 | {
58 | "idiom":"iphone",
59 | "size":"76x76",
60 | "scale":"2x",
61 | "filename":"Icon-App-76x76@2x.png"
62 | },
63 | {
64 | "idiom":"ipad",
65 | "size":"20x20",
66 | "scale":"1x",
67 | "filename":"Icon-App-20x20@1x.png"
68 | },
69 | {
70 | "idiom":"ipad",
71 | "size":"20x20",
72 | "scale":"2x",
73 | "filename":"Icon-App-20x20@2x.png"
74 | },
75 | {
76 | "idiom":"ipad",
77 | "size":"29x29",
78 | "scale":"1x",
79 | "filename":"Icon-App-29x29@1x.png"
80 | },
81 | {
82 | "idiom":"ipad",
83 | "size":"29x29",
84 | "scale":"2x",
85 | "filename":"Icon-App-29x29@2x.png"
86 | },
87 | {
88 | "idiom":"ipad",
89 | "size":"40x40",
90 | "scale":"1x",
91 | "filename":"Icon-App-40x40@1x.png"
92 | },
93 | {
94 | "idiom":"ipad",
95 | "size":"40x40",
96 | "scale":"2x",
97 | "filename":"Icon-App-40x40@2x.png"
98 | },
99 | {
100 | "idiom":"ipad",
101 | "size":"76x76",
102 | "scale":"1x",
103 | "filename":"Icon-App-76x76@1x.png"
104 | },
105 | {
106 | "idiom":"ipad",
107 | "size":"76x76",
108 | "scale":"2x",
109 | "filename":"Icon-App-76x76@2x.png"
110 | },
111 | {
112 | "idiom":"ipad",
113 | "size":"83.5x83.5",
114 | "scale":"2x",
115 | "filename":"Icon-App-83.5x83.5@2x.png"
116 | },
117 | {
118 | "size" : "1024x1024",
119 | "idiom" : "ios-marketing",
120 | "scale" : "1x",
121 | "filename" : "ItunesArtwork@2x.png"
122 | }
123 | ],
124 | "info":{
125 | "version":1,
126 | "author":"easyappicon"
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flowpdc_app
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | ## Slidy Scripts
21 | vars:
22 | clean: flutter clean
23 | get: flutter pub get
24 | runner: flutter pub run build_runner
25 | scripts:
26 | mobx_build: $runner build
27 | mobx_watch: $clean & $get & $runner watch
28 | mobx_build_clean: $clean & $get & $runner build --delete-conflicting-outputs
29 | android-build: flutter build apk --split-per-abi
30 | android-install: flutter install
31 |
32 |
33 |
34 | environment:
35 | sdk: ">=2.7.0 <3.0.0"
36 |
37 | dependencies:
38 | shared_preferences: ^0.5.12+4
39 | rxdart: ^0.24.1
40 | dio: ^3.0.10
41 | flutter_mobx: ^1.1.0+2
42 | mobx: ^1.2.1+4
43 | flutter_modular: ^2.0.1
44 | assets_audio_player: ^2.0.13+1
45 | flutter:
46 | sdk: flutter
47 |
48 |
49 | # The following adds the Cupertino Icons font to your application.
50 | # Use with the CupertinoIcons class for iOS style icons.
51 |
52 | dev_dependencies:
53 | mockito: ^4.1.3
54 | modular_codegen: ^2.0.1
55 | mobx_codegen: ^1.1.2
56 | build_runner: ^1.10.1
57 | flutter_launcher_icons: ^0.8.1
58 | flutter_test:
59 | sdk: flutter
60 |
61 | flutter_icons:
62 | android: true
63 | ios: true
64 | image_path: "images/app_logo.jpg"
65 | # For information on the generic Dart part of this file, see the
66 | # following page: https://dart.dev/tools/pub/pubspec
67 |
68 | # The following section is specific to Flutter.
69 | flutter:
70 |
71 | # The following line ensures that the Material Icons font is
72 | # included with your application, so that you can use the icons in
73 | # the material Icons class.
74 | uses-material-design: true
75 |
76 | # To add assets to your application, add an assets section, like this:
77 | assets:
78 | - images/logo.png
79 |
80 | # An image asset can refer to one or more resolution-specific "variants", see
81 | # https://flutter.dev/assets-and-images/#resolution-aware.
82 |
83 | # For details regarding adding assets from package dependencies, see
84 | # https://flutter.dev/assets-and-images/#from-packages
85 |
86 | # To add custom fonts to your application, add a fonts section here,
87 | # in this "flutter" section. Each entry in this list should have a
88 | # "family" key with the font family name, and a "fonts" key with a
89 | # list giving the asset and other descriptors for the font. For
90 | # example:
91 | # fonts:
92 | # - family: Schyler
93 | # fonts:
94 | # - asset: fonts/Schyler-Regular.ttf
95 | # - asset: fonts/Schyler-Italic.ttf
96 | # style: italic
97 | # - family: Trajan Pro
98 | # fonts:
99 | # - asset: fonts/TrajanPro.ttf
100 | # - asset: fonts/TrajanPro_Bold.ttf
101 | # weight: 700
102 | #
103 | # For details regarding fonts from package dependencies,
104 | # see https://flutter.dev/custom-fonts/#from-packages
105 |
--------------------------------------------------------------------------------
/lib/app/modules/home/home_controller.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/shared/models/podcast.dart';
2 | import 'package:flowpdc_app/app/shared/repositories/localstorage/local_storage_interface.dart';
3 | import 'package:flowpdc_app/app/shared/repositories/podcast_repository.dart';
4 | import 'package:flowpdc_app/app/status/status_podcast.dart';
5 | import 'package:flutter_modular/flutter_modular.dart';
6 | import 'package:mobx/mobx.dart';
7 |
8 | part 'home_controller.g.dart';
9 |
10 | @Injectable()
11 | class HomeController = _HomeControllerBase with _$HomeController;
12 |
13 | abstract class _HomeControllerBase with Store {
14 | final PodcastRepository repository;
15 | final ILocalStorage _storage = Modular.get();
16 |
17 | @observable
18 | ObservableMap podcasts;
19 |
20 | @observable
21 | String loadMoreNextParameter;
22 |
23 | @observable
24 | bool showOnlyFavorites;
25 |
26 | @observable
27 | ObservableList favoritePodcastsIds;
28 |
29 | @observable
30 | Podcast podcastSelected;
31 |
32 | @observable
33 | StatusPodcast statusPodcast = StatusPodcast.INITIAL;
34 |
35 | @observable
36 | StatusPodcast statusPodcasts = StatusPodcast.INITIAL;
37 |
38 | _HomeControllerBase(this.repository) {
39 | this.showOnlyFavorites = false;
40 | this.podcasts = ObservableMap();
41 | fetchPodcasts(null);
42 | }
43 |
44 | @action
45 | selectPodcast(Podcast podcast) => podcastSelected = podcast;
46 |
47 | @action
48 | fetchPodcasts(String nextPaging) async {
49 | try {
50 | PodcastResponse result;
51 | if (nextPaging == null && podcasts.isEmpty) {
52 | statusPodcasts = StatusPodcast.LOADING;
53 | result = await repository.getAllPodcasts();
54 | } else {
55 | result = await repository.loadMorePodcasts(nextPaging);
56 | }
57 | loadMoreNextParameter = result.next;
58 | podcasts.addAll(result.podcastMap.asObservable());
59 |
60 | statusPodcasts = StatusPodcast.SUCCESS;
61 | favoritePodcastsIds = await getFavoritesPodcastsIds();
62 | } catch (e) {
63 | statusPodcasts = StatusPodcast.ERROR;
64 | //statusPodcasts.setMensagem = "Ex mensagem de erro";
65 | }
66 | }
67 |
68 | @action
69 | fetchPodcast(String id) async {
70 | try {
71 | statusPodcast = StatusPodcast.LOADING;
72 | podcastSelected = await repository.getPodcast(id).asObservable();
73 | statusPodcast = StatusPodcast.SUCCESS;
74 | } catch (e) {
75 | statusPodcast = StatusPodcast.ERROR;
76 | //statusPodcastSelected.setMensagem = "Ex mensagem de erro";
77 | }
78 | }
79 |
80 | @action
81 | addOrRemoveFavorite(String id) async {
82 | List favorites = await getFavoritesPodcastsIds();
83 | if (favorites == null) {
84 | _storage.put('favorites', List());
85 | favorites = await getFavoritesPodcastsIds();
86 | }
87 | Podcast podcastFavorited = await repository.getPodcast(id).asObservable();
88 | if (!favorites.contains(id)) {
89 | favorites.add(id);
90 | podcastFavorited.isFavorite = true;
91 | } else {
92 | favorites.remove(id);
93 | podcastFavorited.isFavorite = false;
94 | }
95 |
96 | if (podcasts.containsKey(podcastFavorited.id)) {
97 | podcasts[podcastFavorited.id] = podcastFavorited;
98 | }
99 |
100 | _storage.put('favorites', favorites);
101 | favoritePodcastsIds = await getFavoritesPodcastsIds();
102 | }
103 |
104 | @action
105 | getFavoritesPodcastsIds() async {
106 | try {
107 | List favorites = await _storage.get('favorites');
108 | if (favorites == null) {
109 | _storage.put('favorites', List());
110 | favorites = await _storage.get('favorites');
111 | }
112 | return favorites.asObservable();
113 | } catch (e) {
114 | throw Exception(e.toString());
115 | }
116 | }
117 |
118 | @action
119 | fetchFavoritePodcasts() async {
120 | try {
121 | statusPodcasts = StatusPodcast.LOADING;
122 | List favorites = await getFavoritesPodcastsIds();
123 |
124 | ObservableMap favoritePodcasts =
125 | ObservableMap();
126 |
127 | for (String id in favorites) {
128 | Podcast podcast = await repository.getPodcast(id);
129 | favoritePodcasts[podcast.id] = podcast;
130 | }
131 | podcasts = favoritePodcasts;
132 | statusPodcasts = StatusPodcast.SUCCESS;
133 | } catch (e) {
134 | statusPodcast = StatusPodcast.ERROR;
135 | }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/lib/app/modules/home/home_controller.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'home_controller.dart';
4 |
5 | // **************************************************************************
6 | // InjectionGenerator
7 | // **************************************************************************
8 |
9 | final $HomeController = BindInject(
10 | (i) => HomeController(i()),
11 | singleton: true,
12 | lazy: true,
13 | );
14 |
15 | // **************************************************************************
16 | // StoreGenerator
17 | // **************************************************************************
18 |
19 | // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic
20 |
21 | mixin _$HomeController on _HomeControllerBase, Store {
22 | final _$podcastsAtom = Atom(name: '_HomeControllerBase.podcasts');
23 |
24 | @override
25 | ObservableMap get podcasts {
26 | _$podcastsAtom.reportRead();
27 | return super.podcasts;
28 | }
29 |
30 | @override
31 | set podcasts(ObservableMap value) {
32 | _$podcastsAtom.reportWrite(value, super.podcasts, () {
33 | super.podcasts = value;
34 | });
35 | }
36 |
37 | final _$loadMoreNextParameterAtom =
38 | Atom(name: '_HomeControllerBase.loadMoreNextParameter');
39 |
40 | @override
41 | String get loadMoreNextParameter {
42 | _$loadMoreNextParameterAtom.reportRead();
43 | return super.loadMoreNextParameter;
44 | }
45 |
46 | @override
47 | set loadMoreNextParameter(String value) {
48 | _$loadMoreNextParameterAtom.reportWrite(value, super.loadMoreNextParameter,
49 | () {
50 | super.loadMoreNextParameter = value;
51 | });
52 | }
53 |
54 | final _$showOnlyFavoritesAtom =
55 | Atom(name: '_HomeControllerBase.showOnlyFavorites');
56 |
57 | @override
58 | bool get showOnlyFavorites {
59 | _$showOnlyFavoritesAtom.reportRead();
60 | return super.showOnlyFavorites;
61 | }
62 |
63 | @override
64 | set showOnlyFavorites(bool value) {
65 | _$showOnlyFavoritesAtom.reportWrite(value, super.showOnlyFavorites, () {
66 | super.showOnlyFavorites = value;
67 | });
68 | }
69 |
70 | final _$favoritePodcastsIdsAtom =
71 | Atom(name: '_HomeControllerBase.favoritePodcastsIds');
72 |
73 | @override
74 | ObservableList get favoritePodcastsIds {
75 | _$favoritePodcastsIdsAtom.reportRead();
76 | return super.favoritePodcastsIds;
77 | }
78 |
79 | @override
80 | set favoritePodcastsIds(ObservableList value) {
81 | _$favoritePodcastsIdsAtom.reportWrite(value, super.favoritePodcastsIds, () {
82 | super.favoritePodcastsIds = value;
83 | });
84 | }
85 |
86 | final _$podcastSelectedAtom =
87 | Atom(name: '_HomeControllerBase.podcastSelected');
88 |
89 | @override
90 | Podcast get podcastSelected {
91 | _$podcastSelectedAtom.reportRead();
92 | return super.podcastSelected;
93 | }
94 |
95 | @override
96 | set podcastSelected(Podcast value) {
97 | _$podcastSelectedAtom.reportWrite(value, super.podcastSelected, () {
98 | super.podcastSelected = value;
99 | });
100 | }
101 |
102 | final _$statusPodcastAtom = Atom(name: '_HomeControllerBase.statusPodcast');
103 |
104 | @override
105 | StatusPodcast get statusPodcast {
106 | _$statusPodcastAtom.reportRead();
107 | return super.statusPodcast;
108 | }
109 |
110 | @override
111 | set statusPodcast(StatusPodcast value) {
112 | _$statusPodcastAtom.reportWrite(value, super.statusPodcast, () {
113 | super.statusPodcast = value;
114 | });
115 | }
116 |
117 | final _$statusPodcastsAtom = Atom(name: '_HomeControllerBase.statusPodcasts');
118 |
119 | @override
120 | StatusPodcast get statusPodcasts {
121 | _$statusPodcastsAtom.reportRead();
122 | return super.statusPodcasts;
123 | }
124 |
125 | @override
126 | set statusPodcasts(StatusPodcast value) {
127 | _$statusPodcastsAtom.reportWrite(value, super.statusPodcasts, () {
128 | super.statusPodcasts = value;
129 | });
130 | }
131 |
132 | final _$fetchPodcastsAsyncAction =
133 | AsyncAction('_HomeControllerBase.fetchPodcasts');
134 |
135 | @override
136 | Future fetchPodcasts(String nextPaging) {
137 | return _$fetchPodcastsAsyncAction
138 | .run(() => super.fetchPodcasts(nextPaging));
139 | }
140 |
141 | final _$fetchPodcastAsyncAction =
142 | AsyncAction('_HomeControllerBase.fetchPodcast');
143 |
144 | @override
145 | Future fetchPodcast(String id) {
146 | return _$fetchPodcastAsyncAction.run(() => super.fetchPodcast(id));
147 | }
148 |
149 | final _$addOrRemoveFavoriteAsyncAction =
150 | AsyncAction('_HomeControllerBase.addOrRemoveFavorite');
151 |
152 | @override
153 | Future addOrRemoveFavorite(String id) {
154 | return _$addOrRemoveFavoriteAsyncAction
155 | .run(() => super.addOrRemoveFavorite(id));
156 | }
157 |
158 | final _$getFavoritesPodcastsIdsAsyncAction =
159 | AsyncAction('_HomeControllerBase.getFavoritesPodcastsIds');
160 |
161 | @override
162 | Future getFavoritesPodcastsIds() {
163 | return _$getFavoritesPodcastsIdsAsyncAction
164 | .run(() => super.getFavoritesPodcastsIds());
165 | }
166 |
167 | final _$fetchFavoritePodcastsAsyncAction =
168 | AsyncAction('_HomeControllerBase.fetchFavoritePodcasts');
169 |
170 | @override
171 | Future fetchFavoritePodcasts() {
172 | return _$fetchFavoritePodcastsAsyncAction
173 | .run(() => super.fetchFavoritePodcasts());
174 | }
175 |
176 | final _$_HomeControllerBaseActionController =
177 | ActionController(name: '_HomeControllerBase');
178 |
179 | @override
180 | dynamic selectPodcast(Podcast podcast) {
181 | final _$actionInfo = _$_HomeControllerBaseActionController.startAction(
182 | name: '_HomeControllerBase.selectPodcast');
183 | try {
184 | return super.selectPodcast(podcast);
185 | } finally {
186 | _$_HomeControllerBaseActionController.endAction(_$actionInfo);
187 | }
188 | }
189 |
190 | @override
191 | String toString() {
192 | return '''
193 | podcasts: ${podcasts},
194 | loadMoreNextParameter: ${loadMoreNextParameter},
195 | showOnlyFavorites: ${showOnlyFavorites},
196 | favoritePodcastsIds: ${favoritePodcastsIds},
197 | podcastSelected: ${podcastSelected},
198 | statusPodcast: ${statusPodcast},
199 | statusPodcasts: ${statusPodcasts}
200 | ''';
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/lib/app/widgets/player/player_widget.dart:
--------------------------------------------------------------------------------
1 | import 'package:assets_audio_player/assets_audio_player.dart';
2 | import 'package:flowpdc_app/app/shared/models/podcast.dart';
3 | import 'package:flowpdc_app/app/widgets/player/player_controller.dart';
4 | import 'package:flowpdc_app/app/widgets/player/position_seek_widget.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:flutter/rendering.dart';
7 | import 'package:flutter_mobx/flutter_mobx.dart';
8 | import 'package:flutter_modular/flutter_modular.dart';
9 |
10 | import '../podcast_thumbnail.dart';
11 |
12 | class PlayerWidget extends StatefulWidget {
13 | final Podcast podcast;
14 | final bool isFavorite;
15 | final Function addFavorite;
16 | final Function closePlayer;
17 |
18 | const PlayerWidget({
19 | Key key,
20 | this.podcast,
21 | this.addFavorite,
22 | this.isFavorite,
23 | this.closePlayer,
24 | }) : super(key: key);
25 |
26 | @override
27 | _PlayerWidget createState() => new _PlayerWidget();
28 | }
29 |
30 | class _PlayerWidget extends ModularState {
31 | final _assetsAudioPlayer = AssetsAudioPlayer.newPlayer();
32 | String _currentAudio;
33 |
34 | @override
35 | void dispose() {
36 | super.dispose();
37 | _assetsAudioPlayer.stop();
38 | _assetsAudioPlayer.dispose();
39 | }
40 |
41 | void _loadAudio(String url) {
42 | _assetsAudioPlayer.open(
43 | Audio.network(
44 | url,
45 | metas: Metas(
46 | title: widget.podcast.title,
47 | image: MetasImage.network(widget.podcast.thumbnailUrl),
48 | ),
49 | ),
50 | autoStart: true,
51 | showNotification: true,
52 | notificationSettings: NotificationSettings(
53 | nextEnabled: false,
54 | prevEnabled: false,
55 | customPlayPauseAction: (player) {
56 | controller.isPlaying = !controller.isPlaying;
57 | player.playOrPause();
58 | },
59 | customStopAction: (player) => {
60 | player.stop(),
61 | this.widget.closePlayer(),
62 | },
63 | ),
64 | );
65 | }
66 |
67 | IconData getStatusAudio(bool value) {
68 | if (value) {
69 | return Icons.pause_circle_filled;
70 | }
71 | return Icons.play_circle_fill;
72 | }
73 |
74 | @override
75 | Widget build(BuildContext context) {
76 | if (_currentAudio != widget.podcast.audioUrl) {
77 | _currentAudio = widget.podcast.audioUrl;
78 | _loadAudio(_currentAudio);
79 | }
80 | _currentAudio = widget.podcast.audioUrl;
81 |
82 | return Column(
83 | crossAxisAlignment: CrossAxisAlignment.stretch,
84 | mainAxisAlignment: MainAxisAlignment.end,
85 | children: [
86 | Container(
87 | decoration: BoxDecoration(
88 | color: Theme.of(context).primaryColor,
89 | border: Border(
90 | top: BorderSide(width: 1.0, color: Colors.white),
91 | ),
92 | ),
93 | child: Container(
94 | // margin: EdgeInsets.only(left: 18, right: 18, bottom: 8),
95 | child: Observer(
96 | builder: (_) {
97 | return Column(
98 | mainAxisAlignment: MainAxisAlignment.start,
99 | crossAxisAlignment: CrossAxisAlignment.start,
100 | children: [
101 | Container(
102 | margin: EdgeInsets.only(right: 8),
103 | width: MediaQuery.of(context).size.width,
104 | child: StreamBuilder(
105 | stream: _assetsAudioPlayer.realtimePlayingInfos,
106 | builder: (context, snapshot) {
107 | if (!snapshot.hasData) {
108 | return SizedBox();
109 | }
110 | RealtimePlayingInfos infos = snapshot.data;
111 | return PositionSeekWidget(
112 | seekTo: (to) {
113 | _assetsAudioPlayer.seek(to);
114 | },
115 | duration: infos.duration,
116 | currentPosition: infos.currentPosition,
117 | );
118 | },
119 | ),
120 | ),
121 | Container(
122 | child: ListTile(
123 | leading: Container(
124 | width: 48,
125 | child: PodcastThumbnail(
126 | url: widget.podcast.thumbnailUrl,
127 | ),
128 | ),
129 | title: Container(
130 | width: MediaQuery.of(context).size.width * 0.4,
131 | child: SingleChildScrollView(
132 | scrollDirection: Axis.horizontal,
133 | child: Text(
134 | widget.podcast.title,
135 | overflow: TextOverflow.fade,
136 | softWrap: true,
137 | maxLines: 1,
138 | style: TextStyle(
139 | color: Colors.white,
140 | fontSize: 16,
141 | fontWeight: FontWeight.w700,
142 | ),
143 | ),
144 | ),
145 | ),
146 | contentPadding:
147 | EdgeInsets.symmetric(vertical: 4, horizontal: 16),
148 | trailing: Wrap(
149 | spacing: 12, // space between two icons
150 | children: [
151 | Container(
152 | child: Observer(
153 | builder: (_) {
154 | return IconButton(
155 | icon: Icon(
156 | getStatusAudio(controller.isPlaying),
157 | color: Colors.white,
158 | size: 38,
159 | ),
160 | onPressed: () {
161 | if (_assetsAudioPlayer.current.value !=
162 | null) {
163 | controller.isPlaying =
164 | !controller.isPlaying;
165 |
166 | _assetsAudioPlayer.playOrPause();
167 | }
168 | },
169 | );
170 | },
171 | ),
172 | ),
173 | Container(
174 | margin: EdgeInsets.all(0),
175 | child: IconButton(
176 | icon: Icon(
177 | this.widget.isFavorite
178 | ? Icons.favorite
179 | : Icons.favorite_border,
180 | color: Theme.of(context).accentColor,
181 | size: 38,
182 | ),
183 | onPressed: this.widget.addFavorite,
184 | ),
185 | )
186 | ],
187 | ),
188 | ),
189 | )
190 | ],
191 | );
192 | },
193 | ),
194 | ),
195 | )
196 | ],
197 | );
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/lib/app/modules/home/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flowpdc_app/app/shared/models/podcast.dart';
2 | import 'package:flowpdc_app/app/status/status_podcast.dart';
3 | import 'package:flowpdc_app/app/widgets/player/player_widget.dart';
4 | import 'package:flowpdc_app/app/widgets/podcast_card/podcast_card_widget.dart';
5 | import 'package:flowpdc_app/app/widgets/podcast_description_dialog.dart';
6 | import 'package:flutter/material.dart';
7 | import 'package:flutter_mobx/flutter_mobx.dart';
8 | import 'package:flutter_modular/flutter_modular.dart';
9 | import 'home_controller.dart';
10 |
11 | class HomePage extends StatefulWidget {
12 | final String title;
13 |
14 | const HomePage({Key key, this.title = "Flow Pdc"}) : super(key: key);
15 |
16 | @override
17 | _HomePageState createState() => _HomePageState();
18 | }
19 |
20 | class _HomePageState extends ModularState {
21 | void _loadPodcasts(bool showFavorites) {
22 | if (showFavorites)
23 | controller.fetchFavoritePodcasts();
24 | else {
25 | controller.podcasts.clear();
26 | controller.fetchPodcasts(null);
27 | }
28 | }
29 |
30 | @override
31 | Widget build(BuildContext context) {
32 | return Scaffold(
33 | appBar: AppBar(
34 | toolbarHeight: 80,
35 | flexibleSpace: Container(
36 | margin: EdgeInsets.only(top: 48),
37 | child: Image(
38 | image: AssetImage('images/logo.png'),
39 | fit: BoxFit.contain,
40 | ),
41 | decoration: BoxDecoration(
42 | color: Theme.of(context).primaryColor,
43 | border: Border(
44 | bottom: BorderSide(
45 | width: 1.0,
46 | color: Colors.white,
47 | ),
48 | ),
49 | ),
50 | ),
51 | actions: [
52 | Container(
53 | margin: EdgeInsets.all(18),
54 | child: Observer(builder: (_) {
55 | return IconButton(
56 | icon: Icon(
57 | !controller.showOnlyFavorites
58 | ? Icons.favorite_border
59 | : Icons.favorite,
60 | color: Theme.of(context).accentColor,
61 | size: 38,
62 | ),
63 | onPressed: () {
64 | controller.showOnlyFavorites = !controller.showOnlyFavorites;
65 | _loadPodcasts(controller.showOnlyFavorites);
66 | },
67 | );
68 | }),
69 | )
70 | ],
71 | elevation: 0,
72 | ),
73 | body: Center(
74 | child: Container(
75 | decoration: BoxDecoration(
76 | gradient: LinearGradient(
77 | begin: Alignment.topLeft,
78 | end: Alignment.bottomRight,
79 | stops: [0.7, 1],
80 | colors: [
81 | Theme.of(context).primaryColor,
82 | Theme.of(context).accentColor
83 | ],
84 | ),
85 | ),
86 | child: Stack(
87 | alignment: Alignment.center,
88 | children: [
89 | Observer(
90 | builder: (_) {
91 | switch (controller.statusPodcasts) {
92 | case StatusPodcast.ERROR:
93 | return Center(
94 | child: RaisedButton(
95 | color: Colors.amber,
96 | child: Text(
97 | !controller.showOnlyFavorites
98 | ? "Load podcasts again"
99 | : "Load favorite podcasts again",
100 | style: TextStyle(color: Colors.black),
101 | ),
102 | onPressed: () {
103 | _loadPodcasts(controller.showOnlyFavorites);
104 | },
105 | ),
106 | );
107 | break;
108 | case StatusPodcast.LOADING:
109 | return Center(
110 | child: CircularProgressIndicator(
111 | backgroundColor: Colors.black,
112 | valueColor:
113 | AlwaysStoppedAnimation(Colors.amber),
114 | ),
115 | );
116 | break;
117 | case StatusPodcast.SUCCESS:
118 | Map _podcastMap = controller.podcasts;
119 | List _podcasts = _podcastMap.keys.toList();
120 | List favorites = controller.favoritePodcastsIds;
121 | if (_podcasts.isEmpty) {
122 | return Container(
123 | height: MediaQuery.of(context).size.height,
124 | width: MediaQuery.of(context).size.width,
125 | alignment: Alignment.center,
126 | child: Text(
127 | "Podcasts not found...",
128 | style: TextStyle(color: Colors.white, fontSize: 18),
129 | ),
130 | );
131 | }
132 |
133 | return Stack(
134 | alignment: Alignment.center,
135 | children: [
136 | NotificationListener(
137 | // ignore: missing_return
138 | onNotification: (ScrollNotification scrollInfo) {
139 | if (scrollInfo.metrics.pixels ==
140 | scrollInfo.metrics.maxScrollExtent) {
141 | if (!controller.showOnlyFavorites) {
142 | controller.fetchPodcasts(
143 | controller.loadMoreNextParameter,
144 | );
145 | }
146 | }
147 | },
148 | child: ListView.builder(
149 | itemCount: _podcasts.length,
150 | padding: EdgeInsets.only(
151 | bottom: controller.podcastSelected != null
152 | ? 108
153 | : 8,
154 | ),
155 | itemBuilder: (context, index) {
156 | Podcast _podcast =
157 | _podcastMap[_podcasts[index]];
158 | return GestureDetector(
159 | child: Observer(
160 | builder: (_) {
161 | return PodcastCard(
162 | thumbnail: _podcast.thumbnailUrl,
163 | title: _podcast.title,
164 | isFavorite:
165 | favorites.contains(_podcast.id),
166 | addFavorite: () {
167 | controller
168 | .addOrRemoveFavorite(_podcast.id);
169 | _podcast.isFavorite =
170 | !_podcast.isFavorite;
171 | },
172 | );
173 | },
174 | ),
175 | onTap: () {
176 | controller.selectPodcast(_podcast);
177 | },
178 | onLongPress: () {
179 | showDialog(
180 | context: context,
181 | builder: (BuildContext context) {
182 | return PodcastDescriptionDialog(
183 | title: _podcast.title,
184 | description: _podcast.description,
185 | thumbnail: _podcast.thumbnailUrl,
186 | );
187 | },
188 | );
189 | },
190 | );
191 | },
192 | ),
193 | ),
194 | ],
195 | );
196 | break;
197 | default:
198 | return Container();
199 | break;
200 | }
201 | },
202 | ),
203 | Observer(
204 | builder: (_) {
205 | List favorites = controller.favoritePodcastsIds;
206 | if (controller.podcastSelected != null) {
207 | Podcast podcast = controller.podcastSelected;
208 | return PlayerWidget(
209 | podcast: podcast,
210 | isFavorite: favorites.contains(podcast.id),
211 | addFavorite: () {
212 | controller.addOrRemoveFavorite(podcast.id);
213 | },
214 | closePlayer: () {
215 | controller.selectPodcast(null);
216 | },
217 | );
218 | } else {
219 | return Divider();
220 | }
221 | },
222 | ),
223 | ],
224 | ),
225 | ),
226 | ),
227 | );
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | _fe_analyzer_shared:
5 | dependency: transitive
6 | description:
7 | name: _fe_analyzer_shared
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "12.0.0"
11 | analyzer:
12 | dependency: transitive
13 | description:
14 | name: analyzer
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "0.40.6"
18 | archive:
19 | dependency: transitive
20 | description:
21 | name: archive
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "2.0.13"
25 | args:
26 | dependency: transitive
27 | description:
28 | name: args
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.6.0"
32 | assets_audio_player:
33 | dependency: "direct main"
34 | description:
35 | name: assets_audio_player
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "2.0.13+1"
39 | assets_audio_player_web:
40 | dependency: transitive
41 | description:
42 | name: assets_audio_player_web
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "2.0.13+1"
46 | async:
47 | dependency: transitive
48 | description:
49 | name: async
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "2.5.0-nullsafety.1"
53 | boolean_selector:
54 | dependency: transitive
55 | description:
56 | name: boolean_selector
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "2.1.0-nullsafety.1"
60 | build:
61 | dependency: transitive
62 | description:
63 | name: build
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "1.5.1"
67 | build_config:
68 | dependency: transitive
69 | description:
70 | name: build_config
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "0.4.3"
74 | build_daemon:
75 | dependency: transitive
76 | description:
77 | name: build_daemon
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "2.1.4"
81 | build_resolvers:
82 | dependency: transitive
83 | description:
84 | name: build_resolvers
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "1.4.3"
88 | build_runner:
89 | dependency: "direct dev"
90 | description:
91 | name: build_runner
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "1.10.6"
95 | build_runner_core:
96 | dependency: transitive
97 | description:
98 | name: build_runner_core
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "6.1.1"
102 | built_collection:
103 | dependency: transitive
104 | description:
105 | name: built_collection
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "4.3.2"
109 | built_value:
110 | dependency: transitive
111 | description:
112 | name: built_value
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "7.1.0"
116 | characters:
117 | dependency: transitive
118 | description:
119 | name: characters
120 | url: "https://pub.dartlang.org"
121 | source: hosted
122 | version: "1.1.0-nullsafety.3"
123 | charcode:
124 | dependency: transitive
125 | description:
126 | name: charcode
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.2.0-nullsafety.1"
130 | checked_yaml:
131 | dependency: transitive
132 | description:
133 | name: checked_yaml
134 | url: "https://pub.dartlang.org"
135 | source: hosted
136 | version: "1.0.2"
137 | cli_util:
138 | dependency: transitive
139 | description:
140 | name: cli_util
141 | url: "https://pub.dartlang.org"
142 | source: hosted
143 | version: "0.2.0"
144 | clock:
145 | dependency: transitive
146 | description:
147 | name: clock
148 | url: "https://pub.dartlang.org"
149 | source: hosted
150 | version: "1.1.0-nullsafety.1"
151 | code_builder:
152 | dependency: transitive
153 | description:
154 | name: code_builder
155 | url: "https://pub.dartlang.org"
156 | source: hosted
157 | version: "3.5.0"
158 | collection:
159 | dependency: transitive
160 | description:
161 | name: collection
162 | url: "https://pub.dartlang.org"
163 | source: hosted
164 | version: "1.15.0-nullsafety.3"
165 | convert:
166 | dependency: transitive
167 | description:
168 | name: convert
169 | url: "https://pub.dartlang.org"
170 | source: hosted
171 | version: "2.1.1"
172 | crypto:
173 | dependency: transitive
174 | description:
175 | name: crypto
176 | url: "https://pub.dartlang.org"
177 | source: hosted
178 | version: "2.1.5"
179 | dart_style:
180 | dependency: transitive
181 | description:
182 | name: dart_style
183 | url: "https://pub.dartlang.org"
184 | source: hosted
185 | version: "1.3.10"
186 | dio:
187 | dependency: "direct main"
188 | description:
189 | name: dio
190 | url: "https://pub.dartlang.org"
191 | source: hosted
192 | version: "3.0.10"
193 | fake_async:
194 | dependency: transitive
195 | description:
196 | name: fake_async
197 | url: "https://pub.dartlang.org"
198 | source: hosted
199 | version: "1.2.0-nullsafety.1"
200 | ffi:
201 | dependency: transitive
202 | description:
203 | name: ffi
204 | url: "https://pub.dartlang.org"
205 | source: hosted
206 | version: "0.1.3"
207 | file:
208 | dependency: transitive
209 | description:
210 | name: file
211 | url: "https://pub.dartlang.org"
212 | source: hosted
213 | version: "5.2.1"
214 | fixnum:
215 | dependency: transitive
216 | description:
217 | name: fixnum
218 | url: "https://pub.dartlang.org"
219 | source: hosted
220 | version: "0.10.11"
221 | flutter:
222 | dependency: "direct main"
223 | description: flutter
224 | source: sdk
225 | version: "0.0.0"
226 | flutter_launcher_icons:
227 | dependency: "direct dev"
228 | description:
229 | name: flutter_launcher_icons
230 | url: "https://pub.dartlang.org"
231 | source: hosted
232 | version: "0.8.1"
233 | flutter_mobx:
234 | dependency: "direct main"
235 | description:
236 | name: flutter_mobx
237 | url: "https://pub.dartlang.org"
238 | source: hosted
239 | version: "1.1.0+2"
240 | flutter_modular:
241 | dependency: "direct main"
242 | description:
243 | name: flutter_modular
244 | url: "https://pub.dartlang.org"
245 | source: hosted
246 | version: "2.0.1"
247 | flutter_test:
248 | dependency: "direct dev"
249 | description: flutter
250 | source: sdk
251 | version: "0.0.0"
252 | flutter_web_plugins:
253 | dependency: transitive
254 | description: flutter
255 | source: sdk
256 | version: "0.0.0"
257 | glob:
258 | dependency: transitive
259 | description:
260 | name: glob
261 | url: "https://pub.dartlang.org"
262 | source: hosted
263 | version: "1.2.0"
264 | graphs:
265 | dependency: transitive
266 | description:
267 | name: graphs
268 | url: "https://pub.dartlang.org"
269 | source: hosted
270 | version: "0.2.0"
271 | http:
272 | dependency: transitive
273 | description:
274 | name: http
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "0.12.2"
278 | http_multi_server:
279 | dependency: transitive
280 | description:
281 | name: http_multi_server
282 | url: "https://pub.dartlang.org"
283 | source: hosted
284 | version: "2.2.0"
285 | http_parser:
286 | dependency: transitive
287 | description:
288 | name: http_parser
289 | url: "https://pub.dartlang.org"
290 | source: hosted
291 | version: "3.1.4"
292 | image:
293 | dependency: transitive
294 | description:
295 | name: image
296 | url: "https://pub.dartlang.org"
297 | source: hosted
298 | version: "2.1.19"
299 | intl:
300 | dependency: transitive
301 | description:
302 | name: intl
303 | url: "https://pub.dartlang.org"
304 | source: hosted
305 | version: "0.16.1"
306 | io:
307 | dependency: transitive
308 | description:
309 | name: io
310 | url: "https://pub.dartlang.org"
311 | source: hosted
312 | version: "0.3.4"
313 | js:
314 | dependency: transitive
315 | description:
316 | name: js
317 | url: "https://pub.dartlang.org"
318 | source: hosted
319 | version: "0.6.2"
320 | json_annotation:
321 | dependency: transitive
322 | description:
323 | name: json_annotation
324 | url: "https://pub.dartlang.org"
325 | source: hosted
326 | version: "3.1.1"
327 | logging:
328 | dependency: transitive
329 | description:
330 | name: logging
331 | url: "https://pub.dartlang.org"
332 | source: hosted
333 | version: "0.11.4"
334 | matcher:
335 | dependency: transitive
336 | description:
337 | name: matcher
338 | url: "https://pub.dartlang.org"
339 | source: hosted
340 | version: "0.12.10-nullsafety.1"
341 | meta:
342 | dependency: transitive
343 | description:
344 | name: meta
345 | url: "https://pub.dartlang.org"
346 | source: hosted
347 | version: "1.3.0-nullsafety.3"
348 | mime:
349 | dependency: transitive
350 | description:
351 | name: mime
352 | url: "https://pub.dartlang.org"
353 | source: hosted
354 | version: "0.9.7"
355 | mobx:
356 | dependency: "direct main"
357 | description:
358 | name: mobx
359 | url: "https://pub.dartlang.org"
360 | source: hosted
361 | version: "1.2.1+4"
362 | mobx_codegen:
363 | dependency: "direct dev"
364 | description:
365 | name: mobx_codegen
366 | url: "https://pub.dartlang.org"
367 | source: hosted
368 | version: "1.1.2"
369 | mockito:
370 | dependency: "direct dev"
371 | description:
372 | name: mockito
373 | url: "https://pub.dartlang.org"
374 | source: hosted
375 | version: "4.1.3"
376 | modular_codegen:
377 | dependency: "direct dev"
378 | description:
379 | name: modular_codegen
380 | url: "https://pub.dartlang.org"
381 | source: hosted
382 | version: "2.0.1"
383 | node_interop:
384 | dependency: transitive
385 | description:
386 | name: node_interop
387 | url: "https://pub.dartlang.org"
388 | source: hosted
389 | version: "1.2.0"
390 | node_io:
391 | dependency: transitive
392 | description:
393 | name: node_io
394 | url: "https://pub.dartlang.org"
395 | source: hosted
396 | version: "1.1.1"
397 | package_config:
398 | dependency: transitive
399 | description:
400 | name: package_config
401 | url: "https://pub.dartlang.org"
402 | source: hosted
403 | version: "1.9.3"
404 | path:
405 | dependency: transitive
406 | description:
407 | name: path
408 | url: "https://pub.dartlang.org"
409 | source: hosted
410 | version: "1.8.0-nullsafety.1"
411 | path_provider:
412 | dependency: transitive
413 | description:
414 | name: path_provider
415 | url: "https://pub.dartlang.org"
416 | source: hosted
417 | version: "1.6.24"
418 | path_provider_linux:
419 | dependency: transitive
420 | description:
421 | name: path_provider_linux
422 | url: "https://pub.dartlang.org"
423 | source: hosted
424 | version: "0.0.1+2"
425 | path_provider_macos:
426 | dependency: transitive
427 | description:
428 | name: path_provider_macos
429 | url: "https://pub.dartlang.org"
430 | source: hosted
431 | version: "0.0.4+6"
432 | path_provider_platform_interface:
433 | dependency: transitive
434 | description:
435 | name: path_provider_platform_interface
436 | url: "https://pub.dartlang.org"
437 | source: hosted
438 | version: "1.0.4"
439 | path_provider_windows:
440 | dependency: transitive
441 | description:
442 | name: path_provider_windows
443 | url: "https://pub.dartlang.org"
444 | source: hosted
445 | version: "0.0.4+3"
446 | pedantic:
447 | dependency: transitive
448 | description:
449 | name: pedantic
450 | url: "https://pub.dartlang.org"
451 | source: hosted
452 | version: "1.9.2"
453 | petitparser:
454 | dependency: transitive
455 | description:
456 | name: petitparser
457 | url: "https://pub.dartlang.org"
458 | source: hosted
459 | version: "3.1.0"
460 | platform:
461 | dependency: transitive
462 | description:
463 | name: platform
464 | url: "https://pub.dartlang.org"
465 | source: hosted
466 | version: "2.2.1"
467 | plugin_platform_interface:
468 | dependency: transitive
469 | description:
470 | name: plugin_platform_interface
471 | url: "https://pub.dartlang.org"
472 | source: hosted
473 | version: "1.0.3"
474 | pool:
475 | dependency: transitive
476 | description:
477 | name: pool
478 | url: "https://pub.dartlang.org"
479 | source: hosted
480 | version: "1.4.0"
481 | process:
482 | dependency: transitive
483 | description:
484 | name: process
485 | url: "https://pub.dartlang.org"
486 | source: hosted
487 | version: "3.0.13"
488 | pub_semver:
489 | dependency: transitive
490 | description:
491 | name: pub_semver
492 | url: "https://pub.dartlang.org"
493 | source: hosted
494 | version: "1.4.4"
495 | pubspec_parse:
496 | dependency: transitive
497 | description:
498 | name: pubspec_parse
499 | url: "https://pub.dartlang.org"
500 | source: hosted
501 | version: "0.1.5"
502 | quiver:
503 | dependency: transitive
504 | description:
505 | name: quiver
506 | url: "https://pub.dartlang.org"
507 | source: hosted
508 | version: "2.1.5"
509 | rxdart:
510 | dependency: "direct main"
511 | description:
512 | name: rxdart
513 | url: "https://pub.dartlang.org"
514 | source: hosted
515 | version: "0.24.1"
516 | shared_preferences:
517 | dependency: "direct main"
518 | description:
519 | name: shared_preferences
520 | url: "https://pub.dartlang.org"
521 | source: hosted
522 | version: "0.5.12+4"
523 | shared_preferences_linux:
524 | dependency: transitive
525 | description:
526 | name: shared_preferences_linux
527 | url: "https://pub.dartlang.org"
528 | source: hosted
529 | version: "0.0.2+4"
530 | shared_preferences_macos:
531 | dependency: transitive
532 | description:
533 | name: shared_preferences_macos
534 | url: "https://pub.dartlang.org"
535 | source: hosted
536 | version: "0.0.1+11"
537 | shared_preferences_platform_interface:
538 | dependency: transitive
539 | description:
540 | name: shared_preferences_platform_interface
541 | url: "https://pub.dartlang.org"
542 | source: hosted
543 | version: "1.0.4"
544 | shared_preferences_web:
545 | dependency: transitive
546 | description:
547 | name: shared_preferences_web
548 | url: "https://pub.dartlang.org"
549 | source: hosted
550 | version: "0.1.2+7"
551 | shared_preferences_windows:
552 | dependency: transitive
553 | description:
554 | name: shared_preferences_windows
555 | url: "https://pub.dartlang.org"
556 | source: hosted
557 | version: "0.0.1+3"
558 | shelf:
559 | dependency: transitive
560 | description:
561 | name: shelf
562 | url: "https://pub.dartlang.org"
563 | source: hosted
564 | version: "0.7.9"
565 | shelf_web_socket:
566 | dependency: transitive
567 | description:
568 | name: shelf_web_socket
569 | url: "https://pub.dartlang.org"
570 | source: hosted
571 | version: "0.2.3"
572 | sky_engine:
573 | dependency: transitive
574 | description: flutter
575 | source: sdk
576 | version: "0.0.99"
577 | source_gen:
578 | dependency: transitive
579 | description:
580 | name: source_gen
581 | url: "https://pub.dartlang.org"
582 | source: hosted
583 | version: "0.9.8"
584 | source_span:
585 | dependency: transitive
586 | description:
587 | name: source_span
588 | url: "https://pub.dartlang.org"
589 | source: hosted
590 | version: "1.8.0-nullsafety.2"
591 | stack_trace:
592 | dependency: transitive
593 | description:
594 | name: stack_trace
595 | url: "https://pub.dartlang.org"
596 | source: hosted
597 | version: "1.10.0-nullsafety.1"
598 | stream_channel:
599 | dependency: transitive
600 | description:
601 | name: stream_channel
602 | url: "https://pub.dartlang.org"
603 | source: hosted
604 | version: "2.1.0-nullsafety.1"
605 | stream_transform:
606 | dependency: transitive
607 | description:
608 | name: stream_transform
609 | url: "https://pub.dartlang.org"
610 | source: hosted
611 | version: "1.2.0"
612 | string_scanner:
613 | dependency: transitive
614 | description:
615 | name: string_scanner
616 | url: "https://pub.dartlang.org"
617 | source: hosted
618 | version: "1.1.0-nullsafety.1"
619 | term_glyph:
620 | dependency: transitive
621 | description:
622 | name: term_glyph
623 | url: "https://pub.dartlang.org"
624 | source: hosted
625 | version: "1.2.0-nullsafety.1"
626 | test_api:
627 | dependency: transitive
628 | description:
629 | name: test_api
630 | url: "https://pub.dartlang.org"
631 | source: hosted
632 | version: "0.2.19-nullsafety.2"
633 | timing:
634 | dependency: transitive
635 | description:
636 | name: timing
637 | url: "https://pub.dartlang.org"
638 | source: hosted
639 | version: "0.1.1+2"
640 | typed_data:
641 | dependency: transitive
642 | description:
643 | name: typed_data
644 | url: "https://pub.dartlang.org"
645 | source: hosted
646 | version: "1.3.0-nullsafety.3"
647 | uuid:
648 | dependency: transitive
649 | description:
650 | name: uuid
651 | url: "https://pub.dartlang.org"
652 | source: hosted
653 | version: "2.2.2"
654 | vector_math:
655 | dependency: transitive
656 | description:
657 | name: vector_math
658 | url: "https://pub.dartlang.org"
659 | source: hosted
660 | version: "2.1.0-nullsafety.3"
661 | watcher:
662 | dependency: transitive
663 | description:
664 | name: watcher
665 | url: "https://pub.dartlang.org"
666 | source: hosted
667 | version: "0.9.7+15"
668 | web_socket_channel:
669 | dependency: transitive
670 | description:
671 | name: web_socket_channel
672 | url: "https://pub.dartlang.org"
673 | source: hosted
674 | version: "1.1.0"
675 | win32:
676 | dependency: transitive
677 | description:
678 | name: win32
679 | url: "https://pub.dartlang.org"
680 | source: hosted
681 | version: "1.7.4"
682 | xdg_directories:
683 | dependency: transitive
684 | description:
685 | name: xdg_directories
686 | url: "https://pub.dartlang.org"
687 | source: hosted
688 | version: "0.1.2"
689 | xml:
690 | dependency: transitive
691 | description:
692 | name: xml
693 | url: "https://pub.dartlang.org"
694 | source: hosted
695 | version: "4.5.1"
696 | yaml:
697 | dependency: transitive
698 | description:
699 | name: yaml
700 | url: "https://pub.dartlang.org"
701 | source: hosted
702 | version: "2.2.1"
703 | sdks:
704 | dart: ">=2.10.0 <2.11.0"
705 | flutter: ">=1.12.13+hotfix.6 <2.0.0"
706 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXCopyFilesBuildPhase section */
19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
20 | isa = PBXCopyFilesBuildPhase;
21 | buildActionMask = 2147483647;
22 | dstPath = "";
23 | dstSubfolderSpec = 10;
24 | files = (
25 | );
26 | name = "Embed Frameworks";
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXCopyFilesBuildPhase section */
30 |
31 | /* Begin PBXFileReference section */
32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | );
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXFrameworksBuildPhase section */
56 |
57 | /* Begin PBXGroup section */
58 | 9740EEB11CF90186004384FC /* Flutter */ = {
59 | isa = PBXGroup;
60 | children = (
61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
65 | );
66 | name = Flutter;
67 | sourceTree = "";
68 | };
69 | 97C146E51CF9000F007C117D = {
70 | isa = PBXGroup;
71 | children = (
72 | 9740EEB11CF90186004384FC /* Flutter */,
73 | 97C146F01CF9000F007C117D /* Runner */,
74 | 97C146EF1CF9000F007C117D /* Products */,
75 | );
76 | sourceTree = "";
77 | };
78 | 97C146EF1CF9000F007C117D /* Products */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 97C146EE1CF9000F007C117D /* Runner.app */,
82 | );
83 | name = Products;
84 | sourceTree = "";
85 | };
86 | 97C146F01CF9000F007C117D /* Runner */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
92 | 97C147021CF9000F007C117D /* Info.plist */,
93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
97 | );
98 | path = Runner;
99 | sourceTree = "";
100 | };
101 | /* End PBXGroup section */
102 |
103 | /* Begin PBXNativeTarget section */
104 | 97C146ED1CF9000F007C117D /* Runner */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
107 | buildPhases = (
108 | 9740EEB61CF901F6004384FC /* Run Script */,
109 | 97C146EA1CF9000F007C117D /* Sources */,
110 | 97C146EB1CF9000F007C117D /* Frameworks */,
111 | 97C146EC1CF9000F007C117D /* Resources */,
112 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
114 | );
115 | buildRules = (
116 | );
117 | dependencies = (
118 | );
119 | name = Runner;
120 | productName = Runner;
121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
122 | productType = "com.apple.product-type.application";
123 | };
124 | /* End PBXNativeTarget section */
125 |
126 | /* Begin PBXProject section */
127 | 97C146E61CF9000F007C117D /* Project object */ = {
128 | isa = PBXProject;
129 | attributes = {
130 | LastUpgradeCheck = 1020;
131 | ORGANIZATIONNAME = "";
132 | TargetAttributes = {
133 | 97C146ED1CF9000F007C117D = {
134 | CreatedOnToolsVersion = 7.3.1;
135 | LastSwiftMigration = 1100;
136 | };
137 | };
138 | };
139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
140 | compatibilityVersion = "Xcode 9.3";
141 | developmentRegion = en;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | Base,
146 | );
147 | mainGroup = 97C146E51CF9000F007C117D;
148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
149 | projectDirPath = "";
150 | projectRoot = "";
151 | targets = (
152 | 97C146ED1CF9000F007C117D /* Runner */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXResourcesBuildPhase section */
158 | 97C146EC1CF9000F007C117D /* Resources */ = {
159 | isa = PBXResourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXShellScriptBuildPhase section */
172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
173 | isa = PBXShellScriptBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | );
177 | inputPaths = (
178 | );
179 | name = "Thin Binary";
180 | outputPaths = (
181 | );
182 | runOnlyForDeploymentPostprocessing = 0;
183 | shellPath = /bin/sh;
184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
185 | };
186 | 9740EEB61CF901F6004384FC /* Run Script */ = {
187 | isa = PBXShellScriptBuildPhase;
188 | buildActionMask = 2147483647;
189 | files = (
190 | );
191 | inputPaths = (
192 | );
193 | name = "Run Script";
194 | outputPaths = (
195 | );
196 | runOnlyForDeploymentPostprocessing = 0;
197 | shellPath = /bin/sh;
198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
199 | };
200 | /* End PBXShellScriptBuildPhase section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 97C146EA1CF9000F007C117D /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXSourcesBuildPhase section */
213 |
214 | /* Begin PBXVariantGroup section */
215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
216 | isa = PBXVariantGroup;
217 | children = (
218 | 97C146FB1CF9000F007C117D /* Base */,
219 | );
220 | name = Main.storyboard;
221 | sourceTree = "";
222 | };
223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
224 | isa = PBXVariantGroup;
225 | children = (
226 | 97C147001CF9000F007C117D /* Base */,
227 | );
228 | name = LaunchScreen.storyboard;
229 | sourceTree = "";
230 | };
231 | /* End PBXVariantGroup section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
240 | CLANG_CXX_LIBRARY = "libc++";
241 | CLANG_ENABLE_MODULES = YES;
242 | CLANG_ENABLE_OBJC_ARC = YES;
243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
244 | CLANG_WARN_BOOL_CONVERSION = YES;
245 | CLANG_WARN_COMMA = YES;
246 | CLANG_WARN_CONSTANT_CONVERSION = YES;
247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
249 | CLANG_WARN_EMPTY_BODY = YES;
250 | CLANG_WARN_ENUM_CONVERSION = YES;
251 | CLANG_WARN_INFINITE_RECURSION = YES;
252 | CLANG_WARN_INT_CONVERSION = YES;
253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
258 | CLANG_WARN_STRICT_PROTOTYPES = YES;
259 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
260 | CLANG_WARN_UNREACHABLE_CODE = YES;
261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
263 | COPY_PHASE_STRIP = NO;
264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
265 | ENABLE_NS_ASSERTIONS = NO;
266 | ENABLE_STRICT_OBJC_MSGSEND = YES;
267 | GCC_C_LANGUAGE_STANDARD = gnu99;
268 | GCC_NO_COMMON_BLOCKS = YES;
269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
271 | GCC_WARN_UNDECLARED_SELECTOR = YES;
272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
273 | GCC_WARN_UNUSED_FUNCTION = YES;
274 | GCC_WARN_UNUSED_VARIABLE = YES;
275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
276 | MTL_ENABLE_DEBUG_INFO = NO;
277 | SDKROOT = iphoneos;
278 | SUPPORTED_PLATFORMS = iphoneos;
279 | TARGETED_DEVICE_FAMILY = "1,2";
280 | VALIDATE_PRODUCT = YES;
281 | };
282 | name = Profile;
283 | };
284 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
285 | isa = XCBuildConfiguration;
286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
287 | buildSettings = {
288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
289 | CLANG_ENABLE_MODULES = YES;
290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
291 | ENABLE_BITCODE = NO;
292 | FRAMEWORK_SEARCH_PATHS = (
293 | "$(inherited)",
294 | "$(PROJECT_DIR)/Flutter",
295 | );
296 | INFOPLIST_FILE = Runner/Info.plist;
297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
298 | LIBRARY_SEARCH_PATHS = (
299 | "$(inherited)",
300 | "$(PROJECT_DIR)/Flutter",
301 | );
302 | PRODUCT_BUNDLE_IDENTIFIER = com.alamedapps.flowpdcApp;
303 | PRODUCT_NAME = "$(TARGET_NAME)";
304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
305 | SWIFT_VERSION = 5.0;
306 | VERSIONING_SYSTEM = "apple-generic";
307 | };
308 | name = Profile;
309 | };
310 | 97C147031CF9000F007C117D /* Debug */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | ALWAYS_SEARCH_USER_PATHS = NO;
314 | CLANG_ANALYZER_NONNULL = YES;
315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
316 | CLANG_CXX_LIBRARY = "libc++";
317 | CLANG_ENABLE_MODULES = YES;
318 | CLANG_ENABLE_OBJC_ARC = YES;
319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
320 | CLANG_WARN_BOOL_CONVERSION = YES;
321 | CLANG_WARN_COMMA = YES;
322 | CLANG_WARN_CONSTANT_CONVERSION = YES;
323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
325 | CLANG_WARN_EMPTY_BODY = YES;
326 | CLANG_WARN_ENUM_CONVERSION = YES;
327 | CLANG_WARN_INFINITE_RECURSION = YES;
328 | CLANG_WARN_INT_CONVERSION = YES;
329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
334 | CLANG_WARN_STRICT_PROTOTYPES = YES;
335 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
336 | CLANG_WARN_UNREACHABLE_CODE = YES;
337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
339 | COPY_PHASE_STRIP = NO;
340 | DEBUG_INFORMATION_FORMAT = dwarf;
341 | ENABLE_STRICT_OBJC_MSGSEND = YES;
342 | ENABLE_TESTABILITY = YES;
343 | GCC_C_LANGUAGE_STANDARD = gnu99;
344 | GCC_DYNAMIC_NO_PIC = NO;
345 | GCC_NO_COMMON_BLOCKS = YES;
346 | GCC_OPTIMIZATION_LEVEL = 0;
347 | GCC_PREPROCESSOR_DEFINITIONS = (
348 | "DEBUG=1",
349 | "$(inherited)",
350 | );
351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
353 | GCC_WARN_UNDECLARED_SELECTOR = YES;
354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
355 | GCC_WARN_UNUSED_FUNCTION = YES;
356 | GCC_WARN_UNUSED_VARIABLE = YES;
357 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
358 | MTL_ENABLE_DEBUG_INFO = YES;
359 | ONLY_ACTIVE_ARCH = YES;
360 | SDKROOT = iphoneos;
361 | TARGETED_DEVICE_FAMILY = "1,2";
362 | };
363 | name = Debug;
364 | };
365 | 97C147041CF9000F007C117D /* Release */ = {
366 | isa = XCBuildConfiguration;
367 | buildSettings = {
368 | ALWAYS_SEARCH_USER_PATHS = NO;
369 | CLANG_ANALYZER_NONNULL = YES;
370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
371 | CLANG_CXX_LIBRARY = "libc++";
372 | CLANG_ENABLE_MODULES = YES;
373 | CLANG_ENABLE_OBJC_ARC = YES;
374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
375 | CLANG_WARN_BOOL_CONVERSION = YES;
376 | CLANG_WARN_COMMA = YES;
377 | CLANG_WARN_CONSTANT_CONVERSION = YES;
378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
380 | CLANG_WARN_EMPTY_BODY = YES;
381 | CLANG_WARN_ENUM_CONVERSION = YES;
382 | CLANG_WARN_INFINITE_RECURSION = YES;
383 | CLANG_WARN_INT_CONVERSION = YES;
384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
389 | CLANG_WARN_STRICT_PROTOTYPES = YES;
390 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
391 | CLANG_WARN_UNREACHABLE_CODE = YES;
392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
394 | COPY_PHASE_STRIP = NO;
395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
396 | ENABLE_NS_ASSERTIONS = NO;
397 | ENABLE_STRICT_OBJC_MSGSEND = YES;
398 | GCC_C_LANGUAGE_STANDARD = gnu99;
399 | GCC_NO_COMMON_BLOCKS = YES;
400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
402 | GCC_WARN_UNDECLARED_SELECTOR = YES;
403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
404 | GCC_WARN_UNUSED_FUNCTION = YES;
405 | GCC_WARN_UNUSED_VARIABLE = YES;
406 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
407 | MTL_ENABLE_DEBUG_INFO = NO;
408 | SDKROOT = iphoneos;
409 | SUPPORTED_PLATFORMS = iphoneos;
410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
411 | TARGETED_DEVICE_FAMILY = "1,2";
412 | VALIDATE_PRODUCT = YES;
413 | };
414 | name = Release;
415 | };
416 | 97C147061CF9000F007C117D /* Debug */ = {
417 | isa = XCBuildConfiguration;
418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
419 | buildSettings = {
420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
421 | CLANG_ENABLE_MODULES = YES;
422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
423 | ENABLE_BITCODE = NO;
424 | FRAMEWORK_SEARCH_PATHS = (
425 | "$(inherited)",
426 | "$(PROJECT_DIR)/Flutter",
427 | );
428 | INFOPLIST_FILE = Runner/Info.plist;
429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
430 | LIBRARY_SEARCH_PATHS = (
431 | "$(inherited)",
432 | "$(PROJECT_DIR)/Flutter",
433 | );
434 | PRODUCT_BUNDLE_IDENTIFIER = com.alamedapps.flowpdcApp;
435 | PRODUCT_NAME = "$(TARGET_NAME)";
436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
438 | SWIFT_VERSION = 5.0;
439 | VERSIONING_SYSTEM = "apple-generic";
440 | };
441 | name = Debug;
442 | };
443 | 97C147071CF9000F007C117D /* Release */ = {
444 | isa = XCBuildConfiguration;
445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
446 | buildSettings = {
447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
448 | CLANG_ENABLE_MODULES = YES;
449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
450 | ENABLE_BITCODE = NO;
451 | FRAMEWORK_SEARCH_PATHS = (
452 | "$(inherited)",
453 | "$(PROJECT_DIR)/Flutter",
454 | );
455 | INFOPLIST_FILE = Runner/Info.plist;
456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
457 | LIBRARY_SEARCH_PATHS = (
458 | "$(inherited)",
459 | "$(PROJECT_DIR)/Flutter",
460 | );
461 | PRODUCT_BUNDLE_IDENTIFIER = com.alamedapps.flowpdcApp;
462 | PRODUCT_NAME = "$(TARGET_NAME)";
463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
464 | SWIFT_VERSION = 5.0;
465 | VERSIONING_SYSTEM = "apple-generic";
466 | };
467 | name = Release;
468 | };
469 | /* End XCBuildConfiguration section */
470 |
471 | /* Begin XCConfigurationList section */
472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
473 | isa = XCConfigurationList;
474 | buildConfigurations = (
475 | 97C147031CF9000F007C117D /* Debug */,
476 | 97C147041CF9000F007C117D /* Release */,
477 | 249021D3217E4FDB00AE95B9 /* Profile */,
478 | );
479 | defaultConfigurationIsVisible = 0;
480 | defaultConfigurationName = Release;
481 | };
482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
483 | isa = XCConfigurationList;
484 | buildConfigurations = (
485 | 97C147061CF9000F007C117D /* Debug */,
486 | 97C147071CF9000F007C117D /* Release */,
487 | 249021D4217E4FDB00AE95B9 /* Profile */,
488 | );
489 | defaultConfigurationIsVisible = 0;
490 | defaultConfigurationName = Release;
491 | };
492 | /* End XCConfigurationList section */
493 | };
494 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
495 | }
--------------------------------------------------------------------------------