├── android ├── gradle.properties ├── app │ ├── src │ │ ├── main │ │ │ ├── res │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values │ │ │ │ │ └── styles.xml │ │ │ │ └── drawable │ │ │ │ │ └── launch_background.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── juvetic │ │ │ │ │ └── card_app │ │ │ │ │ └── MainActivity.kt │ │ │ └── AndroidManifest.xml │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ └── profile │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── settings.gradle └── build.gradle ├── 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 │ ├── Info.plist │ └── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard ├── Runner.xcworkspace │ └── contents.xcworkspacedata └── Runner.xcodeproj │ ├── project.xcworkspace │ └── contents.xcworkspacedata │ ├── xcshareddata │ └── xcschemes │ │ └── Runner.xcscheme │ └── project.pbxproj ├── screenshot ├── list.png ├── darkmode.png ├── spellcard.png ├── trapcard.png ├── monstercard.png └── monstercarddark.png ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ └── feature_request.md ├── .metadata ├── lib ├── utils │ ├── constants.dart │ └── size_config.dart ├── serializers │ ├── card_image.dart │ ├── card_set.dart │ ├── card_price.dart │ └── card.dart ├── models │ ├── settings.dart │ ├── settings.g.dart │ ├── cards.dart │ ├── monsters.dart │ ├── cards.g.dart │ └── monsters.g.dart ├── data │ ├── api_service.dart │ └── api_service.chopper.dart ├── services │ └── preferences_service.dart ├── widgets │ └── themeable_app.dart ├── screens │ ├── settings_page.dart │ ├── home.dart │ ├── all_cards_page.dart │ ├── monster_cards_page.dart │ └── card_detail_page.dart └── main.dart ├── LICENSE ├── test └── widget_test.dart ├── .gitignore ├── README.md ├── pubspec.yaml └── pubspec.lock /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /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" -------------------------------------------------------------------------------- /screenshot/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/list.png -------------------------------------------------------------------------------- /screenshot/darkmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/darkmode.png -------------------------------------------------------------------------------- /screenshot/spellcard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/spellcard.png -------------------------------------------------------------------------------- /screenshot/trapcard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/trapcard.png -------------------------------------------------------------------------------- /screenshot/monstercard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/monstercard.png -------------------------------------------------------------------------------- /screenshot/monstercarddark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/screenshot/monstercarddark.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/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/fikrirazzaq/YugiohCards/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 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-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /.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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/juvetic/card_app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.juvetic.card_app 2 | 3 | import android.os.Bundle 4 | 5 | import io.flutter.app.FlutterActivity 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun onCreate(savedInstanceState: Bundle?) { 10 | super.onCreate(savedInstanceState) 11 | GeneratedPluginRegistrant.registerWith(this) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /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: [UIApplicationLaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/utils/constants.dart: -------------------------------------------------------------------------------- 1 | class Constants { 2 | static String cardList = "https://db.ygoprodeck.com/api/v5/cardinfo.php"; 3 | 4 | static String imgArchetype = "https://ygoprodeck.com/pics/icons/archetype.png"; 5 | static String imgLevelUrl = "https://ygoprodeck.com/wp-content/uploads/2017/01/level.png"; 6 | static String imgTypeUrl = "https://ygoprodeck.com/pics/icons/"; 7 | static String imgSpellTypeUrl = "https://ygoprodeck.com/pics/icons/"; 8 | static String imgMonsterTypeUrl = "https://ygoprodeck.com/pics/"; 9 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /lib/serializers/card_image.dart: -------------------------------------------------------------------------------- 1 | class CardImages { 2 | String id; 3 | String imageUrl; 4 | String imageUrlSmall; 5 | 6 | CardImages({this.id, this.imageUrl, this.imageUrlSmall}); 7 | 8 | CardImages.fromJson(Map json) { 9 | id = json['id']; 10 | imageUrl = json['image_url']; 11 | imageUrlSmall = json['image_url_small']; 12 | } 13 | 14 | Map toJson() { 15 | final Map data = new Map(); 16 | data['id'] = this.id; 17 | data['image_url'] = this.imageUrl; 18 | data['image_url_small'] = this.imageUrlSmall; 19 | return data; 20 | } 21 | } -------------------------------------------------------------------------------- /lib/models/settings.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/services/preferences_service.dart'; 2 | import 'package:mobx/mobx.dart'; 3 | 4 | part 'settings.g.dart'; 5 | 6 | class Settings = SettingsBase with _$Settings; 7 | 8 | abstract class SettingsBase with Store { 9 | PreferencesService _preferencesService; 10 | 11 | @observable 12 | bool useDarkMode; 13 | 14 | SettingsBase(this._preferencesService) { 15 | useDarkMode = _preferencesService.useDarkMode; 16 | } 17 | 18 | @action 19 | void setDarkMode(bool updatedDarkModePref) { 20 | _preferencesService.useDarkMode = updatedDarkModePref; 21 | useDarkMode = updatedDarkModePref; 22 | } 23 | } -------------------------------------------------------------------------------- /lib/data/api_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:chopper/chopper.dart'; 2 | 3 | part 'api_service.chopper.dart'; 4 | 5 | @ChopperApi(baseUrl: '/cardinfo.php') 6 | abstract class ApiService extends ChopperService { 7 | 8 | @Get() 9 | Future getAllCards(@Query('num') int num); 10 | 11 | @Get() 12 | Future getMonsterCards(@Query('num') int num, @Query('type') String type); 13 | 14 | static ApiService create() { 15 | final client = ChopperClient( 16 | baseUrl: 'https://db.ygoprodeck.com/api/v5', 17 | services: [ 18 | _$ApiService(), 19 | ], 20 | interceptors: [HttpLoggingInterceptor()], 21 | ); 22 | return _$ApiService(client); 23 | } 24 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.2.71' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.2.1' 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 | -------------------------------------------------------------------------------- /lib/serializers/card_set.dart: -------------------------------------------------------------------------------- 1 | class CardSets { 2 | String setName; 3 | String setCode; 4 | String setRarity; 5 | String setPrice; 6 | 7 | CardSets({this.setName, this.setCode, this.setRarity, this.setPrice}); 8 | 9 | CardSets.fromJson(Map json) { 10 | setName = json['set_name']; 11 | setCode = json['set_code']; 12 | setRarity = json['set_rarity']; 13 | setPrice = json['set_price']; 14 | } 15 | 16 | Map toJson() { 17 | final Map data = new Map(); 18 | data['set_name'] = this.setName; 19 | data['set_code'] = this.setCode; 20 | data['set_rarity'] = this.setRarity; 21 | data['set_price'] = this.setPrice; 22 | return data; 23 | } 24 | } -------------------------------------------------------------------------------- /lib/services/preferences_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:shared_preferences/shared_preferences.dart'; 2 | 3 | class PreferencesService { 4 | final String _useDarkModeKey = 'useDarkMode'; 5 | final String _favouritesKey = 'favourites'; 6 | 7 | final SharedPreferences _sharedPreferences; 8 | 9 | const PreferencesService(this._sharedPreferences); 10 | 11 | set useDarkMode(bool useDarkMode) { 12 | _sharedPreferences.setBool(_useDarkModeKey, useDarkMode); 13 | } 14 | 15 | bool get useDarkMode => _sharedPreferences.getBool(_useDarkModeKey) ?? false; 16 | 17 | set favourites(List favourites) { 18 | _sharedPreferences.setStringList(_favouritesKey, favourites); 19 | } 20 | 21 | List get favourites => 22 | _sharedPreferences.getStringList(_favouritesKey) ?? List(); 23 | } -------------------------------------------------------------------------------- /lib/widgets/themeable_app.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/models/settings.dart'; 2 | import 'package:card_app/screens/home.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_mobx/flutter_mobx.dart'; 5 | 6 | class ThemeableApp extends StatelessWidget { 7 | final Settings settings; 8 | ThemeableApp(this.settings, {Key key}) : super(key: key); 9 | 10 | @override 11 | Widget build(BuildContext context) { 12 | return Observer( 13 | builder: (_) { 14 | var themeData = ThemeData( 15 | brightness: settings.useDarkMode == true ? Brightness.dark : Brightness.light, 16 | primarySwatch: Colors.orange, 17 | ); 18 | return MaterialApp( 19 | title: 'Yugioh Cards', 20 | theme: themeData, 21 | home: Home(), 22 | ); 23 | }, 24 | ); 25 | } 26 | } -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/serializers/card_price.dart: -------------------------------------------------------------------------------- 1 | class CardPrices { 2 | String cardmarketPrice; 3 | String tcgplayerPrice; 4 | String ebayPrice; 5 | String amazonPrice; 6 | 7 | CardPrices( 8 | {this.cardmarketPrice, 9 | this.tcgplayerPrice, 10 | this.ebayPrice, 11 | this.amazonPrice}); 12 | 13 | CardPrices.fromJson(Map json) { 14 | cardmarketPrice = json['cardmarket_price']; 15 | tcgplayerPrice = json['tcgplayer_price']; 16 | ebayPrice = json['ebay_price']; 17 | amazonPrice = json['amazon_price']; 18 | } 19 | 20 | Map toJson() { 21 | final Map data = new Map(); 22 | data['cardmarket_price'] = this.cardmarketPrice; 23 | data['tcgplayer_price'] = this.tcgplayerPrice; 24 | data['ebay_price'] = this.ebayPrice; 25 | data['amazon_price'] = this.amazonPrice; 26 | return data; 27 | } 28 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Fikri Razzaq 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/data/api_service.chopper.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'api_service.dart'; 4 | 5 | // ************************************************************************** 6 | // ChopperGenerator 7 | // ************************************************************************** 8 | 9 | class _$ApiService extends ApiService { 10 | _$ApiService([ChopperClient client]) { 11 | if (client == null) return; 12 | this.client = client; 13 | } 14 | 15 | final definitionType = ApiService; 16 | 17 | Future getAllCards(int num) { 18 | final $url = '/cardinfo.php'; 19 | final Map $params = {'num': num}; 20 | final $request = Request('GET', $url, client.baseUrl, parameters: $params); 21 | return client.send($request); 22 | } 23 | 24 | Future getMonsterCards(int num, String type) { 25 | final $url = '/cardinfo.php'; 26 | final Map $params = {'num': num, 'type': type}; 27 | final $request = Request('GET', $url, client.baseUrl, parameters: $params); 28 | return client.send($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:card_app/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/utils/size_config.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/widgets.dart'; 2 | 3 | class SizeConfig { 4 | static MediaQueryData _mediaQueryData; 5 | static double screenWidth; 6 | static double screenHeight; 7 | static double blockSizeHorizontal; 8 | static double blockSizeVertical; 9 | 10 | static double _safeAreaHorizontal; 11 | static double _safeAreaVertical; 12 | static double safeBlockHorizontal; 13 | static double safeBlockVertical; 14 | 15 | static double safeAreaHeight; 16 | 17 | void init(BuildContext context) { 18 | _mediaQueryData = MediaQuery.of(context); 19 | screenWidth = _mediaQueryData.size.width; 20 | screenHeight = _mediaQueryData.size.height; 21 | blockSizeHorizontal = screenWidth / 100; 22 | blockSizeVertical = screenHeight / 100; 23 | 24 | _safeAreaHorizontal = 25 | _mediaQueryData.padding.left + _mediaQueryData.padding.right; 26 | _safeAreaVertical = 27 | _mediaQueryData.padding.top + _mediaQueryData.padding.bottom; 28 | safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 100; 29 | safeBlockVertical = (screenHeight - _safeAreaVertical) / 100; 30 | safeAreaHeight = screenHeight - _safeAreaVertical; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/screens/settings_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/models/settings.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_mobx/flutter_mobx.dart'; 4 | import 'package:provider/provider.dart'; 5 | 6 | class SettingsPage extends StatefulWidget { 7 | @override 8 | _SettingsPageState createState() => _SettingsPageState(); 9 | } 10 | 11 | class _SettingsPageState extends State 12 | with AutomaticKeepAliveClientMixin { 13 | @override 14 | Widget build(BuildContext context) { 15 | super.build(context); 16 | 17 | return Consumer( 18 | builder: (context, value, _) => Scaffold( 19 | appBar: AppBar( 20 | title: Text("Settings"), 21 | ), 22 | body: Column( 23 | children: [ 24 | Observer( 25 | builder: (_) => Padding( 26 | padding: EdgeInsets.only(bottom: 16), 27 | child: SwitchListTile( 28 | title: Text("Dark mode"), 29 | subtitle: Text("Use dark mode layout"), 30 | value: value.useDarkMode, 31 | onChanged: (bool val) { 32 | value.setDarkMode(val); 33 | }, 34 | ), 35 | ), 36 | ), 37 | ], 38 | ), 39 | ), 40 | ); 41 | } 42 | 43 | @override 44 | bool get wantKeepAlive => true; 45 | } 46 | -------------------------------------------------------------------------------- /lib/models/settings.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'settings.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars 10 | 11 | mixin _$Settings on SettingsBase, Store { 12 | final _$useDarkModeAtom = Atom(name: 'SettingsBase.useDarkMode'); 13 | 14 | @override 15 | bool get useDarkMode { 16 | _$useDarkModeAtom.context.enforceReadPolicy(_$useDarkModeAtom); 17 | _$useDarkModeAtom.reportObserved(); 18 | return super.useDarkMode; 19 | } 20 | 21 | @override 22 | set useDarkMode(bool value) { 23 | _$useDarkModeAtom.context.conditionallyRunInAction(() { 24 | super.useDarkMode = value; 25 | _$useDarkModeAtom.reportChanged(); 26 | }, _$useDarkModeAtom, name: '${_$useDarkModeAtom.name}_set'); 27 | } 28 | 29 | final _$SettingsBaseActionController = ActionController(name: 'SettingsBase'); 30 | 31 | @override 32 | void setDarkMode(bool updatedDarkModePref) { 33 | final _$actionInfo = _$SettingsBaseActionController.startAction(); 34 | try { 35 | return super.setDarkMode(updatedDarkModePref); 36 | } finally { 37 | _$SettingsBaseActionController.endAction(_$actionInfo); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # Visual Studio Code related 19 | .vscode/ 20 | 21 | # Flutter/Dart/Pub related 22 | **/doc/api/ 23 | .dart_tool/ 24 | .flutter-plugins 25 | .packages 26 | .pub-cache/ 27 | .pub/ 28 | /build/ 29 | 30 | # Android related 31 | **/android/**/gradle-wrapper.jar 32 | **/android/.gradle 33 | **/android/captures/ 34 | **/android/gradlew 35 | **/android/gradlew.bat 36 | **/android/local.properties 37 | **/android/**/GeneratedPluginRegistrant.java 38 | 39 | # iOS/XCode related 40 | **/ios/**/*.mode1v3 41 | **/ios/**/*.mode2v3 42 | **/ios/**/*.moved-aside 43 | **/ios/**/*.pbxuser 44 | **/ios/**/*.perspectivev3 45 | **/ios/**/*sync/ 46 | **/ios/**/.sconsign.dblite 47 | **/ios/**/.tags* 48 | **/ios/**/.vagrant/ 49 | **/ios/**/DerivedData/ 50 | **/ios/**/Icon? 51 | **/ios/**/Pods/ 52 | **/ios/**/.symlinks/ 53 | **/ios/**/profile 54 | **/ios/**/xcuserdata 55 | **/ios/.generated/ 56 | **/ios/Flutter/App.framework 57 | **/ios/Flutter/Flutter.framework 58 | **/ios/Flutter/Generated.xcconfig 59 | **/ios/Flutter/app.flx 60 | **/ios/Flutter/app.zip 61 | **/ios/Flutter/flutter_assets/ 62 | **/ios/ServiceDefinitions.json 63 | **/ios/Runner/GeneratedPluginRegistrant.* 64 | 65 | # Exceptions to above rules. 66 | !**/ios/**/default.mode1v3 67 | !**/ios/**/default.mode2v3 68 | !**/ios/**/default.pbxuser 69 | !**/ios/**/default.perspectivev3 70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 71 | -------------------------------------------------------------------------------- /lib/models/cards.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:card_app/data/api_service.dart'; 4 | import 'package:card_app/serializers/card.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:mobx/mobx.dart'; 7 | import 'package:provider/provider.dart'; 8 | 9 | part 'cards.g.dart'; 10 | 11 | class Cards = CardsBase with _$Cards; 12 | 13 | abstract class CardsBase with Store { 14 | CardsBase(); 15 | 16 | @observable 17 | List cardsList = List(); 18 | 19 | @observable 20 | int numOfCards = 6; 21 | 22 | @observable 23 | String filterUrl = ""; 24 | 25 | @action 26 | increaseNumOfCards(BuildContext context) { 27 | numOfCards = numOfCards + 6; 28 | getCardsList(context); 29 | } 30 | 31 | @action 32 | filterCardList(int filter) {} 33 | 34 | @action 35 | getCardsList(BuildContext context) { 36 | fetchCardsList(numOfCards, filterUrl, context).then((retrievedCards) { 37 | cardsList = retrievedCards; 38 | }); 39 | } 40 | } 41 | 42 | Future> fetchCardsList( 43 | int numOfCards, String url, BuildContext context) async { 44 | final res = await Provider.of(context).getAllCards(numOfCards); 45 | 46 | List cards = List(); 47 | 48 | if (res.isSuccessful) { 49 | Iterable cardList = json.decode(res.body); 50 | cards = cardList.map((card) => YgoCard.fromJson(card)).toList(); 51 | for (int i = 0; i < cards.length; i++) { 52 | print("KARTU ::::: ${cards[i].name}"); 53 | } 54 | return cards; 55 | } else { 56 | throw Exception("Failed to load cards"); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | card_app 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 | 45 | 46 | -------------------------------------------------------------------------------- /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/models/monsters.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:card_app/data/api_service.dart'; 4 | import 'package:card_app/serializers/card.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:mobx/mobx.dart'; 7 | import 'package:provider/provider.dart'; 8 | 9 | part 'monsters.g.dart'; 10 | 11 | class Monsters = MonstersBase with _$Monsters; 12 | 13 | abstract class MonstersBase with Store { 14 | MonstersBase(); 15 | 16 | @observable 17 | List cardsList = List(); 18 | 19 | @observable 20 | int numOfCards = 6; 21 | 22 | @observable 23 | String filterType = "normal monster"; 24 | 25 | @action 26 | increaseNumOfCards(BuildContext context) { 27 | numOfCards = numOfCards + 6; 28 | getCardsList(context); 29 | } 30 | 31 | @action 32 | filterCardList(String filterUrl, BuildContext context) { 33 | this.filterType = filterUrl; 34 | getCardsList(context); 35 | } 36 | 37 | @action 38 | getCardsList(BuildContext context) { 39 | fetchCardsList(numOfCards, filterType, context).then((retrievedCards) { 40 | cardsList = retrievedCards; 41 | }); 42 | } 43 | } 44 | 45 | Future> fetchCardsList( 46 | int numOfCards, String url, BuildContext context) async { 47 | final res = await Provider.of(context) 48 | .getMonsterCards(numOfCards, "normal monster"); 49 | 50 | List cards = List(); 51 | 52 | if (res.isSuccessful) { 53 | Iterable cardList = json.decode(res.body); 54 | cards = cardList.map((card) => YgoCard.fromJson(card)).toList(); 55 | for (int i = 0; i < cards.length; i++) { 56 | print("KARTU ::::: ${cards[i].name}"); 57 | } 58 | return cards; 59 | } else { 60 | throw Exception("Failed to load cards"); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/data/api_service.dart'; 2 | import 'package:card_app/models/cards.dart'; 3 | import 'package:card_app/models/monsters.dart'; 4 | import 'package:card_app/models/settings.dart'; 5 | import 'package:card_app/services/preferences_service.dart'; 6 | import 'package:card_app/widgets/themeable_app.dart'; 7 | import 'package:flutter/material.dart'; 8 | import 'package:shared_preferences/shared_preferences.dart'; 9 | import 'package:provider/provider.dart'; 10 | import 'package:logging/logging.dart'; 11 | 12 | Future main() async { 13 | _setupLogging(); 14 | var sharedPreferences = await SharedPreferences.getInstance(); 15 | runApp(MyApp(PreferencesService(sharedPreferences))); 16 | } 17 | 18 | void _setupLogging() { 19 | Logger.root.level = Level.ALL; 20 | Logger.root.onRecord.listen((rec) { 21 | print('${rec.level.name}: ${rec.time}: ${rec.message}'); 22 | }); 23 | } 24 | 25 | class MyApp extends StatelessWidget { 26 | final PreferencesService _preferencesService; 27 | 28 | const MyApp(this._preferencesService); 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return MultiProvider( 33 | providers: [ 34 | Provider( 35 | builder: (_) => ApiService.create(), 36 | dispose: (_, ApiService service) => service.client.dispose(), 37 | ), 38 | Provider( 39 | builder: (_) => _preferencesService, 40 | ), 41 | Provider( 42 | builder: (_) => Settings(_preferencesService), 43 | ), 44 | Provider( 45 | builder: (_) => Cards(), 46 | ), 47 | Provider( 48 | builder: (_) => Monsters(), 49 | ), 50 | ], 51 | child: Consumer( 52 | builder: (context, value, _) => ThemeableApp(value), 53 | ), 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 10 | 11 | 12 | 16 | 23 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.juvetic.card_app" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 66 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 67 | } 68 | -------------------------------------------------------------------------------- /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/serializers/card.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/serializers/card_image.dart'; 2 | import 'package:card_app/serializers/card_price.dart'; 3 | import 'package:card_app/serializers/card_set.dart'; 4 | 5 | class YgoCard { 6 | String id; 7 | String name; 8 | String type; 9 | String desc; 10 | String atk; 11 | String def; 12 | String level; 13 | String race; 14 | String attribute; 15 | String archetype; 16 | List cardSets; 17 | List cardImages; 18 | CardPrices cardPrices; 19 | 20 | YgoCard( 21 | {this.id, 22 | this.name, 23 | this.type, 24 | this.desc, 25 | this.atk, 26 | this.def, 27 | this.level, 28 | this.race, 29 | this.attribute, 30 | this.archetype, 31 | this.cardSets, 32 | this.cardImages, 33 | this.cardPrices}); 34 | 35 | YgoCard.fromJson(Map json) { 36 | id = json['id']; 37 | name = json['name']; 38 | type = json['type']; 39 | desc = json['desc']; 40 | atk = json['atk']; 41 | def = json['def']; 42 | level = json['level']; 43 | race = json['race']; 44 | attribute = json['attribute']; 45 | archetype = json['archetype']; 46 | if (json['card_sets'] != null) { 47 | cardSets = new List(); 48 | json['card_sets'].forEach((v) { 49 | cardSets.add(new CardSets.fromJson(v)); 50 | }); 51 | } 52 | if (json['card_images'] != null) { 53 | cardImages = new List(); 54 | json['card_images'].forEach((v) { 55 | cardImages.add(new CardImages.fromJson(v)); 56 | }); 57 | } 58 | cardPrices = json['card_prices'] != null 59 | ? new CardPrices.fromJson(json['card_prices']) 60 | : null; 61 | } 62 | 63 | Map toJson() { 64 | final Map data = new Map(); 65 | data['id'] = this.id; 66 | data['name'] = this.name; 67 | data['type'] = this.type; 68 | data['desc'] = this.desc; 69 | data['atk'] = this.atk; 70 | data['def'] = this.def; 71 | data['level'] = this.level; 72 | data['race'] = this.race; 73 | data['attribute'] = this.attribute; 74 | data['archetype'] = this.archetype; 75 | if (this.cardSets != null) { 76 | data['card_sets'] = this.cardSets.map((v) => v.toJson()).toList(); 77 | } 78 | if (this.cardImages != null) { 79 | data['card_images'] = this.cardImages.map((v) => v.toJson()).toList(); 80 | } 81 | if (this.cardPrices != null) { 82 | data['card_prices'] = this.cardPrices.toJson(); 83 | } 84 | return data; 85 | } 86 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yugioh Cards Sample App 2 | 3 | All data are collected from https://db.ygoprodeck.com/api-guide/. 4 | 5 | I apply MobX as state management for this app. At this time, I only implement the list of cards with pagination and detail page. But, I will add some features like sorting, searching, and filter the cards based on availability of multiple parameters in the ygoprodeck.com api. In addition, I use [git-karma] for the commit messages conventions. 6 | There are still room for improvements, so I'm open for any feedback. Sharing with one another helps us all grow and learn. ✌️ 7 | 8 | ### Screenshots 9 | 10 | 11 | 12 | 13 | 14 | ### Api Service 15 | ``` 16 | GET 17 | https://db.ygoprodeck.com/api/v5/cardinfo.php 18 | ``` 19 | 20 | ## Build App 21 | This app required generated code. Here is the command: 22 | ``` 23 | flutter packages get 24 | flutter packages run build_runner build 25 | flutter run 26 | ``` 27 | 28 | ## Libs Dependencies 29 | * [mobx] 30 | * [flutter_mobx] 31 | * [provider] 32 | * [chopper] 33 | * [cached_network_image] 34 | * [fluttertoast] 35 | * [mobx_codegen] 36 | * [build_runner] 37 | 38 | ## TO DO 39 | - [x] Chopper for Network calls 40 | - [x] Using Provider 41 | - [ ] Favorite Cards using Moor 42 | - [ ] ... 43 | 44 | ## Repository Created & Maintained By 45 | 46 | ### Fikri Razzaq 47 | 48 | #Flutter Enthusiast, #Android Developer. 49 | 50 | 51 | 52 | 53 | 54 | [mobx]: 55 | [flutter_mobx]: 56 | [provider]: 57 | [chopper]: 58 | [cached_network_image]: 59 | [fluttertoast]: 60 | [mobx_codegen]: 61 | [build_runner]: 62 | [git-karma]: 63 | -------------------------------------------------------------------------------- /lib/models/cards.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'cards.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars 10 | 11 | mixin _$Cards on CardsBase, Store { 12 | final _$cardsListAtom = Atom(name: 'CardsBase.cardsList'); 13 | 14 | @override 15 | List get cardsList { 16 | _$cardsListAtom.context.enforceReadPolicy(_$cardsListAtom); 17 | _$cardsListAtom.reportObserved(); 18 | return super.cardsList; 19 | } 20 | 21 | @override 22 | set cardsList(List value) { 23 | _$cardsListAtom.context.conditionallyRunInAction(() { 24 | super.cardsList = value; 25 | _$cardsListAtom.reportChanged(); 26 | }, _$cardsListAtom, name: '${_$cardsListAtom.name}_set'); 27 | } 28 | 29 | final _$numOfCardsAtom = Atom(name: 'CardsBase.numOfCards'); 30 | 31 | @override 32 | int get numOfCards { 33 | _$numOfCardsAtom.context.enforceReadPolicy(_$numOfCardsAtom); 34 | _$numOfCardsAtom.reportObserved(); 35 | return super.numOfCards; 36 | } 37 | 38 | @override 39 | set numOfCards(int value) { 40 | _$numOfCardsAtom.context.conditionallyRunInAction(() { 41 | super.numOfCards = value; 42 | _$numOfCardsAtom.reportChanged(); 43 | }, _$numOfCardsAtom, name: '${_$numOfCardsAtom.name}_set'); 44 | } 45 | 46 | final _$filterUrlAtom = Atom(name: 'CardsBase.filterUrl'); 47 | 48 | @override 49 | String get filterUrl { 50 | _$filterUrlAtom.context.enforceReadPolicy(_$filterUrlAtom); 51 | _$filterUrlAtom.reportObserved(); 52 | return super.filterUrl; 53 | } 54 | 55 | @override 56 | set filterUrl(String value) { 57 | _$filterUrlAtom.context.conditionallyRunInAction(() { 58 | super.filterUrl = value; 59 | _$filterUrlAtom.reportChanged(); 60 | }, _$filterUrlAtom, name: '${_$filterUrlAtom.name}_set'); 61 | } 62 | 63 | final _$CardsBaseActionController = ActionController(name: 'CardsBase'); 64 | 65 | @override 66 | dynamic increaseNumOfCards(BuildContext context) { 67 | final _$actionInfo = _$CardsBaseActionController.startAction(); 68 | try { 69 | return super.increaseNumOfCards(context); 70 | } finally { 71 | _$CardsBaseActionController.endAction(_$actionInfo); 72 | } 73 | } 74 | 75 | @override 76 | dynamic filterCardList(int filter) { 77 | final _$actionInfo = _$CardsBaseActionController.startAction(); 78 | try { 79 | return super.filterCardList(filter); 80 | } finally { 81 | _$CardsBaseActionController.endAction(_$actionInfo); 82 | } 83 | } 84 | 85 | @override 86 | dynamic getCardsList(BuildContext context) { 87 | final _$actionInfo = _$CardsBaseActionController.startAction(); 88 | try { 89 | return super.getCardsList(context); 90 | } finally { 91 | _$CardsBaseActionController.endAction(_$actionInfo); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /lib/models/monsters.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'monsters.dart'; 4 | 5 | // ************************************************************************** 6 | // StoreGenerator 7 | // ************************************************************************** 8 | 9 | // ignore_for_file: non_constant_identifier_names, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars 10 | 11 | mixin _$Monsters on MonstersBase, Store { 12 | final _$cardsListAtom = Atom(name: 'MonstersBase.cardsList'); 13 | 14 | @override 15 | List get cardsList { 16 | _$cardsListAtom.context.enforceReadPolicy(_$cardsListAtom); 17 | _$cardsListAtom.reportObserved(); 18 | return super.cardsList; 19 | } 20 | 21 | @override 22 | set cardsList(List value) { 23 | _$cardsListAtom.context.conditionallyRunInAction(() { 24 | super.cardsList = value; 25 | _$cardsListAtom.reportChanged(); 26 | }, _$cardsListAtom, name: '${_$cardsListAtom.name}_set'); 27 | } 28 | 29 | final _$numOfCardsAtom = Atom(name: 'MonstersBase.numOfCards'); 30 | 31 | @override 32 | int get numOfCards { 33 | _$numOfCardsAtom.context.enforceReadPolicy(_$numOfCardsAtom); 34 | _$numOfCardsAtom.reportObserved(); 35 | return super.numOfCards; 36 | } 37 | 38 | @override 39 | set numOfCards(int value) { 40 | _$numOfCardsAtom.context.conditionallyRunInAction(() { 41 | super.numOfCards = value; 42 | _$numOfCardsAtom.reportChanged(); 43 | }, _$numOfCardsAtom, name: '${_$numOfCardsAtom.name}_set'); 44 | } 45 | 46 | final _$filterTypeAtom = Atom(name: 'MonstersBase.filterType'); 47 | 48 | @override 49 | String get filterType { 50 | _$filterTypeAtom.context.enforceReadPolicy(_$filterTypeAtom); 51 | _$filterTypeAtom.reportObserved(); 52 | return super.filterType; 53 | } 54 | 55 | @override 56 | set filterType(String value) { 57 | _$filterTypeAtom.context.conditionallyRunInAction(() { 58 | super.filterType = value; 59 | _$filterTypeAtom.reportChanged(); 60 | }, _$filterTypeAtom, name: '${_$filterTypeAtom.name}_set'); 61 | } 62 | 63 | final _$MonstersBaseActionController = ActionController(name: 'MonstersBase'); 64 | 65 | @override 66 | dynamic increaseNumOfCards(BuildContext context) { 67 | final _$actionInfo = _$MonstersBaseActionController.startAction(); 68 | try { 69 | return super.increaseNumOfCards(context); 70 | } finally { 71 | _$MonstersBaseActionController.endAction(_$actionInfo); 72 | } 73 | } 74 | 75 | @override 76 | dynamic filterCardList(String filterUrl, BuildContext context) { 77 | final _$actionInfo = _$MonstersBaseActionController.startAction(); 78 | try { 79 | return super.filterCardList(filterUrl, context); 80 | } finally { 81 | _$MonstersBaseActionController.endAction(_$actionInfo); 82 | } 83 | } 84 | 85 | @override 86 | dynamic getCardsList(BuildContext context) { 87 | final _$actionInfo = _$MonstersBaseActionController.startAction(); 88 | try { 89 | return super.getCardsList(context); 90 | } finally { 91 | _$MonstersBaseActionController.endAction(_$actionInfo); 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: card_app 2 | description: A new Flutter application. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # In Android, build-name is used as versionName while build-number used as versionCode. 10 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 11 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 12 | # Read more about iOS versioning at 13 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 14 | version: 1.0.0+1 15 | 16 | environment: 17 | sdk: ">=2.1.0-dev <3.0.0" 18 | 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.2 26 | 27 | # MobX 28 | mobx: 29 | flutter_mobx: 30 | 31 | # Networking 32 | http: 33 | 34 | # Image Loader 35 | cached_network_image: 36 | 37 | # Toast 38 | fluttertoast: 39 | 40 | # Shared Preference 41 | shared_preferences: 42 | 43 | # Provider 44 | provider: 45 | 46 | # Chopper 47 | chopper: 48 | 49 | dev_dependencies: 50 | flutter_test: 51 | sdk: flutter 52 | 53 | chopper_generator: 54 | mobx_codegen: 55 | build_runner: 56 | 57 | # For information on the generic Dart part of this file, see the 58 | # following page: https://www.dartlang.org/tools/pub/pubspec 59 | 60 | # The following section is specific to Flutter. 61 | flutter: 62 | 63 | # The following line ensures that the Material Icons font is 64 | # included with your application, so that you can use the icons in 65 | # the material Icons class. 66 | uses-material-design: true 67 | 68 | # To add assets to your application, add an assets section, like this: 69 | # assets: 70 | # - images/a_dot_burr.jpeg 71 | # - images/a_dot_ham.jpeg 72 | 73 | # An image asset can refer to one or more resolution-specific "variants", see 74 | # https://flutter.dev/assets-and-images/#resolution-aware. 75 | 76 | # For details regarding adding assets from package dependencies, see 77 | # https://flutter.dev/assets-and-images/#from-packages 78 | 79 | # To add custom fonts to your application, add a fonts section here, 80 | # in this "flutter" section. Each entry in this list should have a 81 | # "family" key with the font family name, and a "fonts" key with a 82 | # list giving the asset and other descriptors for the font. For 83 | # example: 84 | # fonts: 85 | # - family: Schyler 86 | # fonts: 87 | # - asset: fonts/Schyler-Regular.ttf 88 | # - asset: fonts/Schyler-Italic.ttf 89 | # style: italic 90 | # - family: Trajan Pro 91 | # fonts: 92 | # - asset: fonts/TrajanPro.ttf 93 | # - asset: fonts/TrajanPro_Bold.ttf 94 | # weight: 700 95 | # 96 | # For details regarding fonts from package dependencies, 97 | # see https://flutter.dev/custom-fonts/#from-packages -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/screens/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:card_app/models/cards.dart'; 2 | import 'package:card_app/screens/all_cards_page.dart'; 3 | import 'package:card_app/screens/monster_cards_page.dart'; 4 | import 'package:card_app/screens/settings_page.dart'; 5 | import 'package:card_app/utils/size_config.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter/services.dart'; 8 | import 'package:provider/provider.dart'; 9 | 10 | class Home extends StatefulWidget { 11 | @override 12 | _HomeState createState() => _HomeState(); 13 | } 14 | 15 | class _HomeState extends State { 16 | int selectedIndex = 0; 17 | 18 | final widgetPager = [ 19 | Consumer( 20 | builder: (context, value, _) => AllCardsPage(), 21 | ), 22 | Consumer( 23 | builder: (context, value, _) => MonsterCardsPage(), 24 | ), 25 | ]; 26 | 27 | @override 28 | Widget build(BuildContext context) { 29 | SizeConfig().init(context); 30 | 31 | return WillPopScope( 32 | onWillPop: _willPopCallback, 33 | child: Scaffold( 34 | appBar: AppBar( 35 | title: Text(getTitle(selectedIndex)), 36 | actions: [ 37 | IconButton( 38 | onPressed: () { 39 | Navigator.of(context).push( 40 | MaterialPageRoute( 41 | builder: (context) => SettingsPage(), 42 | ), 43 | ); 44 | }, 45 | icon: Icon( 46 | Icons.settings, 47 | ), 48 | ) 49 | ], 50 | ), 51 | bottomNavigationBar: BottomNavigationBar( 52 | items: [ 53 | BottomNavigationBarItem( 54 | icon: Icon(Icons.all_inclusive), 55 | title: Text('All Cards'), 56 | ), 57 | BottomNavigationBarItem( 58 | icon: Icon(Icons.child_care), 59 | title: Text('Monster Cards'), 60 | ), 61 | ], 62 | currentIndex: selectedIndex, 63 | onTap: onItemTapped, 64 | ), 65 | body: widgetPager.elementAt(selectedIndex), 66 | ), 67 | ); 68 | } 69 | 70 | void onItemTapped(int index) { 71 | setState(() { 72 | selectedIndex = index; 73 | }); 74 | } 75 | 76 | String getTitle(int index) { 77 | switch (index) { 78 | case 0: 79 | return "All Cards"; 80 | break; 81 | case 1: 82 | return "Monster Cards"; 83 | break; 84 | default: 85 | return "All Cards"; 86 | break; 87 | } 88 | } 89 | 90 | Future _willPopCallback() async { 91 | showDialog( 92 | context: context, 93 | builder: (_) { 94 | return AlertDialog( 95 | title: Text("Quit App?"), 96 | actions: [ 97 | FlatButton( 98 | child: Text("CANCEL"), 99 | onPressed: () { 100 | Navigator.of(context).pop(); 101 | }, 102 | ), 103 | RaisedButton( 104 | shape: RoundedRectangleBorder( 105 | borderRadius: BorderRadius.circular(24)), 106 | color: Colors.orange, 107 | child: Text( 108 | "YA", 109 | style: TextStyle( 110 | fontWeight: FontWeight.bold, 111 | color: Colors.white, 112 | ), 113 | ), 114 | onPressed: () { 115 | SystemChannels.platform.invokeMethod('SystemNavigator.pop'); 116 | }, 117 | ), 118 | ], 119 | ); 120 | }, 121 | ); 122 | return Future.value(false); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /lib/screens/all_cards_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:card_app/models/cards.dart'; 3 | import 'package:card_app/screens/card_detail_page.dart'; 4 | import 'package:card_app/serializers/card.dart'; 5 | import 'package:card_app/utils/size_config.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_mobx/flutter_mobx.dart'; 8 | 9 | class AllCardsPage extends StatefulWidget { 10 | @override 11 | _AllCardsPageState createState() => _AllCardsPageState(); 12 | } 13 | 14 | class _AllCardsPageState extends State { 15 | ScrollController _scrollController = ScrollController(); 16 | 17 | final _cards = Cards(); 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | } 23 | 24 | @override 25 | void dispose() { 26 | _scrollController.dispose(); 27 | super.dispose(); 28 | } 29 | 30 | @override 31 | void didChangeDependencies() { 32 | super.didChangeDependencies(); 33 | _cards.getCardsList(context); 34 | 35 | _scrollController.addListener(() async { 36 | if (_scrollController.position.pixels == 37 | _scrollController.position.maxScrollExtent) { 38 | await _cards.increaseNumOfCards(context); 39 | } 40 | }); 41 | } 42 | 43 | @override 44 | Widget build(BuildContext context) { 45 | SizeConfig().init(context); 46 | 47 | return Scaffold( 48 | body: Observer( 49 | builder: (context) => RefreshIndicator( 50 | onRefresh: () async { 51 | await Future.delayed(Duration(seconds: 1)); 52 | await _cards.increaseNumOfCards(context); 53 | }, 54 | child: Container( 55 | child: Observer( 56 | builder: (_) => 57 | ((_cards.cardsList != null) && (_cards.cardsList.isNotEmpty)) 58 | ? ListView.builder( 59 | controller: _scrollController, 60 | itemCount: _cards.cardsList.length, 61 | itemBuilder: (_, index) { 62 | final card = _cards.cardsList[index]; 63 | return _cardContainer( 64 | card, index, _cards.cardsList.length); 65 | }, 66 | ) 67 | : Center( 68 | child: CircularProgressIndicator(), 69 | ), 70 | ), 71 | ), 72 | ), 73 | ), 74 | ); 75 | } 76 | 77 | Widget _cardContainer(YgoCard card, int index, int length) { 78 | return Container( 79 | padding: EdgeInsets.only( 80 | left: 8, 81 | right: 8, 82 | top: index == 0 ? 10 : 2, 83 | bottom: index == length - 1 ? 10 : 2), 84 | child: Card( 85 | shape: RoundedRectangleBorder( 86 | borderRadius: BorderRadius.all(Radius.zero), 87 | ), 88 | child: InkWell( 89 | borderRadius: BorderRadius.all(Radius.zero), 90 | onTap: () { 91 | Navigator.push( 92 | context, 93 | MaterialPageRoute( 94 | builder: (context) => CardDetailPage( 95 | card: card, 96 | ), 97 | ), 98 | ); 99 | }, 100 | child: Row( 101 | children: [ 102 | CachedNetworkImage( 103 | width: SizeConfig.blockSizeHorizontal * 30, 104 | imageUrl: "https://ygoprodeck.com/pics/${card.id}.jpg", 105 | placeholder: (context, url) => Container( 106 | width: SizeConfig.blockSizeHorizontal * 30, 107 | child: Center(child: CircularProgressIndicator()), 108 | ), 109 | errorWidget: (context, url, error) => Icon(Icons.error), 110 | ), 111 | Container( 112 | height: SizeConfig.blockSizeVertical * 20, 113 | width: SizeConfig.blockSizeHorizontal * 60, 114 | padding: EdgeInsets.only(left: 8, right: 8, top: 8, bottom: 8), 115 | child: Column( 116 | crossAxisAlignment: CrossAxisAlignment.start, 117 | mainAxisSize: MainAxisSize.max, 118 | children: [ 119 | Container( 120 | child: Text( 121 | card.name, 122 | style: TextStyle( 123 | fontSize: 16, 124 | fontWeight: FontWeight.w600, 125 | ), 126 | ), 127 | ), 128 | Container( 129 | margin: EdgeInsets.only(top: 2, bottom: 4), 130 | child: Text( 131 | card.type, 132 | style: TextStyle( 133 | fontSize: 12, 134 | color: cardTypeColor(card.type), 135 | ), 136 | ), 137 | ), 138 | Expanded( 139 | child: Text( 140 | card.desc, 141 | maxLines: 4, 142 | overflow: TextOverflow.ellipsis, 143 | style: TextStyle(fontSize: 12, color: Colors.grey), 144 | ), 145 | ), 146 | ], 147 | ), 148 | ) 149 | ], 150 | ), 151 | ), 152 | ), 153 | ); 154 | } 155 | 156 | Color cardTypeColor(String type) { 157 | if (type.toLowerCase().contains('spell')) { 158 | return Colors.teal; 159 | } else if (type.toLowerCase().contains('skill')) { 160 | return Colors.teal; 161 | } else if (type.toLowerCase().contains('monster')) { 162 | return Colors.brown; 163 | } else if (type.toLowerCase().contains('trap')) { 164 | return Colors.pink[800]; 165 | } else { 166 | return Colors.blueAccent; 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /lib/screens/monster_cards_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:card_app/models/monsters.dart'; 3 | import 'package:card_app/screens/card_detail_page.dart'; 4 | import 'package:card_app/serializers/card.dart'; 5 | import 'package:card_app/utils/size_config.dart'; 6 | import 'package:flutter/material.dart'; 7 | import 'package:flutter_mobx/flutter_mobx.dart'; 8 | 9 | class MonsterCardsPage extends StatefulWidget { 10 | @override 11 | _MonsterCardsPageState createState() => _MonsterCardsPageState(); 12 | } 13 | 14 | class _MonsterCardsPageState extends State { 15 | ScrollController _scrollController = ScrollController(); 16 | 17 | final _cards = Monsters(); 18 | 19 | @override 20 | void initState() { 21 | super.initState(); 22 | } 23 | 24 | @override 25 | void dispose() { 26 | _scrollController.dispose(); 27 | super.dispose(); 28 | } 29 | 30 | @override 31 | void didChangeDependencies() { 32 | super.didChangeDependencies(); 33 | _cards.getCardsList(context); 34 | _scrollController.addListener(() async { 35 | if (_scrollController.position.pixels == 36 | _scrollController.position.maxScrollExtent) { 37 | await _cards.increaseNumOfCards(context); 38 | } 39 | }); 40 | } 41 | 42 | @override 43 | Widget build(BuildContext context) { 44 | SizeConfig().init(context); 45 | 46 | return Scaffold( 47 | body: Observer( 48 | builder: (context) => RefreshIndicator( 49 | onRefresh: () async { 50 | await Future.delayed(Duration(seconds: 1)); 51 | await _cards.increaseNumOfCards(context); 52 | }, 53 | child: Container( 54 | child: Observer( 55 | builder: (_) => 56 | ((_cards.cardsList != null) && (_cards.cardsList.isNotEmpty)) 57 | ? ListView.builder( 58 | controller: _scrollController, 59 | itemCount: _cards.cardsList.length, 60 | itemBuilder: (_, index) { 61 | final card = _cards.cardsList[index]; 62 | return _cardContainer( 63 | card, index, _cards.cardsList.length); 64 | }, 65 | ) 66 | : Center( 67 | child: CircularProgressIndicator(), 68 | ), 69 | ), 70 | ), 71 | ), 72 | ), 73 | ); 74 | } 75 | 76 | Widget _cardContainer(YgoCard card, int index, int length) { 77 | return Container( 78 | padding: EdgeInsets.only( 79 | left: 8, 80 | right: 8, 81 | top: index == 0 ? 10 : 2, 82 | bottom: index == length - 1 ? 10 : 2), 83 | child: Card( 84 | shape: RoundedRectangleBorder( 85 | borderRadius: BorderRadius.all(Radius.zero), 86 | ), 87 | child: InkWell( 88 | borderRadius: BorderRadius.all(Radius.zero), 89 | onTap: () { 90 | Navigator.push( 91 | context, 92 | MaterialPageRoute( 93 | builder: (context) => CardDetailPage( 94 | card: card, 95 | ), 96 | ), 97 | ); 98 | }, 99 | child: Row( 100 | children: [ 101 | CachedNetworkImage( 102 | width: SizeConfig.blockSizeHorizontal * 30, 103 | imageUrl: "https://ygoprodeck.com/pics/${card.id}.jpg", 104 | placeholder: (context, url) => Container( 105 | width: SizeConfig.blockSizeHorizontal * 30, 106 | child: Center(child: CircularProgressIndicator()), 107 | ), 108 | errorWidget: (context, url, error) => Icon(Icons.error), 109 | ), 110 | Container( 111 | height: SizeConfig.blockSizeVertical * 20, 112 | width: SizeConfig.blockSizeHorizontal * 60, 113 | padding: EdgeInsets.only(left: 8, right: 8, top: 8, bottom: 8), 114 | child: Column( 115 | crossAxisAlignment: CrossAxisAlignment.start, 116 | mainAxisSize: MainAxisSize.max, 117 | children: [ 118 | Container( 119 | child: Text( 120 | card.name, 121 | style: TextStyle( 122 | fontSize: 16, 123 | fontWeight: FontWeight.w600, 124 | ), 125 | ), 126 | ), 127 | Container( 128 | margin: EdgeInsets.only(top: 2, bottom: 4), 129 | child: Text( 130 | card.type, 131 | style: TextStyle( 132 | fontSize: 12, 133 | color: cardTypeColor(card.type), 134 | ), 135 | ), 136 | ), 137 | Expanded( 138 | child: Text( 139 | card.desc, 140 | maxLines: 4, 141 | overflow: TextOverflow.ellipsis, 142 | style: TextStyle(fontSize: 12, color: Colors.grey), 143 | ), 144 | ), 145 | ], 146 | ), 147 | ) 148 | ], 149 | ), 150 | ), 151 | ), 152 | ); 153 | } 154 | 155 | Color cardTypeColor(String type) { 156 | if (type.toLowerCase().contains('spell')) { 157 | return Colors.teal; 158 | } else if (type.toLowerCase().contains('skill')) { 159 | return Colors.teal; 160 | } else if (type.toLowerCase().contains('monster')) { 161 | return Colors.brown; 162 | } else if (type.toLowerCase().contains('trap')) { 163 | return Colors.pink[800]; 164 | } else { 165 | return Colors.blueAccent; 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | analyzer: 5 | dependency: transitive 6 | description: 7 | name: analyzer 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "0.36.4" 11 | args: 12 | dependency: transitive 13 | description: 14 | name: args 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "1.5.2" 18 | async: 19 | dependency: transitive 20 | description: 21 | name: async 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.2.0" 25 | boolean_selector: 26 | dependency: transitive 27 | description: 28 | name: boolean_selector 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.0.4" 32 | build: 33 | dependency: transitive 34 | description: 35 | name: build 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.1.4" 39 | build_config: 40 | dependency: transitive 41 | description: 42 | name: build_config 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "0.4.0" 46 | build_daemon: 47 | dependency: transitive 48 | description: 49 | name: build_daemon 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.1.0" 53 | build_resolvers: 54 | dependency: transitive 55 | description: 56 | name: build_resolvers 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.0.5" 60 | build_runner: 61 | dependency: "direct dev" 62 | description: 63 | name: build_runner 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.6.1" 67 | build_runner_core: 68 | dependency: transitive 69 | description: 70 | name: build_runner_core 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "3.0.6" 74 | built_collection: 75 | dependency: transitive 76 | description: 77 | name: built_collection 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "4.2.2" 81 | built_value: 82 | dependency: transitive 83 | description: 84 | name: built_value 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "6.6.0" 88 | cached_network_image: 89 | dependency: "direct main" 90 | description: 91 | name: cached_network_image 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "1.0.0" 95 | charcode: 96 | dependency: transitive 97 | description: 98 | name: charcode 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "1.1.2" 102 | chopper: 103 | dependency: "direct main" 104 | description: 105 | name: chopper 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "2.4.2" 109 | chopper_generator: 110 | dependency: "direct dev" 111 | description: 112 | name: chopper_generator 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "2.4.2" 116 | code_builder: 117 | dependency: transitive 118 | description: 119 | name: code_builder 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "3.2.0" 123 | collection: 124 | dependency: transitive 125 | description: 126 | name: collection 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "1.14.11" 130 | convert: 131 | dependency: transitive 132 | description: 133 | name: convert 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "2.1.1" 137 | crypto: 138 | dependency: transitive 139 | description: 140 | name: crypto 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "2.0.6" 144 | csslib: 145 | dependency: transitive 146 | description: 147 | name: csslib 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "0.16.0" 151 | cupertino_icons: 152 | dependency: "direct main" 153 | description: 154 | name: cupertino_icons 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "0.1.2" 158 | dart_style: 159 | dependency: transitive 160 | description: 161 | name: dart_style 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "1.2.7" 165 | fixnum: 166 | dependency: transitive 167 | description: 168 | name: fixnum 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "0.10.9" 172 | flutter: 173 | dependency: "direct main" 174 | description: flutter 175 | source: sdk 176 | version: "0.0.0" 177 | flutter_cache_manager: 178 | dependency: transitive 179 | description: 180 | name: flutter_cache_manager 181 | url: "https://pub.dartlang.org" 182 | source: hosted 183 | version: "1.0.0" 184 | flutter_mobx: 185 | dependency: "direct main" 186 | description: 187 | name: flutter_mobx 188 | url: "https://pub.dartlang.org" 189 | source: hosted 190 | version: "0.3.0+1" 191 | flutter_test: 192 | dependency: "direct dev" 193 | description: flutter 194 | source: sdk 195 | version: "0.0.0" 196 | fluttertoast: 197 | dependency: "direct main" 198 | description: 199 | name: fluttertoast 200 | url: "https://pub.dartlang.org" 201 | source: hosted 202 | version: "3.1.0" 203 | front_end: 204 | dependency: transitive 205 | description: 206 | name: front_end 207 | url: "https://pub.dartlang.org" 208 | source: hosted 209 | version: "0.1.19" 210 | glob: 211 | dependency: transitive 212 | description: 213 | name: glob 214 | url: "https://pub.dartlang.org" 215 | source: hosted 216 | version: "1.1.7" 217 | graphs: 218 | dependency: transitive 219 | description: 220 | name: graphs 221 | url: "https://pub.dartlang.org" 222 | source: hosted 223 | version: "0.2.0" 224 | html: 225 | dependency: transitive 226 | description: 227 | name: html 228 | url: "https://pub.dartlang.org" 229 | source: hosted 230 | version: "0.14.0+2" 231 | http: 232 | dependency: "direct main" 233 | description: 234 | name: http 235 | url: "https://pub.dartlang.org" 236 | source: hosted 237 | version: "0.12.0+2" 238 | http_multi_server: 239 | dependency: transitive 240 | description: 241 | name: http_multi_server 242 | url: "https://pub.dartlang.org" 243 | source: hosted 244 | version: "2.1.0" 245 | http_parser: 246 | dependency: transitive 247 | description: 248 | name: http_parser 249 | url: "https://pub.dartlang.org" 250 | source: hosted 251 | version: "3.1.3" 252 | io: 253 | dependency: transitive 254 | description: 255 | name: io 256 | url: "https://pub.dartlang.org" 257 | source: hosted 258 | version: "0.3.3" 259 | js: 260 | dependency: transitive 261 | description: 262 | name: js 263 | url: "https://pub.dartlang.org" 264 | source: hosted 265 | version: "0.6.1+1" 266 | json_annotation: 267 | dependency: transitive 268 | description: 269 | name: json_annotation 270 | url: "https://pub.dartlang.org" 271 | source: hosted 272 | version: "2.4.0" 273 | kernel: 274 | dependency: transitive 275 | description: 276 | name: kernel 277 | url: "https://pub.dartlang.org" 278 | source: hosted 279 | version: "0.3.19" 280 | logging: 281 | dependency: transitive 282 | description: 283 | name: logging 284 | url: "https://pub.dartlang.org" 285 | source: hosted 286 | version: "0.11.3+2" 287 | matcher: 288 | dependency: transitive 289 | description: 290 | name: matcher 291 | url: "https://pub.dartlang.org" 292 | source: hosted 293 | version: "0.12.5" 294 | meta: 295 | dependency: transitive 296 | description: 297 | name: meta 298 | url: "https://pub.dartlang.org" 299 | source: hosted 300 | version: "1.1.6" 301 | mime: 302 | dependency: transitive 303 | description: 304 | name: mime 305 | url: "https://pub.dartlang.org" 306 | source: hosted 307 | version: "0.9.6+3" 308 | mobx: 309 | dependency: "direct main" 310 | description: 311 | name: mobx 312 | url: "https://pub.dartlang.org" 313 | source: hosted 314 | version: "0.3.3+2" 315 | mobx_codegen: 316 | dependency: "direct dev" 317 | description: 318 | name: mobx_codegen 319 | url: "https://pub.dartlang.org" 320 | source: hosted 321 | version: "0.3.3+1" 322 | package_config: 323 | dependency: transitive 324 | description: 325 | name: package_config 326 | url: "https://pub.dartlang.org" 327 | source: hosted 328 | version: "1.0.5" 329 | package_resolver: 330 | dependency: transitive 331 | description: 332 | name: package_resolver 333 | url: "https://pub.dartlang.org" 334 | source: hosted 335 | version: "1.0.10" 336 | path: 337 | dependency: transitive 338 | description: 339 | name: path 340 | url: "https://pub.dartlang.org" 341 | source: hosted 342 | version: "1.6.2" 343 | path_provider: 344 | dependency: transitive 345 | description: 346 | name: path_provider 347 | url: "https://pub.dartlang.org" 348 | source: hosted 349 | version: "1.1.0" 350 | pedantic: 351 | dependency: transitive 352 | description: 353 | name: pedantic 354 | url: "https://pub.dartlang.org" 355 | source: hosted 356 | version: "1.7.0" 357 | pool: 358 | dependency: transitive 359 | description: 360 | name: pool 361 | url: "https://pub.dartlang.org" 362 | source: hosted 363 | version: "1.4.0" 364 | provider: 365 | dependency: "direct main" 366 | description: 367 | name: provider 368 | url: "https://pub.dartlang.org" 369 | source: hosted 370 | version: "3.0.0+1" 371 | pub_semver: 372 | dependency: transitive 373 | description: 374 | name: pub_semver 375 | url: "https://pub.dartlang.org" 376 | source: hosted 377 | version: "1.4.2" 378 | pubspec_parse: 379 | dependency: transitive 380 | description: 381 | name: pubspec_parse 382 | url: "https://pub.dartlang.org" 383 | source: hosted 384 | version: "0.1.4" 385 | quiver: 386 | dependency: transitive 387 | description: 388 | name: quiver 389 | url: "https://pub.dartlang.org" 390 | source: hosted 391 | version: "2.0.3" 392 | shared_preferences: 393 | dependency: "direct main" 394 | description: 395 | name: shared_preferences 396 | url: "https://pub.dartlang.org" 397 | source: hosted 398 | version: "0.5.3+2" 399 | shelf: 400 | dependency: transitive 401 | description: 402 | name: shelf 403 | url: "https://pub.dartlang.org" 404 | source: hosted 405 | version: "0.7.5" 406 | shelf_web_socket: 407 | dependency: transitive 408 | description: 409 | name: shelf_web_socket 410 | url: "https://pub.dartlang.org" 411 | source: hosted 412 | version: "0.2.3" 413 | sky_engine: 414 | dependency: transitive 415 | description: flutter 416 | source: sdk 417 | version: "0.0.99" 418 | source_gen: 419 | dependency: transitive 420 | description: 421 | name: source_gen 422 | url: "https://pub.dartlang.org" 423 | source: hosted 424 | version: "0.9.4+2" 425 | source_span: 426 | dependency: transitive 427 | description: 428 | name: source_span 429 | url: "https://pub.dartlang.org" 430 | source: hosted 431 | version: "1.5.5" 432 | sqflite: 433 | dependency: transitive 434 | description: 435 | name: sqflite 436 | url: "https://pub.dartlang.org" 437 | source: hosted 438 | version: "1.1.6+1" 439 | stack_trace: 440 | dependency: transitive 441 | description: 442 | name: stack_trace 443 | url: "https://pub.dartlang.org" 444 | source: hosted 445 | version: "1.9.3" 446 | stream_channel: 447 | dependency: transitive 448 | description: 449 | name: stream_channel 450 | url: "https://pub.dartlang.org" 451 | source: hosted 452 | version: "2.0.0" 453 | stream_transform: 454 | dependency: transitive 455 | description: 456 | name: stream_transform 457 | url: "https://pub.dartlang.org" 458 | source: hosted 459 | version: "0.0.19" 460 | string_scanner: 461 | dependency: transitive 462 | description: 463 | name: string_scanner 464 | url: "https://pub.dartlang.org" 465 | source: hosted 466 | version: "1.0.4" 467 | synchronized: 468 | dependency: transitive 469 | description: 470 | name: synchronized 471 | url: "https://pub.dartlang.org" 472 | source: hosted 473 | version: "2.1.0+1" 474 | term_glyph: 475 | dependency: transitive 476 | description: 477 | name: term_glyph 478 | url: "https://pub.dartlang.org" 479 | source: hosted 480 | version: "1.1.0" 481 | test_api: 482 | dependency: transitive 483 | description: 484 | name: test_api 485 | url: "https://pub.dartlang.org" 486 | source: hosted 487 | version: "0.2.5" 488 | timing: 489 | dependency: transitive 490 | description: 491 | name: timing 492 | url: "https://pub.dartlang.org" 493 | source: hosted 494 | version: "0.1.1+1" 495 | typed_data: 496 | dependency: transitive 497 | description: 498 | name: typed_data 499 | url: "https://pub.dartlang.org" 500 | source: hosted 501 | version: "1.1.6" 502 | uuid: 503 | dependency: transitive 504 | description: 505 | name: uuid 506 | url: "https://pub.dartlang.org" 507 | source: hosted 508 | version: "2.0.2" 509 | vector_math: 510 | dependency: transitive 511 | description: 512 | name: vector_math 513 | url: "https://pub.dartlang.org" 514 | source: hosted 515 | version: "2.0.8" 516 | watcher: 517 | dependency: transitive 518 | description: 519 | name: watcher 520 | url: "https://pub.dartlang.org" 521 | source: hosted 522 | version: "0.9.7+10" 523 | web_socket_channel: 524 | dependency: transitive 525 | description: 526 | name: web_socket_channel 527 | url: "https://pub.dartlang.org" 528 | source: hosted 529 | version: "1.0.13" 530 | yaml: 531 | dependency: transitive 532 | description: 533 | name: yaml 534 | url: "https://pub.dartlang.org" 535 | source: hosted 536 | version: "2.1.16" 537 | sdks: 538 | dart: ">=2.3.0-dev.0.1 <3.0.0" 539 | flutter: ">=1.5.0 <2.0.0" 540 | -------------------------------------------------------------------------------- /lib/screens/card_detail_page.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:card_app/serializers/card.dart'; 3 | import 'package:card_app/utils/constants.dart'; 4 | import 'package:card_app/utils/size_config.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:fluttertoast/fluttertoast.dart'; 7 | 8 | class CardDetailPage extends StatefulWidget { 9 | final YgoCard card; 10 | 11 | CardDetailPage({Key key, @required this.card}) : super(key: key); 12 | 13 | @override 14 | _CardDetailPageState createState() => _CardDetailPageState(); 15 | } 16 | 17 | class _CardDetailPageState extends State { 18 | 19 | bool isFavourite; 20 | 21 | @override 22 | void initState() { 23 | Fluttertoast.cancel(); 24 | Fluttertoast.showToast( 25 | msg: widget.card.name, 26 | toastLength: Toast.LENGTH_SHORT, 27 | gravity: ToastGravity.BOTTOM, 28 | timeInSecForIos: 1, 29 | backgroundColor: cardTypeColor(widget.card.type), 30 | textColor: Colors.white, 31 | fontSize: 16.0); 32 | isFavourite = false; 33 | super.initState(); 34 | } 35 | 36 | @override 37 | Widget build(BuildContext context) { 38 | SizeConfig().init(context); 39 | return Scaffold( 40 | appBar: AppBar( 41 | title: Text("Card Information"), 42 | actions: [], 43 | ), 44 | body: SingleChildScrollView( 45 | physics: BouncingScrollPhysics(), 46 | child: Container( 47 | margin: EdgeInsets.all(12), 48 | width: SizeConfig.screenWidth, 49 | child: widget.card.type.toLowerCase().contains("monster") 50 | ? monsterCard() 51 | : spellCard(), 52 | ), 53 | ), 54 | ); 55 | } 56 | 57 | Widget spellCard() { 58 | return Column( 59 | mainAxisSize: MainAxisSize.max, 60 | crossAxisAlignment: CrossAxisAlignment.center, 61 | children: [ 62 | cardImageContainer(), 63 | // Name 64 | spellNameContainer(), 65 | // Type 66 | spellTypeContainer(), 67 | // Race 68 | spellRaceContainer(), 69 | // Archetype 70 | spellArcheContainer(), 71 | // Desc 72 | descContainer(), 73 | // Sets 74 | setsContainer(), 75 | ], 76 | ); 77 | } 78 | 79 | Widget monsterCard() { 80 | return Column( 81 | mainAxisSize: MainAxisSize.max, 82 | crossAxisAlignment: CrossAxisAlignment.center, 83 | children: [ 84 | cardImageContainer(), 85 | // Name 86 | monsterNameContainer(), 87 | // Type 88 | spellTypeContainer(), 89 | // Atk/Def 90 | atkDefContainer(), 91 | // Attribute 92 | attributeContainer(), 93 | // Race 94 | monsterRaceContainer(), 95 | // Archetype 96 | spellArcheContainer(), 97 | // Desc 98 | descContainer(), 99 | // Sets 100 | setsContainer(), 101 | ], 102 | ); 103 | } 104 | 105 | Card cardImageContainer() { 106 | return Card( 107 | elevation: 6, 108 | child: Container( 109 | child: CachedNetworkImage( 110 | height: SizeConfig.blockSizeVertical * 35, 111 | imageUrl: "https://ygoprodeck.com/pics/${widget.card.id}.jpg", 112 | ), 113 | ), 114 | ); 115 | } 116 | 117 | Container descContainer() { 118 | return Container( 119 | padding: EdgeInsets.all(8), 120 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 121 | child: Row( 122 | children: [ 123 | Expanded( 124 | child: Container( 125 | child: Text( 126 | widget.card.desc, 127 | style: TextStyle(fontSize: 14), 128 | textAlign: TextAlign.justify, 129 | ), 130 | ), 131 | ), 132 | ], 133 | ), 134 | decoration: BoxDecoration( 135 | border: Border.all( 136 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 137 | ); 138 | } 139 | 140 | Container spellArcheContainer() { 141 | return widget.card.archetype != null 142 | ? Container( 143 | padding: EdgeInsets.all(8), 144 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 145 | child: Row( 146 | children: [ 147 | CachedNetworkImage( 148 | width: 12, 149 | imageUrl: Constants.imgArchetype, 150 | ), 151 | Container( 152 | margin: EdgeInsets.only(left: 8), 153 | child: Text("Archetype: "), 154 | ), 155 | Container( 156 | child: Text( 157 | widget.card.archetype, 158 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 159 | ), 160 | ), 161 | ], 162 | ), 163 | decoration: BoxDecoration( 164 | border: Border.all( 165 | color: Colors.black12, 166 | width: 1, 167 | style: BorderStyle.solid, 168 | ), 169 | ), 170 | ) 171 | : Container(); 172 | } 173 | 174 | Container spellRaceContainer() { 175 | return Container( 176 | padding: EdgeInsets.all(8), 177 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 178 | child: Row( 179 | children: [ 180 | CachedNetworkImage( 181 | width: 12, 182 | imageUrl: "${Constants.imgSpellTypeUrl}${widget.card.race}.png", 183 | ), 184 | Container( 185 | margin: EdgeInsets.only(left: 8), 186 | child: Text("Type: "), 187 | ), 188 | Container( 189 | child: Text( 190 | widget.card.race, 191 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 192 | ), 193 | ), 194 | ], 195 | ), 196 | decoration: BoxDecoration( 197 | border: Border.all( 198 | color: Colors.black12, 199 | width: 1, 200 | style: BorderStyle.solid, 201 | ), 202 | ), 203 | ); 204 | } 205 | 206 | Container spellTypeContainer() { 207 | return Container( 208 | padding: EdgeInsets.all(8), 209 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 210 | child: Row( 211 | children: [ 212 | CachedNetworkImage( 213 | width: 12, 214 | imageUrl: "${Constants.imgTypeUrl}${widget.card.type}.jpg", 215 | ), 216 | Container( 217 | margin: EdgeInsets.only(left: 8), 218 | child: Text( 219 | widget.card.type, 220 | style: TextStyle( 221 | fontSize: 14, 222 | color: cardTypeColor(widget.card.type), 223 | fontWeight: FontWeight.w600), 224 | ), 225 | ), 226 | Container( 227 | margin: EdgeInsets.only(left: 4), 228 | child: Text("/ ID: ${widget.card.id}"), 229 | ) 230 | ], 231 | ), 232 | decoration: BoxDecoration( 233 | border: Border.all( 234 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 235 | ); 236 | } 237 | 238 | Container spellNameContainer() { 239 | return Container( 240 | padding: EdgeInsets.all(8), 241 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 242 | child: Row( 243 | children: [ 244 | Expanded( 245 | child: Container( 246 | child: Text( 247 | widget.card.name, 248 | style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), 249 | ), 250 | ), 251 | ), 252 | ], 253 | ), 254 | decoration: BoxDecoration( 255 | border: Border.all( 256 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 257 | ); 258 | } 259 | 260 | Container monsterRaceContainer() { 261 | return Container( 262 | padding: EdgeInsets.all(8), 263 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 264 | child: Row( 265 | children: [ 266 | CachedNetworkImage( 267 | width: 12, 268 | imageUrl: "${Constants.imgMonsterTypeUrl}${widget.card.race}.png", 269 | ), 270 | Container( 271 | margin: EdgeInsets.only(left: 8), 272 | child: Text("Type: "), 273 | ), 274 | Container( 275 | child: Text( 276 | widget.card.race, 277 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 278 | ), 279 | ), 280 | ], 281 | ), 282 | decoration: BoxDecoration( 283 | border: Border.all( 284 | color: Colors.black12, 285 | width: 1, 286 | style: BorderStyle.solid, 287 | ), 288 | ), 289 | ); 290 | } 291 | 292 | Container attributeContainer() { 293 | return Container( 294 | padding: EdgeInsets.all(8), 295 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 296 | child: Row( 297 | children: [ 298 | CachedNetworkImage( 299 | width: 12, 300 | imageUrl: 301 | "${Constants.imgMonsterTypeUrl}${widget.card.attribute}.jpg", 302 | ), 303 | Container( 304 | margin: EdgeInsets.only(left: 8), 305 | child: Text("Attribute: "), 306 | ), 307 | Container( 308 | child: Text( 309 | widget.card.attribute, 310 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 311 | ), 312 | ), 313 | ], 314 | ), 315 | decoration: BoxDecoration( 316 | border: Border.all( 317 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 318 | ); 319 | } 320 | 321 | Container atkDefContainer() { 322 | return Container( 323 | padding: EdgeInsets.all(8), 324 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 325 | child: Row( 326 | children: [ 327 | Container( 328 | child: Text("ATK: "), 329 | ), 330 | Container( 331 | child: Text( 332 | widget.card.atk, 333 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 334 | ), 335 | ), 336 | Container( 337 | margin: EdgeInsets.only(left: 8), 338 | child: Text("DEF: "), 339 | ), 340 | Container( 341 | child: Text( 342 | widget.card.def, 343 | style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600), 344 | ), 345 | ), 346 | ], 347 | ), 348 | decoration: BoxDecoration( 349 | border: Border.all( 350 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 351 | ); 352 | } 353 | 354 | Container monsterNameContainer() { 355 | return Container( 356 | padding: EdgeInsets.all(8), 357 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 358 | child: Row( 359 | children: [ 360 | Expanded( 361 | child: Container( 362 | child: Text( 363 | widget.card.name, 364 | style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600), 365 | ), 366 | ), 367 | ), 368 | Container( 369 | height: 12, 370 | margin: EdgeInsets.only(left: 8), 371 | child: CachedNetworkImage(imageUrl: Constants.imgLevelUrl), 372 | ), 373 | Container( 374 | margin: EdgeInsets.only(left: 2), 375 | child: Text(widget.card.level), 376 | ) 377 | ], 378 | ), 379 | decoration: BoxDecoration( 380 | border: Border.all( 381 | color: Colors.black12, width: 1, style: BorderStyle.solid)), 382 | ); 383 | } 384 | 385 | Container setsContainer() { 386 | return widget.card.cardSets != null 387 | ? Container( 388 | padding: EdgeInsets.all(8), 389 | margin: EdgeInsets.only(top: SizeConfig.blockSizeVertical * 2), 390 | child: Column( 391 | mainAxisSize: MainAxisSize.max, 392 | mainAxisAlignment: MainAxisAlignment.center, 393 | children: [ 394 | Container( 395 | margin: EdgeInsets.only(bottom: 4), 396 | child: Text( 397 | "Sets", 398 | style: TextStyle( 399 | fontSize: 14, 400 | fontWeight: FontWeight.w600, 401 | ), 402 | ), 403 | ), 404 | Divider( 405 | height: 0.0, 406 | ), 407 | ListView.builder( 408 | physics: NeverScrollableScrollPhysics(), 409 | scrollDirection: Axis.vertical, 410 | shrinkWrap: true, 411 | itemCount: widget.card.cardSets.length, 412 | itemBuilder: (_, index) { 413 | final set = widget.card.cardSets[index]; 414 | return Column( 415 | children: [ 416 | Container( 417 | margin: EdgeInsets.only(top: 6, bottom: 6), 418 | child: Row( 419 | children: [ 420 | Container( 421 | child: Text("(${set.setRarity}) "), 422 | ), 423 | Expanded( 424 | child: Container( 425 | child: Text( 426 | "${set.setName} ", 427 | overflow: TextOverflow.ellipsis, 428 | ), 429 | ), 430 | ), 431 | Container( 432 | margin: EdgeInsets.only(left: 8), 433 | child: Text("\$${set.setPrice}"), 434 | ) 435 | ], 436 | ), 437 | ), 438 | Divider( 439 | height: 0.0, 440 | ) 441 | ], 442 | ); 443 | }, 444 | ), 445 | ], 446 | ), 447 | decoration: BoxDecoration( 448 | border: Border.all( 449 | color: Colors.black12, 450 | width: 1, 451 | style: BorderStyle.solid, 452 | ), 453 | ), 454 | ) 455 | : Container(); 456 | } 457 | 458 | Color cardTypeColor(String type) { 459 | if (type.toLowerCase().contains('spell')) { 460 | return Colors.teal; 461 | } else if (type.toLowerCase().contains('skill')) { 462 | return Colors.teal; 463 | } else if (type.toLowerCase().contains('monster')) { 464 | return Colors.brown; 465 | } else if (type.toLowerCase().contains('trap')) { 466 | return Colors.pink[800]; 467 | } else { 468 | return Colors.blueAccent; 469 | } 470 | } 471 | } 472 | -------------------------------------------------------------------------------- /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 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 19 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 20 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXCopyFilesBuildPhase section */ 24 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 25 | isa = PBXCopyFilesBuildPhase; 26 | buildActionMask = 2147483647; 27 | dstPath = ""; 28 | dstSubfolderSpec = 10; 29 | files = ( 30 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 31 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 32 | ); 33 | name = "Embed Frameworks"; 34 | runOnlyForDeploymentPostprocessing = 0; 35 | }; 36 | /* End PBXCopyFilesBuildPhase section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 40 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 41 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 42 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 43 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 44 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 45 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 46 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 47 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 48 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 49 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 51 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 52 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 53 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 62 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 63 | ); 64 | runOnlyForDeploymentPostprocessing = 0; 65 | }; 66 | /* End PBXFrameworksBuildPhase section */ 67 | 68 | /* Begin PBXGroup section */ 69 | 9740EEB11CF90186004384FC /* Flutter */ = { 70 | isa = PBXGroup; 71 | children = ( 72 | 3B80C3931E831B6300D905FE /* App.framework */, 73 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 74 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 75 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 76 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 77 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 78 | ); 79 | name = Flutter; 80 | sourceTree = ""; 81 | }; 82 | 97C146E51CF9000F007C117D = { 83 | isa = PBXGroup; 84 | children = ( 85 | 9740EEB11CF90186004384FC /* Flutter */, 86 | 97C146F01CF9000F007C117D /* Runner */, 87 | 97C146EF1CF9000F007C117D /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 97C146EF1CF9000F007C117D /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 97C146EE1CF9000F007C117D /* Runner.app */, 95 | ); 96 | name = Products; 97 | sourceTree = ""; 98 | }; 99 | 97C146F01CF9000F007C117D /* Runner */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 103 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 104 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 105 | 97C147021CF9000F007C117D /* Info.plist */, 106 | 97C146F11CF9000F007C117D /* Supporting Files */, 107 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 108 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 109 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 110 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 111 | ); 112 | path = Runner; 113 | sourceTree = ""; 114 | }; 115 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | ); 119 | name = "Supporting Files"; 120 | sourceTree = ""; 121 | }; 122 | /* End PBXGroup section */ 123 | 124 | /* Begin PBXNativeTarget section */ 125 | 97C146ED1CF9000F007C117D /* Runner */ = { 126 | isa = PBXNativeTarget; 127 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 128 | buildPhases = ( 129 | 9740EEB61CF901F6004384FC /* Run Script */, 130 | 97C146EA1CF9000F007C117D /* Sources */, 131 | 97C146EB1CF9000F007C117D /* Frameworks */, 132 | 97C146EC1CF9000F007C117D /* Resources */, 133 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 134 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = Runner; 141 | productName = Runner; 142 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | 97C146E61CF9000F007C117D /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | LastUpgradeCheck = 0910; 152 | ORGANIZATIONNAME = "The Chromium Authors"; 153 | TargetAttributes = { 154 | 97C146ED1CF9000F007C117D = { 155 | CreatedOnToolsVersion = 7.3.1; 156 | LastSwiftMigration = 0910; 157 | }; 158 | }; 159 | }; 160 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 161 | compatibilityVersion = "Xcode 3.2"; 162 | developmentRegion = English; 163 | hasScannedForEncodings = 0; 164 | knownRegions = ( 165 | en, 166 | Base, 167 | ); 168 | mainGroup = 97C146E51CF9000F007C117D; 169 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 170 | projectDirPath = ""; 171 | projectRoot = ""; 172 | targets = ( 173 | 97C146ED1CF9000F007C117D /* Runner */, 174 | ); 175 | }; 176 | /* End PBXProject section */ 177 | 178 | /* Begin PBXResourcesBuildPhase section */ 179 | 97C146EC1CF9000F007C117D /* Resources */ = { 180 | isa = PBXResourcesBuildPhase; 181 | buildActionMask = 2147483647; 182 | files = ( 183 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 184 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 185 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 186 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 187 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXResourcesBuildPhase section */ 192 | 193 | /* Begin PBXShellScriptBuildPhase section */ 194 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 195 | isa = PBXShellScriptBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | ); 199 | inputPaths = ( 200 | ); 201 | name = "Thin Binary"; 202 | outputPaths = ( 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | shellPath = /bin/sh; 206 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 207 | }; 208 | 9740EEB61CF901F6004384FC /* Run Script */ = { 209 | isa = PBXShellScriptBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | ); 213 | inputPaths = ( 214 | ); 215 | name = "Run Script"; 216 | outputPaths = ( 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | shellPath = /bin/sh; 220 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 221 | }; 222 | /* End PBXShellScriptBuildPhase section */ 223 | 224 | /* Begin PBXSourcesBuildPhase section */ 225 | 97C146EA1CF9000F007C117D /* Sources */ = { 226 | isa = PBXSourcesBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 230 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 231 | ); 232 | runOnlyForDeploymentPostprocessing = 0; 233 | }; 234 | /* End PBXSourcesBuildPhase section */ 235 | 236 | /* Begin PBXVariantGroup section */ 237 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 238 | isa = PBXVariantGroup; 239 | children = ( 240 | 97C146FB1CF9000F007C117D /* Base */, 241 | ); 242 | name = Main.storyboard; 243 | sourceTree = ""; 244 | }; 245 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 97C147001CF9000F007C117D /* Base */, 249 | ); 250 | name = LaunchScreen.storyboard; 251 | sourceTree = ""; 252 | }; 253 | /* End PBXVariantGroup section */ 254 | 255 | /* Begin XCBuildConfiguration section */ 256 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 257 | isa = XCBuildConfiguration; 258 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 259 | buildSettings = { 260 | ALWAYS_SEARCH_USER_PATHS = NO; 261 | CLANG_ANALYZER_NONNULL = YES; 262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 263 | CLANG_CXX_LIBRARY = "libc++"; 264 | CLANG_ENABLE_MODULES = YES; 265 | CLANG_ENABLE_OBJC_ARC = YES; 266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_COMMA = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 271 | CLANG_WARN_EMPTY_BODY = YES; 272 | CLANG_WARN_ENUM_CONVERSION = YES; 273 | CLANG_WARN_INFINITE_RECURSION = YES; 274 | CLANG_WARN_INT_CONVERSION = YES; 275 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 276 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 277 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 278 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 279 | CLANG_WARN_STRICT_PROTOTYPES = YES; 280 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 281 | CLANG_WARN_UNREACHABLE_CODE = YES; 282 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 283 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 284 | COPY_PHASE_STRIP = NO; 285 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 286 | ENABLE_NS_ASSERTIONS = NO; 287 | ENABLE_STRICT_OBJC_MSGSEND = YES; 288 | GCC_C_LANGUAGE_STANDARD = gnu99; 289 | GCC_NO_COMMON_BLOCKS = YES; 290 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 291 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 292 | GCC_WARN_UNDECLARED_SELECTOR = YES; 293 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 294 | GCC_WARN_UNUSED_FUNCTION = YES; 295 | GCC_WARN_UNUSED_VARIABLE = YES; 296 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 297 | MTL_ENABLE_DEBUG_INFO = NO; 298 | SDKROOT = iphoneos; 299 | TARGETED_DEVICE_FAMILY = "1,2"; 300 | VALIDATE_PRODUCT = YES; 301 | }; 302 | name = Profile; 303 | }; 304 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 305 | isa = XCBuildConfiguration; 306 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 307 | buildSettings = { 308 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 309 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 310 | DEVELOPMENT_TEAM = S8QB4VV633; 311 | ENABLE_BITCODE = NO; 312 | FRAMEWORK_SEARCH_PATHS = ( 313 | "$(inherited)", 314 | "$(PROJECT_DIR)/Flutter", 315 | ); 316 | INFOPLIST_FILE = Runner/Info.plist; 317 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 318 | LIBRARY_SEARCH_PATHS = ( 319 | "$(inherited)", 320 | "$(PROJECT_DIR)/Flutter", 321 | ); 322 | PRODUCT_BUNDLE_IDENTIFIER = com.juvetic.cardApp; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | SWIFT_VERSION = 4.0; 325 | VERSIONING_SYSTEM = "apple-generic"; 326 | }; 327 | name = Profile; 328 | }; 329 | 97C147031CF9000F007C117D /* Debug */ = { 330 | isa = XCBuildConfiguration; 331 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_ANALYZER_NONNULL = YES; 335 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 336 | CLANG_CXX_LIBRARY = "libc++"; 337 | CLANG_ENABLE_MODULES = YES; 338 | CLANG_ENABLE_OBJC_ARC = YES; 339 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 340 | CLANG_WARN_BOOL_CONVERSION = YES; 341 | CLANG_WARN_COMMA = YES; 342 | CLANG_WARN_CONSTANT_CONVERSION = YES; 343 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 344 | CLANG_WARN_EMPTY_BODY = YES; 345 | CLANG_WARN_ENUM_CONVERSION = YES; 346 | CLANG_WARN_INFINITE_RECURSION = YES; 347 | CLANG_WARN_INT_CONVERSION = YES; 348 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 349 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 350 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 351 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 352 | CLANG_WARN_STRICT_PROTOTYPES = YES; 353 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 354 | CLANG_WARN_UNREACHABLE_CODE = YES; 355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 356 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 357 | COPY_PHASE_STRIP = NO; 358 | DEBUG_INFORMATION_FORMAT = dwarf; 359 | ENABLE_STRICT_OBJC_MSGSEND = YES; 360 | ENABLE_TESTABILITY = YES; 361 | GCC_C_LANGUAGE_STANDARD = gnu99; 362 | GCC_DYNAMIC_NO_PIC = NO; 363 | GCC_NO_COMMON_BLOCKS = YES; 364 | GCC_OPTIMIZATION_LEVEL = 0; 365 | GCC_PREPROCESSOR_DEFINITIONS = ( 366 | "DEBUG=1", 367 | "$(inherited)", 368 | ); 369 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 370 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 371 | GCC_WARN_UNDECLARED_SELECTOR = YES; 372 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 373 | GCC_WARN_UNUSED_FUNCTION = YES; 374 | GCC_WARN_UNUSED_VARIABLE = YES; 375 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 376 | MTL_ENABLE_DEBUG_INFO = YES; 377 | ONLY_ACTIVE_ARCH = YES; 378 | SDKROOT = iphoneos; 379 | TARGETED_DEVICE_FAMILY = "1,2"; 380 | }; 381 | name = Debug; 382 | }; 383 | 97C147041CF9000F007C117D /* Release */ = { 384 | isa = XCBuildConfiguration; 385 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 386 | buildSettings = { 387 | ALWAYS_SEARCH_USER_PATHS = NO; 388 | CLANG_ANALYZER_NONNULL = YES; 389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 390 | CLANG_CXX_LIBRARY = "libc++"; 391 | CLANG_ENABLE_MODULES = YES; 392 | CLANG_ENABLE_OBJC_ARC = YES; 393 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 394 | CLANG_WARN_BOOL_CONVERSION = YES; 395 | CLANG_WARN_COMMA = YES; 396 | CLANG_WARN_CONSTANT_CONVERSION = YES; 397 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 398 | CLANG_WARN_EMPTY_BODY = YES; 399 | CLANG_WARN_ENUM_CONVERSION = YES; 400 | CLANG_WARN_INFINITE_RECURSION = YES; 401 | CLANG_WARN_INT_CONVERSION = YES; 402 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 403 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 404 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 405 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 406 | CLANG_WARN_STRICT_PROTOTYPES = YES; 407 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 408 | CLANG_WARN_UNREACHABLE_CODE = YES; 409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 411 | COPY_PHASE_STRIP = NO; 412 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 413 | ENABLE_NS_ASSERTIONS = NO; 414 | ENABLE_STRICT_OBJC_MSGSEND = YES; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_NO_COMMON_BLOCKS = YES; 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 424 | MTL_ENABLE_DEBUG_INFO = NO; 425 | SDKROOT = iphoneos; 426 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | VALIDATE_PRODUCT = YES; 429 | }; 430 | name = Release; 431 | }; 432 | 97C147061CF9000F007C117D /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 435 | buildSettings = { 436 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 437 | CLANG_ENABLE_MODULES = YES; 438 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 439 | ENABLE_BITCODE = NO; 440 | FRAMEWORK_SEARCH_PATHS = ( 441 | "$(inherited)", 442 | "$(PROJECT_DIR)/Flutter", 443 | ); 444 | INFOPLIST_FILE = Runner/Info.plist; 445 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 446 | LIBRARY_SEARCH_PATHS = ( 447 | "$(inherited)", 448 | "$(PROJECT_DIR)/Flutter", 449 | ); 450 | PRODUCT_BUNDLE_IDENTIFIER = com.juvetic.cardApp; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 453 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 454 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 455 | SWIFT_VERSION = 4.0; 456 | VERSIONING_SYSTEM = "apple-generic"; 457 | }; 458 | name = Debug; 459 | }; 460 | 97C147071CF9000F007C117D /* Release */ = { 461 | isa = XCBuildConfiguration; 462 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 463 | buildSettings = { 464 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 465 | CLANG_ENABLE_MODULES = YES; 466 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 467 | ENABLE_BITCODE = NO; 468 | FRAMEWORK_SEARCH_PATHS = ( 469 | "$(inherited)", 470 | "$(PROJECT_DIR)/Flutter", 471 | ); 472 | INFOPLIST_FILE = Runner/Info.plist; 473 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 474 | LIBRARY_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "$(PROJECT_DIR)/Flutter", 477 | ); 478 | PRODUCT_BUNDLE_IDENTIFIER = com.juvetic.cardApp; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 481 | SWIFT_SWIFT3_OBJC_INFERENCE = On; 482 | SWIFT_VERSION = 4.0; 483 | VERSIONING_SYSTEM = "apple-generic"; 484 | }; 485 | name = Release; 486 | }; 487 | /* End XCBuildConfiguration section */ 488 | 489 | /* Begin XCConfigurationList section */ 490 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 491 | isa = XCConfigurationList; 492 | buildConfigurations = ( 493 | 97C147031CF9000F007C117D /* Debug */, 494 | 97C147041CF9000F007C117D /* Release */, 495 | 249021D3217E4FDB00AE95B9 /* Profile */, 496 | ); 497 | defaultConfigurationIsVisible = 0; 498 | defaultConfigurationName = Release; 499 | }; 500 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 501 | isa = XCConfigurationList; 502 | buildConfigurations = ( 503 | 97C147061CF9000F007C117D /* Debug */, 504 | 97C147071CF9000F007C117D /* Release */, 505 | 249021D4217E4FDB00AE95B9 /* Profile */, 506 | ); 507 | defaultConfigurationIsVisible = 0; 508 | defaultConfigurationName = Release; 509 | }; 510 | /* End XCConfigurationList section */ 511 | 512 | }; 513 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 514 | } 515 | --------------------------------------------------------------------------------