Initial commit

This commit is contained in:
salvadordeveloper
2021-05-27 15:59:34 -06:00
commit b279b64c6e
174 changed files with 10603 additions and 0 deletions

5
.codecov.yml Normal file
View File

@ -0,0 +1,5 @@
ignore:
- '**/**/**/*.g.dart'
- '**/**/**/*.freezed.dart'
- '**/**/**/**/*.g.dart'
- '**/**/**/**/*.freezed.dart'

1
.env.example Normal file
View File

@ -0,0 +1 @@
API_KEY=

45
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: release
on:
push:
tags:
- 'v*'
env:
flutter_version: "2.2.0"
jobs:
build_deploy:
name: Build apk and release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Cache Flutter dependencies
uses: actions/cache@v1
with:
path: /opt/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache-${{ env.flutter_version }}
- uses: subosito/flutter-action@v1
with:
flutter-version: ${{ env.flutter_version }}
channel: 'stable'
- run: flutter pub get
# build Android version
- name: Create env file
run: |
touch .env
echo API_KEY=${{ secrets.API_KEY }} >> .env
cat .env
- run: flutter build apk --split-per-abi
# This action will create a github release and optionally upload an artifact to it.
# https://github.com/ncipollo/release-action
- name: Extract release notes
id: extract-release-notes
uses: ffurrer2/extract-release-notes@v1
- name: Create a Release APK
uses: ncipollo/release-action@v1
with:
artifacts: "build/app/outputs/apk/release/*.apk"
token: ${{ secrets.GITHUB_TOKEN }}
body: ${{ steps.extract-release-notes.outputs.release_notes }}

128
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,128 @@
#The name of your workflow.
name: test
# Trigger the workflow on push or pull request
on: [push,pull_request_review]
env:
flutter_version: "2.2.0"
#A workflow run is made up of one or more jobs. Jobs run in parallel by default.
jobs:
unit-testing:
#The type of machine to run the job on. [windows,macos, ubuntu , self-hosted]
runs-on: ubuntu-latest
#sequence of tasks called
steps:
# The branch or tag ref that triggered the workflow will be checked out.
# https://github.com/actions/checkout
- uses: actions/checkout@v1
# Setup a flutter environment.
# https://github.com/marketplace/actions/flutter-action
- name: Cache Flutter dependencies
uses: actions/cache@v1
with:
path: /opt/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache-${{ env.flutter_version }}
- uses: subosito/flutter-action@v1
with:
flutter-version: '${{ env.flutter_version }}'
channel: 'stable'
- name: Create env file
run: |
touch .env
echo API_KEY=${{ secrets.API_KEY }} >> .env
cat .env
- run: flutter pub get
# run static analys code
- run: flutter analyze
# run flutter widgets tests and unit tests
- run: flutter test --coverage
# Upload coverage reports to Codecov
# https://github.com/marketplace/actions/codecov
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: coverage/lcov.info
ios-integration:
#creates a build matrix for your jobs
strategy:
#set of different configurations of the virtual environment.
matrix:
device:
- "iPhone 8 (14.4)"
- "iPhone 12 Pro Max (14.4)"
fail-fast: false
runs-on: macos-latest
#Identifies any jobs that must complete successfully before this job will run.
needs: unit-testing
steps:
- name: List all simulators
run: xcrun instruments -s
# get UUID simulator and boot a simulator on mac from command line
- name: Start Simulator
run: |
UDID=$(
xcrun instruments -s |
awk \
-F ' *[][]' \
-v 'device=${{ matrix.device }}' \
'$1 == device { print $2 }'
)
xcrun simctl boot "${UDID:?No Simulator with this name found}"
- uses: actions/checkout@v1
- name: Cache Flutter dependencies
uses: actions/cache@v1
with:
path: /opt/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache-${{ env.flutter_version }}
- uses: subosito/flutter-action@v1
with:
flutter-version: '${{ env.flutter_version }}'
channel: 'stable'
- name: Create env file
run: |
touch .env
echo API_KEY=${{ secrets.API_KEY }} >> .env
cat .env
- run: flutter pub get
# Run flutter integrate tests
- name: Run Flutter Driver tests
run: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/main_test.dart
android-integration:
runs-on: macos-latest
#creates a build matrix for your jobs
strategy:
#set of different configurations of the virtual environment.
matrix:
api-level: [21, 29]
target: [default]
needs: unit-testing
steps:
- uses: actions/checkout@v1
- name: Cache Flutter dependencies
uses: actions/cache@v1
with:
path: /opt/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache-${{ env.flutter_version }}
- uses: subosito/flutter-action@v1
with:
flutter-version: '${{ env.flutter_version }}'
channel: 'stable'
- name: Create env file
run: |
touch .env
echo API_KEY=${{ secrets.API_KEY }} >> .env
cat .env
- name: Run Flutter Driver tests
#GitHub Action for installing, configuring and running Android Emulators (work only Mac OS)
#https://github.com/ReactiveCircus/android-emulator-runner
uses: reactivecircus/android-emulator-runner@v1
with:
api-level: ${{ matrix.api-level }}
target: ${{ matrix.target }}
arch: x86_64
profile: Nexus 6
script: flutter drive --driver=test_driver/integration_test.dart --target=integration_test/main_test.dart

46
.gitignore vendored Normal file
View File

@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Folder generated by flutter test --coverage
coverage/
.env

10
.metadata Normal file
View File

@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: 1aafb3a8b9b0c36241c5f5b34ee914770f015818
channel: stable
project_type: app

20
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "app_crypto",
"request": "launch",
"type": "dart"
},
{
"name": "App Crypto",
"program": "lib/main.dart",
"request": "launch",
"type": "dart",
"args": []
}
]
}

21
CHANGELOG.md Normal file
View File

@ -0,0 +1,21 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0] - 2021-05-27
### First version
## Features
- API REST (CryptoWatch)
- Linear Graph View (Hour, Day, Week, etc)
- OHLC Graph
- Search
- Light / Dark Theme
- Multi Lenguage
- Exchange Selection
- Favorite Pair

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Salvador Valverde
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

117
README.md Normal file
View File

@ -0,0 +1,117 @@
# Flutter Crypto APP
Complete Flutter Application with Riverpod & Freezed + Dio for API REST.
[![test](https://github.com/salvadordeveloper/flutter-crypto-app/actions/workflows/tests.yml/badge.svg)](https://github.com/salvadordeveloper/flutter-crypto-app/actions/workflows/tests.yml)
[![build](https://github.com/salvadordeveloper/flutter-crypto-app/actions/workflows/release.yml/badge.svg)](https://github.com/salvadordeveloper/flutter-crypto-app/actions/workflows/release.yml)
[![codecov](https://codecov.io/gh/salvadordeveloper/flutter-crypto-app/branch/main/graph/badge.svg?token=UYU0OB442S)](https://codecov.io/gh/salvadordeveloper/flutter-crypto-app)
[![Flutter version](https://img.shields.io/badge/flutter-2.2.0-blue?logo=flutter)](https://flutter.dev/docs/get-started/install)
[![GitHub license](https://img.shields.io/github/license/chinnonsantos/full_testing_flutter)](https://choosealicense.com/licenses/mit/)
<img src="screenshots/cover.png" >
## Features
- API REST (CryptoWatch)
- Linear Graph View (Hour, Day, Week, etc)
- OHLC Graph
- Search
- Light / Dark Theme
- Multi Lenguage
- Exchange Selection
- Favorite Pair
### Stack
- Flutter 2.2.0
- Riverpod + Hooks
- Freezed
- Dio
### Testing
- Unit Testing (flutter_test)
- Integration Testing (integration_test)
- Mock Data (http_mock_adapter)
- Github Actions (iOS & Android Integration Test)
## Screenshots
| Home | Details | Settings |
| --- | --- | --- |
|<img src="screenshots/1_dark.jpeg" width="250">|<img src="screenshots/2_dark.jpeg" width="250">|<img src="screenshots/4_dark.jpeg" width="250">|
|<img src="screenshots/1_light.jpeg" width="250">|<img src="screenshots/2_light.jpeg" width="250">|<img src="screenshots/4_light.jpeg" width="250">|
## Setup project
Download project
```bash
git clone https://github.com/salvadordeveloper/flutter-crypto-app
```
Get flutter dependencies
```bash
flutter pub get
```
You need to create an account at https://cryptowat.ch/ to get a personal API KEY
Rename the env.example file to .env and put there you API KEY
```bash
API_KEY={CryptoWatch_KEY}
```
Run the app
```bash
flutter run
```
If you have any error with generated files try to run this
```bash
flutter pub run build_runner build --delete-conflicting-outputs
```
### Testing
Unit Test
```bash
flutter test
```
Integration Test
```bash
flutter drive --driver=test_driver/integration_test.dart --target=integration_test/main_test.dart
```
## Resources
[Flutter Docs](https://flutter.dev/docs)
[Riverpod Docs](https://riverpod.dev/docs/getting_started/)
[Cryptowatch Docs](https://docs.cryptowat.ch/rest-api/)
## Licence
```
MIT License
Copyright (c) 2021 Salvador Valverde
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

10
analysis_options.yaml Normal file
View File

@ -0,0 +1,10 @@
#include: package:effective_dart/analysis_options.yaml
analyzer:
enable-experiment:
- non-nullable
exclude:
- "**/*.g.dart"
- "**/*.freezed.dart"

11
android/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties

63
android/app/build.gradle Normal file
View File

@ -0,0 +1,63 @@
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 29
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.cryptocurrency_app"
minSdkVersion 18
targetSdkVersion 29
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cryptocurrency_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@ -0,0 +1,48 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cryptocurrency_app">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name="io.flutter.app.FlutterApplication"
android:label="Crypto App"
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

View File

@ -0,0 +1,6 @@
package com.example.cryptocurrency_app
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
</style>
</resources>

View File

@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cryptocurrency_app">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

31
android/build.gradle Normal file
View File

@ -0,0 +1,31 @@
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View File

@ -0,0 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip

11
android/settings.gradle Normal file
View File

@ -0,0 +1,11 @@
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

BIN
assets/icon/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,50 @@
{
"homeTitle" : "Home",
"openChart" : "Open Chart",
"searchTitle" : "Search",
"searchBar" : "Search coin...",
"noResults" : "No results",
"settingsTitle": "Settings",
"languageSection" : "Language",
"language": "Language",
"dataSection" : "Data",
"exchange" : "Exchange",
"topPair" : "Top Pair",
"designSection" : "Design",
"appTheme" : "App theme",
"spanish" : "Spanish",
"english" : "English",
"summary" : "Summary",
"orderbook" : "Orderbook",
"trades" : "Trades",
"ohlc" : "OHLC",
"price" : "Price",
"last" : "Last",
"high" : "High",
"low" : "Low",
"change" : "Change",
"volume" : "Volume",
"quoteVolume" : "Quote Volume",
"time" : "Time",
"amount" : "Amount",
"bid" : "Bid",
"ask" : "Ask",
"errorRequestCancelled" : "Request to API server was cancelled",
"errorConnectionTimeout" : "Connection timeout with API server",
"errorInternetConnection" : "Connection to API server failed due to internet connection",
"errorReceiveTimeout" : "Receive timeout in connection with API server",
"errorSendTimeout" : "Send timout in connection iwth API server",
"errorBadRequest": "Bad request",
"errorRequestNotFound": "The requested resource was not found",
"errorIntenalServer" : "Internal server error",
"errorSomethingWentWrong" : "Something went wrong"
}

View File

@ -0,0 +1,50 @@
{
"homeTitle" : "Inicio",
"openChart" : "Abrir grafica",
"searchTitle" : "Buscar",
"searchBar" : "Buscar moneda...",
"noResults" : "Sin resultados",
"settingsTitle": "Ajustes",
"languageSection" : "Lenguage",
"language": "Idioma",
"dataSection" : "Datos",
"exchange" : "Exchange",
"topPair" : "Top Par",
"designSection" : "Diseño",
"appTheme" : "Tema",
"spanish" : "Español",
"english" : "Ingles",
"summary" : "Resumen",
"orderbook" : "Orderbook",
"trades" : "Trades",
"ohlc" : "OHLC",
"price" : "Precio",
"last" : "Ultimo",
"high" : "Más alto",
"low" : "Más bajo",
"change" : "Cambio",
"volume" : "Volumen",
"quoteVolume" : "Quote Volume",
"time" : "Tiempo",
"amount" : "Cantidad",
"bid" : "Bid",
"ask" : "Ask",
"errorRequestCancelled" : "Request to API server was cancelled",
"errorConnectionTimeout" : "Connection timeout with API server",
"errorInternetConnection" : "Connection to API server failed due to internet connection",
"errorReceiveTimeout" : "Receive timeout in connection with API server",
"errorSendTimeout" : "Send timout in connection iwth API server",
"errorBadRequest": "Bad request",
"errorRequestNotFound": "The requested resource was not found",
"errorIntenalServer" : "Internal server error",
"errorSomethingWentWrong" : "Something went wrong"
}

View File

@ -0,0 +1,137 @@
class ApiData {
static final Map<String, dynamic> exchanges = {
"result": [
{
"id": 17,
"symbol": "mexbt",
"name": "meXBT",
"route": "https://api.cryptowat.ch/exchanges/mexbt",
"active": false
},
{
"id": 62,
"symbol": "coinone",
"name": "Coinone",
"route": "https://api.cryptowat.ch/exchanges/coinone",
"active": true
},
],
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
static final Map<String, dynamic> pairs = {
"result": [
{
"id": 579,
"exchange": "binance",
"pair": "btcusdt",
"active": true,
"route": "https://api.cryptowat.ch/markets/binance/btcusdt"
},
{
"id": 580,
"exchange": "binance",
"pair": "ethbtc",
"active": true,
"route": "https://api.cryptowat.ch/markets/binance/ethbtc"
},
{
"id": 581,
"exchange": "binance",
"pair": "ltcbtc",
"active": true,
"route": "https://api.cryptowat.ch/markets/binance/ltcbtc"
},
{
"id": 582,
"exchange": "binance",
"pair": "neobtc",
"active": true,
"route": "https://api.cryptowat.ch/markets/binance/neobtc"
},
],
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
static final Map<String, dynamic> pair_btcusdt_summary = {
"result": {
"price": {
"last": 35503.33,
"high": 43861.94,
"low": 30000,
"change": {"percentage": -0.18764266402587584, "absolute": -8200.75}
},
"volume": 257132.87322650044,
"volumeQuote": 10096197214.14349
},
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
static final Map<String, dynamic> pair_btcusdt_oderbook = {
"result": {
"asks": [
[35922.59, 0.004088],
[35925.23, 0.003071],
[35925.71, 0.012824],
[35927.12, 0.000556],
[35927.58, 0.2178],
],
"bids": [
[35904.23, 0.153095],
[35900.35, 0.082238],
[35898, 0.12],
[35897.99, 0.006152],
[35897.68, 0.04332],
],
"seqNum": 429614
},
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
static final Map<String, dynamic> pair_btcusdt_trades = {
"result": [
[0, 1621433110, 34452.66, 0.008464],
[0, 1621433110, 34454.43, 0.016662],
[0, 1621433110, 34485.69, 0.00476],
[0, 1621433110, 34475.97, 0.000401],
[0, 1621433110, 34456.09, 0.0011],
[0, 1621433110, 34456.09, 0.004997],
],
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
static final Map<String, dynamic> pair_btcusdt_graph = {
"result": {
"14400": [
[
1607054400,
19422.34,
19527,
19122.74,
19162.62,
8683.588417,
167917416.81467284
],
[
1607097600,
18835.47,
19146.22,
18686.38,
18943.35,
14717.586675,
278732315.17076141
],
[
1607112000,
18944.06,
19078.68,
18817,
19038.73,
8799.851665,
166925728.42698553
],
]
},
"allowance": {"cost": 0, "remaining": 100, "upgrade": ""}
};
}

View File

@ -0,0 +1,8 @@
import 'package:integration_test/integration_test.dart';
import 'search_test.dart' as app;
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
app.main();
}

View File

@ -0,0 +1,104 @@
import 'dart:async';
import 'package:cryptocurrency_app/constants/keys.dart';
import 'package:cryptocurrency_app/main.dart' as app;
import 'package:cryptocurrency_app/repository/crypto_repository.dart';
import 'package:dio/dio.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';
import 'data/api_data.dart';
void main() {
final dioAdapter = DioAdapter();
final dio = Dio();
setUpAll(() {
dio.httpClientAdapter = dioAdapter;
//Get graph
dioAdapter.onGet('/markets/binance/btcusdt/ohlc', (request) {
request.reply(200, ApiData.pair_btcusdt_graph);
});
//Get trades
dioAdapter.onGet('/markets/binance/btcusdt/trades', (request) {
request.reply(200, ApiData.pair_btcusdt_trades);
});
//Get orderbook
dioAdapter.onGet('/markets/binance/btcusdt/orderbook', (request) {
request.reply(200, ApiData.pair_btcusdt_oderbook);
});
//Get sumary of btcusdt
dioAdapter.onGet('/markets/binance/btcusdt/summary', (request) {
print(request.toString());
request.reply(200, ApiData.pair_btcusdt_summary);
});
//Get list of pairs from Binance
dioAdapter.onGet('/markets/binance', (request) {
print(request.toString());
request.reply(200, ApiData.pairs);
});
});
group('Search Screen Test', () {
testWidgets('Search screen loading data', (tester) async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(EasyLocalization(
supportedLocales: [Locale('en'), Locale('es')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
child: ProviderScope(
overrides: [clientProvider.overrideWithValue(dio)],
child: app.MyApp(),
)));
await tester.pumpAndSettle();
final searchButton = find.byKey(Keys.NAV_SEARCH);
await pumpUntilFound(tester, searchButton);
await tester.tap(searchButton);
await tester.pumpAndSettle();
final results = await find.byKey(Keys.PAIR_TILE);
expect(results, findsNWidgets(4));
final searchTextField = await find.byKey(Keys.SEARCH_TEXT_FIELD);
await tester.showKeyboard(searchTextField);
tester.testTextInput.enterText("btcusdt");
await tester.testTextInput.receiveAction(TextInputAction.done);
await tester.pumpAndSettle();
final resultsFiltered = await find.byKey(Keys.PAIR_TILE);
expect(resultsFiltered, findsOneWidget);
});
});
}
Future<void> pumpUntilFound(
WidgetTester tester,
Finder finder, {
Duration timeout = const Duration(seconds: 30),
}) async {
var timerDone = false;
final timer =
Timer(timeout, () => throw TimeoutException("Pump until has timed out"));
while (timerDone != true) {
await tester.pump();
final found = tester.any(finder);
if (found) {
timerDone = true;
}
}
timer.cancel();
}

32
ios/.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
</dict>
</plist>

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

41
ios/Podfile Normal file
View File

@ -0,0 +1,41 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

34
ios/Podfile.lock Normal file
View File

@ -0,0 +1,34 @@
PODS:
- Flutter (1.0.0)
- flutter_secure_storage (3.3.1):
- Flutter
- integration_test (0.0.1):
- Flutter
- shared_preferences (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- integration_test (from `.symlinks/plugins/integration_test/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_secure_storage:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
integration_test:
:path: ".symlinks/plugins/integration_test/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
SPEC CHECKSUMS:
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
COCOAPODS: 1.10.1

View File

@ -0,0 +1,575 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
E52D63AAC42E7D57198ABF57 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 13C8C2662A08886B38F840BE /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
13C8C2662A08886B38F840BE /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
470256A2C406E78196483DCD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CFC9D2888BE8ADB8479E4A6F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
F5B1D7DFF146D5EFF0E036BF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
E52D63AAC42E7D57198ABF57 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
C2A5875E2C18837D1F86EA8F /* Pods */,
A2BBB35B63AD12E0DD726378 /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
A2BBB35B63AD12E0DD726378 /* Frameworks */ = {
isa = PBXGroup;
children = (
13C8C2662A08886B38F840BE /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
C2A5875E2C18837D1F86EA8F /* Pods */ = {
isa = PBXGroup;
children = (
470256A2C406E78196483DCD /* Pods-Runner.debug.xcconfig */,
F5B1D7DFF146D5EFF0E036BF /* Pods-Runner.release.xcconfig */,
CFC9D2888BE8ADB8479E4A6F /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
EE7B0F0FC718AE4532930190 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
709721392DE5A8A9401AB1A3 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
709721392DE5A8A9401AB1A3 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
EE7B0F0FC718AE4532930190 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = M63FJ72T54;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.cryptocurrencyApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = M63FJ72T54;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.cryptocurrencyApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = M63FJ72T54;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.cryptocurrencyApp;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

51
ios/Runner/Info.plist Normal file
View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Crypto App</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
<string>es</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
class AppTheme {
static final ThemeData light = ThemeData(
iconTheme: IconThemeData(color: Colors.black87),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
backgroundColor: Colors.blueGrey,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white70),
appBarTheme: AppBarTheme(
color: Colors.blueGrey,
brightness: Brightness.dark,
),
scaffoldBackgroundColor: Colors.white,
accentColor: Colors.black54,
brightness: Brightness.light,
cardColor: Colors.grey[500],
unselectedWidgetColor: Colors.black45,
focusColor: Colors.black,
primarySwatch: Colors.blueGrey,
textTheme: TextTheme(
headline1: TextStyle(
color: Colors.black, fontSize: 40, fontWeight: FontWeight.w500),
headline2: TextStyle(
color: Colors.black, fontSize: 34, fontWeight: FontWeight.w400),
headline3: TextStyle(
color: Colors.black, fontSize: 22, fontWeight: FontWeight.w500),
headline4: TextStyle(
color: Colors.black54, fontSize: 16, fontWeight: FontWeight.bold),
headline5: TextStyle(
color: Colors.black, fontSize: 19, fontWeight: FontWeight.w700),
headline6: TextStyle(
color: Colors.black, fontSize: 13, fontWeight: FontWeight.w400),
subtitle1: TextStyle(
color: Colors.black87, fontSize: 14, fontWeight: FontWeight.normal),
subtitle2: TextStyle(
color: Colors.black, fontSize: 16, fontWeight: FontWeight.bold),
),
);
static final ThemeData dark = ThemeData(
primaryColor: Colors.black12,
bottomNavigationBarTheme: BottomNavigationBarThemeData(
backgroundColor: Colors.black,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white70),
appBarTheme: AppBarTheme(
color: Colors.black,
brightness: Brightness.dark,
),
scaffoldBackgroundColor: Colors.black,
accentColor: Colors.white54,
brightness: Brightness.dark,
focusColor: Colors.white,
primarySwatch: Colors.blueGrey,
textTheme: TextTheme(
headline1: TextStyle(
color: Colors.white, fontSize: 40, fontWeight: FontWeight.w500),
headline2: TextStyle(
color: Colors.white, fontSize: 34, fontWeight: FontWeight.w400),
headline3: TextStyle(
color: Colors.white, fontSize: 22, fontWeight: FontWeight.w500),
headline4: TextStyle(
color: Colors.white70, fontSize: 16, fontWeight: FontWeight.bold),
headline5: TextStyle(
color: Colors.white, fontSize: 19, fontWeight: FontWeight.w700),
headline6: TextStyle(
color: Colors.white, fontSize: 13, fontWeight: FontWeight.w400),
subtitle1: TextStyle(
color: Colors.white70, fontSize: 14, fontWeight: FontWeight.normal),
subtitle2: TextStyle(
color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold)),
);
}

View File

@ -0,0 +1,47 @@
import 'package:dio/dio.dart';
import '../../generated/locale_keys.g.dart';
class DataException implements Exception {
DataException({required this.message});
DataException.fromDioError(DioError dioError) {
switch (dioError.type) {
case DioErrorType.cancel:
message = LocaleKeys.errorRequestCancelled;
break;
case DioErrorType.connectTimeout:
message = LocaleKeys.errorConnectionTimeout;
break;
case DioErrorType.receiveTimeout:
message = LocaleKeys.errorReceiveTimeout;
break;
case DioErrorType.response:
message = _handleError(dioError.response!.statusCode!);
break;
case DioErrorType.sendTimeout:
message = LocaleKeys.errorSendTimeout;
break;
default:
message = LocaleKeys.errorInternetConnection;
break;
}
}
String message = "";
String _handleError(int statusCode) {
switch (statusCode) {
case 400:
return LocaleKeys.errorBadRequest;
case 404:
return LocaleKeys.errorRequestNotFound;
case 500:
return LocaleKeys.errorIntenalServer;
default:
return LocaleKeys.errorSomethingWentWrong;
}
}
@override
String toString() => message;
}

17
lib/constants/keys.dart Normal file
View File

@ -0,0 +1,17 @@
import 'package:flutter/material.dart';
class Keys {
static final NAV_BAR = Key('nav_bar');
static final NAV_HOME = Key('nav_home');
static final NAV_SEARCH = Key('nav_search');
static final NAV_SETTINGS = Key('nav_settings');
static final HOME_SCREEN = Key('home_screen');
static final SEARCH_SCREEN = Key('search_screen');
static final SETTINGS_SCREEN = Key('settings_screen');
static final DETAILS_SCREEN = Key('details_screen');
static final SEARCH_TEXT_FIELD = Key('seach_text_field');
static final PAIR_TILE = Key('pair_tile');
}

78
lib/constants/utils.dart Normal file
View File

@ -0,0 +1,78 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import '../models/graph/graph/graph.dart';
ThemeMode getThemeMode(String type) {
ThemeMode themeMode = ThemeMode.system;
switch (type) {
case "System":
themeMode = ThemeMode.system;
break;
case "Dark":
themeMode = ThemeMode.dark;
break;
case "Light":
themeMode = ThemeMode.light;
break;
}
return themeMode;
}
final themeModes = ["System", "Dark", "Light"];
final String defaultLenguage = "English";
final String defaultExchange = "binance";
final String defaultPair = "btcusdt";
final String defaultTheme = "System";
List<double> getPoints(Graph graph) {
if (graph.pairs[0].points.length > 0)
return graph.pairs[0].points.map((e) => e.closePrice).toList();
else
return [];
}
String epochToString(String epoch) {
final DateTime timeStamp =
DateTime.fromMillisecondsSinceEpoch(int.parse(epoch) * 1000);
return DateFormat('dd/MM/yyyy').format(timeStamp);
}
final List<double> demoGraphData = const [
86,
45,
59,
65,
1,
62,
26,
41,
88,
60,
17,
18,
58,
67,
55,
56,
97,
96,
22,
57,
29,
69,
19,
30,
47,
63,
33,
37,
40,
51,
53,
91,
71,
92,
28,
];

View File

@ -0,0 +1,44 @@
// DO NOT EDIT. This is code generated via package:easy_localization/generate.dart
abstract class LocaleKeys {
static const homeTitle = 'homeTitle';
static const openChart = 'openChart';
static const searchTitle = 'searchTitle';
static const searchBar = 'searchBar';
static const noResults = 'noResults';
static const settingsTitle = 'settingsTitle';
static const languageSection = 'languageSection';
static const language = 'language';
static const dataSection = 'dataSection';
static const exchange = 'exchange';
static const topPair = 'topPair';
static const designSection = 'designSection';
static const appTheme = 'appTheme';
static const spanish = 'spanish';
static const english = 'english';
static const summary = 'summary';
static const orderbook = 'orderbook';
static const trades = 'trades';
static const ohlc = 'ohlc';
static const price = 'price';
static const last = 'last';
static const high = 'high';
static const low = 'low';
static const change = 'change';
static const volume = 'volume';
static const quoteVolume = 'quoteVolume';
static const time = 'time';
static const amount = 'amount';
static const bid = 'bid';
static const ask = 'ask';
static const errorRequestCancelled = 'errorRequestCancelled';
static const errorConnectionTimeout = 'errorConnectionTimeout';
static const errorInternetConnection = 'errorInternetConnection';
static const errorReceiveTimeout = 'errorReceiveTimeout';
static const errorSendTimeout = 'errorSendTimeout';
static const errorBadRequest = 'errorBadRequest';
static const errorRequestNotFound = 'errorRequestNotFound';
static const errorIntenalServer = 'errorIntenalServer';
static const errorSomethingWentWrong = 'errorSomethingWentWrong';
}

44
lib/main.dart Normal file
View File

@ -0,0 +1,44 @@
import 'package:cryptocurrency_app/constants/app_theme.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart' as DotEnv;
import 'provider/settings_provider.dart';
import 'ui/home.dart';
import 'package:cryptocurrency_app/constants/utils.dart' as Utils;
void main() async {
await DotEnv.load(fileName: ".env");
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(EasyLocalization(
supportedLocales: [Locale('en'), Locale('es')],
path: 'assets/translations',
fallbackLocale: Locale('en'),
child: ProviderScope(child: MyApp())));
}
class MyApp extends HookWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final settings = useProvider(cryptoSettings);
final themeMode = settings.maybeWhen(
data: (data) => Utils.getThemeMode(data.themeMode),
orElse: () => ThemeMode.system);
return MaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: Home(),
themeMode: themeMode,
theme: AppTheme.light,
darkTheme: AppTheme.dark);
}
}

View File

@ -0,0 +1,15 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'allowance.freezed.dart';
part 'allowance.g.dart';
@freezed
abstract class Allowance with _$Allowance {
const factory Allowance({
required double cost,
required double remaining,
}) = _Allowance;
factory Allowance.fromJson(Map<String, dynamic> json) =>
_$AllowanceFromJson(json);
}

View File

@ -0,0 +1,179 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'allowance.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
Allowance _$AllowanceFromJson(Map<String, dynamic> json) {
return _Allowance.fromJson(json);
}
/// @nodoc
class _$AllowanceTearOff {
const _$AllowanceTearOff();
_Allowance call({required double cost, required double remaining}) {
return _Allowance(
cost: cost,
remaining: remaining,
);
}
Allowance fromJson(Map<String, Object> json) {
return Allowance.fromJson(json);
}
}
/// @nodoc
const $Allowance = _$AllowanceTearOff();
/// @nodoc
mixin _$Allowance {
double get cost => throw _privateConstructorUsedError;
double get remaining => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$AllowanceCopyWith<Allowance> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $AllowanceCopyWith<$Res> {
factory $AllowanceCopyWith(Allowance value, $Res Function(Allowance) then) =
_$AllowanceCopyWithImpl<$Res>;
$Res call({double cost, double remaining});
}
/// @nodoc
class _$AllowanceCopyWithImpl<$Res> implements $AllowanceCopyWith<$Res> {
_$AllowanceCopyWithImpl(this._value, this._then);
final Allowance _value;
// ignore: unused_field
final $Res Function(Allowance) _then;
@override
$Res call({
Object? cost = freezed,
Object? remaining = freezed,
}) {
return _then(_value.copyWith(
cost: cost == freezed
? _value.cost
: cost // ignore: cast_nullable_to_non_nullable
as double,
remaining: remaining == freezed
? _value.remaining
: remaining // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
/// @nodoc
abstract class _$AllowanceCopyWith<$Res> implements $AllowanceCopyWith<$Res> {
factory _$AllowanceCopyWith(
_Allowance value, $Res Function(_Allowance) then) =
__$AllowanceCopyWithImpl<$Res>;
@override
$Res call({double cost, double remaining});
}
/// @nodoc
class __$AllowanceCopyWithImpl<$Res> extends _$AllowanceCopyWithImpl<$Res>
implements _$AllowanceCopyWith<$Res> {
__$AllowanceCopyWithImpl(_Allowance _value, $Res Function(_Allowance) _then)
: super(_value, (v) => _then(v as _Allowance));
@override
_Allowance get _value => super._value as _Allowance;
@override
$Res call({
Object? cost = freezed,
Object? remaining = freezed,
}) {
return _then(_Allowance(
cost: cost == freezed
? _value.cost
: cost // ignore: cast_nullable_to_non_nullable
as double,
remaining: remaining == freezed
? _value.remaining
: remaining // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
/// @nodoc
@JsonSerializable()
class _$_Allowance implements _Allowance {
const _$_Allowance({required this.cost, required this.remaining});
factory _$_Allowance.fromJson(Map<String, dynamic> json) =>
_$_$_AllowanceFromJson(json);
@override
final double cost;
@override
final double remaining;
@override
String toString() {
return 'Allowance(cost: $cost, remaining: $remaining)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Allowance &&
(identical(other.cost, cost) ||
const DeepCollectionEquality().equals(other.cost, cost)) &&
(identical(other.remaining, remaining) ||
const DeepCollectionEquality()
.equals(other.remaining, remaining)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(cost) ^
const DeepCollectionEquality().hash(remaining);
@JsonKey(ignore: true)
@override
_$AllowanceCopyWith<_Allowance> get copyWith =>
__$AllowanceCopyWithImpl<_Allowance>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$_$_AllowanceToJson(this);
}
}
abstract class _Allowance implements Allowance {
const factory _Allowance({required double cost, required double remaining}) =
_$_Allowance;
factory _Allowance.fromJson(Map<String, dynamic> json) =
_$_Allowance.fromJson;
@override
double get cost => throw _privateConstructorUsedError;
@override
double get remaining => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$AllowanceCopyWith<_Allowance> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,20 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'allowance.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_Allowance _$_$_AllowanceFromJson(Map<String, dynamic> json) {
return _$_Allowance(
cost: (json['cost'] as num).toDouble(),
remaining: (json['remaining'] as num).toDouble(),
);
}
Map<String, dynamic> _$_$_AllowanceToJson(_$_Allowance instance) =>
<String, dynamic>{
'cost': instance.cost,
'remaining': instance.remaining,
};

View File

@ -0,0 +1,17 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'exchange.freezed.dart';
part 'exchange.g.dart';
@freezed
abstract class Exchange with _$Exchange {
const factory Exchange(
{required int id,
required String symbol,
required String name,
required String route,
required bool active}) = _Exchange;
factory Exchange.fromJson(Map<String, dynamic> json) =>
_$ExchangeFromJson(json);
}

View File

@ -0,0 +1,247 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'exchange.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
Exchange _$ExchangeFromJson(Map<String, dynamic> json) {
return _Exchange.fromJson(json);
}
/// @nodoc
class _$ExchangeTearOff {
const _$ExchangeTearOff();
_Exchange call(
{required int id,
required String symbol,
required String name,
required String route,
required bool active}) {
return _Exchange(
id: id,
symbol: symbol,
name: name,
route: route,
active: active,
);
}
Exchange fromJson(Map<String, Object> json) {
return Exchange.fromJson(json);
}
}
/// @nodoc
const $Exchange = _$ExchangeTearOff();
/// @nodoc
mixin _$Exchange {
int get id => throw _privateConstructorUsedError;
String get symbol => throw _privateConstructorUsedError;
String get name => throw _privateConstructorUsedError;
String get route => throw _privateConstructorUsedError;
bool get active => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ExchangeCopyWith<Exchange> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ExchangeCopyWith<$Res> {
factory $ExchangeCopyWith(Exchange value, $Res Function(Exchange) then) =
_$ExchangeCopyWithImpl<$Res>;
$Res call({int id, String symbol, String name, String route, bool active});
}
/// @nodoc
class _$ExchangeCopyWithImpl<$Res> implements $ExchangeCopyWith<$Res> {
_$ExchangeCopyWithImpl(this._value, this._then);
final Exchange _value;
// ignore: unused_field
final $Res Function(Exchange) _then;
@override
$Res call({
Object? id = freezed,
Object? symbol = freezed,
Object? name = freezed,
Object? route = freezed,
Object? active = freezed,
}) {
return _then(_value.copyWith(
id: id == freezed
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
symbol: symbol == freezed
? _value.symbol
: symbol // ignore: cast_nullable_to_non_nullable
as String,
name: name == freezed
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
route: route == freezed
? _value.route
: route // ignore: cast_nullable_to_non_nullable
as String,
active: active == freezed
? _value.active
: active // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
abstract class _$ExchangeCopyWith<$Res> implements $ExchangeCopyWith<$Res> {
factory _$ExchangeCopyWith(_Exchange value, $Res Function(_Exchange) then) =
__$ExchangeCopyWithImpl<$Res>;
@override
$Res call({int id, String symbol, String name, String route, bool active});
}
/// @nodoc
class __$ExchangeCopyWithImpl<$Res> extends _$ExchangeCopyWithImpl<$Res>
implements _$ExchangeCopyWith<$Res> {
__$ExchangeCopyWithImpl(_Exchange _value, $Res Function(_Exchange) _then)
: super(_value, (v) => _then(v as _Exchange));
@override
_Exchange get _value => super._value as _Exchange;
@override
$Res call({
Object? id = freezed,
Object? symbol = freezed,
Object? name = freezed,
Object? route = freezed,
Object? active = freezed,
}) {
return _then(_Exchange(
id: id == freezed
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int,
symbol: symbol == freezed
? _value.symbol
: symbol // ignore: cast_nullable_to_non_nullable
as String,
name: name == freezed
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
route: route == freezed
? _value.route
: route // ignore: cast_nullable_to_non_nullable
as String,
active: active == freezed
? _value.active
: active // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
@JsonSerializable()
class _$_Exchange implements _Exchange {
const _$_Exchange(
{required this.id,
required this.symbol,
required this.name,
required this.route,
required this.active});
factory _$_Exchange.fromJson(Map<String, dynamic> json) =>
_$_$_ExchangeFromJson(json);
@override
final int id;
@override
final String symbol;
@override
final String name;
@override
final String route;
@override
final bool active;
@override
String toString() {
return 'Exchange(id: $id, symbol: $symbol, name: $name, route: $route, active: $active)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Exchange &&
(identical(other.id, id) ||
const DeepCollectionEquality().equals(other.id, id)) &&
(identical(other.symbol, symbol) ||
const DeepCollectionEquality().equals(other.symbol, symbol)) &&
(identical(other.name, name) ||
const DeepCollectionEquality().equals(other.name, name)) &&
(identical(other.route, route) ||
const DeepCollectionEquality().equals(other.route, route)) &&
(identical(other.active, active) ||
const DeepCollectionEquality().equals(other.active, active)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(id) ^
const DeepCollectionEquality().hash(symbol) ^
const DeepCollectionEquality().hash(name) ^
const DeepCollectionEquality().hash(route) ^
const DeepCollectionEquality().hash(active);
@JsonKey(ignore: true)
@override
_$ExchangeCopyWith<_Exchange> get copyWith =>
__$ExchangeCopyWithImpl<_Exchange>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$_$_ExchangeToJson(this);
}
}
abstract class _Exchange implements Exchange {
const factory _Exchange(
{required int id,
required String symbol,
required String name,
required String route,
required bool active}) = _$_Exchange;
factory _Exchange.fromJson(Map<String, dynamic> json) = _$_Exchange.fromJson;
@override
int get id => throw _privateConstructorUsedError;
@override
String get symbol => throw _privateConstructorUsedError;
@override
String get name => throw _privateConstructorUsedError;
@override
String get route => throw _privateConstructorUsedError;
@override
bool get active => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$ExchangeCopyWith<_Exchange> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,26 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'exchange.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_Exchange _$_$_ExchangeFromJson(Map<String, dynamic> json) {
return _$_Exchange(
id: json['id'] as int,
symbol: json['symbol'] as String,
name: json['name'] as String,
route: json['route'] as String,
active: json['active'] as bool,
);
}
Map<String, dynamic> _$_$_ExchangeToJson(_$_Exchange instance) =>
<String, dynamic>{
'id': instance.id,
'symbol': instance.symbol,
'name': instance.name,
'route': instance.route,
'active': instance.active,
};

View File

@ -0,0 +1,14 @@
import 'package:cryptocurrency_app/models/exchanges/exchange/exchange.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'exchanges_response.freezed.dart';
part 'exchanges_response.g.dart';
@freezed
abstract class ExchangesResponse with _$ExchangesResponse {
const factory ExchangesResponse({required List<Exchange> result}) =
_ExchangesResponse;
factory ExchangesResponse.fromJson(Map<String, dynamic> json) =>
_$ExchangesResponseFromJson(json);
}

View File

@ -0,0 +1,163 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'exchanges_response.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
ExchangesResponse _$ExchangesResponseFromJson(Map<String, dynamic> json) {
return _ExchangesResponse.fromJson(json);
}
/// @nodoc
class _$ExchangesResponseTearOff {
const _$ExchangesResponseTearOff();
_ExchangesResponse call({required List<Exchange> result}) {
return _ExchangesResponse(
result: result,
);
}
ExchangesResponse fromJson(Map<String, Object> json) {
return ExchangesResponse.fromJson(json);
}
}
/// @nodoc
const $ExchangesResponse = _$ExchangesResponseTearOff();
/// @nodoc
mixin _$ExchangesResponse {
List<Exchange> get result => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$ExchangesResponseCopyWith<ExchangesResponse> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $ExchangesResponseCopyWith<$Res> {
factory $ExchangesResponseCopyWith(
ExchangesResponse value, $Res Function(ExchangesResponse) then) =
_$ExchangesResponseCopyWithImpl<$Res>;
$Res call({List<Exchange> result});
}
/// @nodoc
class _$ExchangesResponseCopyWithImpl<$Res>
implements $ExchangesResponseCopyWith<$Res> {
_$ExchangesResponseCopyWithImpl(this._value, this._then);
final ExchangesResponse _value;
// ignore: unused_field
final $Res Function(ExchangesResponse) _then;
@override
$Res call({
Object? result = freezed,
}) {
return _then(_value.copyWith(
result: result == freezed
? _value.result
: result // ignore: cast_nullable_to_non_nullable
as List<Exchange>,
));
}
}
/// @nodoc
abstract class _$ExchangesResponseCopyWith<$Res>
implements $ExchangesResponseCopyWith<$Res> {
factory _$ExchangesResponseCopyWith(
_ExchangesResponse value, $Res Function(_ExchangesResponse) then) =
__$ExchangesResponseCopyWithImpl<$Res>;
@override
$Res call({List<Exchange> result});
}
/// @nodoc
class __$ExchangesResponseCopyWithImpl<$Res>
extends _$ExchangesResponseCopyWithImpl<$Res>
implements _$ExchangesResponseCopyWith<$Res> {
__$ExchangesResponseCopyWithImpl(
_ExchangesResponse _value, $Res Function(_ExchangesResponse) _then)
: super(_value, (v) => _then(v as _ExchangesResponse));
@override
_ExchangesResponse get _value => super._value as _ExchangesResponse;
@override
$Res call({
Object? result = freezed,
}) {
return _then(_ExchangesResponse(
result: result == freezed
? _value.result
: result // ignore: cast_nullable_to_non_nullable
as List<Exchange>,
));
}
}
/// @nodoc
@JsonSerializable()
class _$_ExchangesResponse implements _ExchangesResponse {
const _$_ExchangesResponse({required this.result});
factory _$_ExchangesResponse.fromJson(Map<String, dynamic> json) =>
_$_$_ExchangesResponseFromJson(json);
@override
final List<Exchange> result;
@override
String toString() {
return 'ExchangesResponse(result: $result)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _ExchangesResponse &&
(identical(other.result, result) ||
const DeepCollectionEquality().equals(other.result, result)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(result);
@JsonKey(ignore: true)
@override
_$ExchangesResponseCopyWith<_ExchangesResponse> get copyWith =>
__$ExchangesResponseCopyWithImpl<_ExchangesResponse>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$_$_ExchangesResponseToJson(this);
}
}
abstract class _ExchangesResponse implements ExchangesResponse {
const factory _ExchangesResponse({required List<Exchange> result}) =
_$_ExchangesResponse;
factory _ExchangesResponse.fromJson(Map<String, dynamic> json) =
_$_ExchangesResponse.fromJson;
@override
List<Exchange> get result => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$ExchangesResponseCopyWith<_ExchangesResponse> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'exchanges_response.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$_ExchangesResponse _$_$_ExchangesResponseFromJson(Map<String, dynamic> json) {
return _$_ExchangesResponse(
result: (json['result'] as List<dynamic>)
.map((e) => Exchange.fromJson(e as Map<String, dynamic>))
.toList(),
);
}
Map<String, dynamic> _$_$_ExchangesResponseToJson(
_$_ExchangesResponse instance) =>
<String, dynamic>{
'result': instance.result,
};

View File

@ -0,0 +1,18 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../pair_graph/pair_graph.dart';
part 'graph.freezed.dart';
@freezed
abstract class Graph with _$Graph {
const factory Graph({required List<PairGraph> pairs}) = _Graph;
factory Graph.fromJson(dynamic json) {
List<PairGraph> pairs = <PairGraph>[];
json.forEach((k, v) {
pairs.add(PairGraph.fromJson(v, k));
});
return Graph(pairs: pairs);
}
}

View File

@ -0,0 +1,134 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'graph.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$GraphTearOff {
const _$GraphTearOff();
_Graph call({required List<PairGraph> pairs}) {
return _Graph(
pairs: pairs,
);
}
}
/// @nodoc
const $Graph = _$GraphTearOff();
/// @nodoc
mixin _$Graph {
List<PairGraph> get pairs => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$GraphCopyWith<Graph> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $GraphCopyWith<$Res> {
factory $GraphCopyWith(Graph value, $Res Function(Graph) then) =
_$GraphCopyWithImpl<$Res>;
$Res call({List<PairGraph> pairs});
}
/// @nodoc
class _$GraphCopyWithImpl<$Res> implements $GraphCopyWith<$Res> {
_$GraphCopyWithImpl(this._value, this._then);
final Graph _value;
// ignore: unused_field
final $Res Function(Graph) _then;
@override
$Res call({
Object? pairs = freezed,
}) {
return _then(_value.copyWith(
pairs: pairs == freezed
? _value.pairs
: pairs // ignore: cast_nullable_to_non_nullable
as List<PairGraph>,
));
}
}
/// @nodoc
abstract class _$GraphCopyWith<$Res> implements $GraphCopyWith<$Res> {
factory _$GraphCopyWith(_Graph value, $Res Function(_Graph) then) =
__$GraphCopyWithImpl<$Res>;
@override
$Res call({List<PairGraph> pairs});
}
/// @nodoc
class __$GraphCopyWithImpl<$Res> extends _$GraphCopyWithImpl<$Res>
implements _$GraphCopyWith<$Res> {
__$GraphCopyWithImpl(_Graph _value, $Res Function(_Graph) _then)
: super(_value, (v) => _then(v as _Graph));
@override
_Graph get _value => super._value as _Graph;
@override
$Res call({
Object? pairs = freezed,
}) {
return _then(_Graph(
pairs: pairs == freezed
? _value.pairs
: pairs // ignore: cast_nullable_to_non_nullable
as List<PairGraph>,
));
}
}
/// @nodoc
class _$_Graph implements _Graph {
const _$_Graph({required this.pairs});
@override
final List<PairGraph> pairs;
@override
String toString() {
return 'Graph(pairs: $pairs)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _Graph &&
(identical(other.pairs, pairs) ||
const DeepCollectionEquality().equals(other.pairs, pairs)));
}
@override
int get hashCode =>
runtimeType.hashCode ^ const DeepCollectionEquality().hash(pairs);
@JsonKey(ignore: true)
@override
_$GraphCopyWith<_Graph> get copyWith =>
__$GraphCopyWithImpl<_Graph>(this, _$identity);
}
abstract class _Graph implements Graph {
const factory _Graph({required List<PairGraph> pairs}) = _$_Graph;
@override
List<PairGraph> get pairs => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$GraphCopyWith<_Graph> get copyWith => throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,17 @@
import 'package:cryptocurrency_app/models/allowance/allowance.dart';
import 'package:cryptocurrency_app/models/graph/graph/graph.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'graph_response.freezed.dart';
@freezed
abstract class GraphResponse with _$GraphResponse {
const factory GraphResponse(
{required Graph result, required Allowance allowance}) = _GraphResponse;
factory GraphResponse.fromJson(Map<String, dynamic> json) {
final result = Graph.fromJson(json['result']);
final allowance = Allowance.fromJson(json['allowance']);
return GraphResponse(result: result, allowance: allowance);
}
}

View File

@ -0,0 +1,186 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'graph_response.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$GraphResponseTearOff {
const _$GraphResponseTearOff();
_GraphResponse call({required Graph result, required Allowance allowance}) {
return _GraphResponse(
result: result,
allowance: allowance,
);
}
}
/// @nodoc
const $GraphResponse = _$GraphResponseTearOff();
/// @nodoc
mixin _$GraphResponse {
Graph get result => throw _privateConstructorUsedError;
Allowance get allowance => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$GraphResponseCopyWith<GraphResponse> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $GraphResponseCopyWith<$Res> {
factory $GraphResponseCopyWith(
GraphResponse value, $Res Function(GraphResponse) then) =
_$GraphResponseCopyWithImpl<$Res>;
$Res call({Graph result, Allowance allowance});
$GraphCopyWith<$Res> get result;
$AllowanceCopyWith<$Res> get allowance;
}
/// @nodoc
class _$GraphResponseCopyWithImpl<$Res>
implements $GraphResponseCopyWith<$Res> {
_$GraphResponseCopyWithImpl(this._value, this._then);
final GraphResponse _value;
// ignore: unused_field
final $Res Function(GraphResponse) _then;
@override
$Res call({
Object? result = freezed,
Object? allowance = freezed,
}) {
return _then(_value.copyWith(
result: result == freezed
? _value.result
: result // ignore: cast_nullable_to_non_nullable
as Graph,
allowance: allowance == freezed
? _value.allowance
: allowance // ignore: cast_nullable_to_non_nullable
as Allowance,
));
}
@override
$GraphCopyWith<$Res> get result {
return $GraphCopyWith<$Res>(_value.result, (value) {
return _then(_value.copyWith(result: value));
});
}
@override
$AllowanceCopyWith<$Res> get allowance {
return $AllowanceCopyWith<$Res>(_value.allowance, (value) {
return _then(_value.copyWith(allowance: value));
});
}
}
/// @nodoc
abstract class _$GraphResponseCopyWith<$Res>
implements $GraphResponseCopyWith<$Res> {
factory _$GraphResponseCopyWith(
_GraphResponse value, $Res Function(_GraphResponse) then) =
__$GraphResponseCopyWithImpl<$Res>;
@override
$Res call({Graph result, Allowance allowance});
@override
$GraphCopyWith<$Res> get result;
@override
$AllowanceCopyWith<$Res> get allowance;
}
/// @nodoc
class __$GraphResponseCopyWithImpl<$Res>
extends _$GraphResponseCopyWithImpl<$Res>
implements _$GraphResponseCopyWith<$Res> {
__$GraphResponseCopyWithImpl(
_GraphResponse _value, $Res Function(_GraphResponse) _then)
: super(_value, (v) => _then(v as _GraphResponse));
@override
_GraphResponse get _value => super._value as _GraphResponse;
@override
$Res call({
Object? result = freezed,
Object? allowance = freezed,
}) {
return _then(_GraphResponse(
result: result == freezed
? _value.result
: result // ignore: cast_nullable_to_non_nullable
as Graph,
allowance: allowance == freezed
? _value.allowance
: allowance // ignore: cast_nullable_to_non_nullable
as Allowance,
));
}
}
/// @nodoc
class _$_GraphResponse implements _GraphResponse {
const _$_GraphResponse({required this.result, required this.allowance});
@override
final Graph result;
@override
final Allowance allowance;
@override
String toString() {
return 'GraphResponse(result: $result, allowance: $allowance)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _GraphResponse &&
(identical(other.result, result) ||
const DeepCollectionEquality().equals(other.result, result)) &&
(identical(other.allowance, allowance) ||
const DeepCollectionEquality()
.equals(other.allowance, allowance)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(result) ^
const DeepCollectionEquality().hash(allowance);
@JsonKey(ignore: true)
@override
_$GraphResponseCopyWith<_GraphResponse> get copyWith =>
__$GraphResponseCopyWithImpl<_GraphResponse>(this, _$identity);
}
abstract class _GraphResponse implements GraphResponse {
const factory _GraphResponse(
{required Graph result, required Allowance allowance}) = _$_GraphResponse;
@override
Graph get result => throw _privateConstructorUsedError;
@override
Allowance get allowance => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$GraphResponseCopyWith<_GraphResponse> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@ -0,0 +1,19 @@
import 'package:freezed_annotation/freezed_annotation.dart';
import '../points/points.dart';
part 'pair_graph.freezed.dart';
@freezed
abstract class PairGraph with _$PairGraph {
const factory PairGraph(
{required String period, required List<Points> points}) = _PairGraph;
factory PairGraph.fromJson(dynamic json, String period) {
List<Points> points = <Points>[];
json.forEach((v) {
points.add(Points.fromJson(v));
});
return PairGraph(period: period, points: points);
}
}

View File

@ -0,0 +1,158 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides
part of 'pair_graph.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
/// @nodoc
class _$PairGraphTearOff {
const _$PairGraphTearOff();
_PairGraph call({required String period, required List<Points> points}) {
return _PairGraph(
period: period,
points: points,
);
}
}
/// @nodoc
const $PairGraph = _$PairGraphTearOff();
/// @nodoc
mixin _$PairGraph {
String get period => throw _privateConstructorUsedError;
List<Points> get points => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$PairGraphCopyWith<PairGraph> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $PairGraphCopyWith<$Res> {
factory $PairGraphCopyWith(PairGraph value, $Res Function(PairGraph) then) =
_$PairGraphCopyWithImpl<$Res>;
$Res call({String period, List<Points> points});
}
/// @nodoc
class _$PairGraphCopyWithImpl<$Res> implements $PairGraphCopyWith<$Res> {
_$PairGraphCopyWithImpl(this._value, this._then);
final PairGraph _value;
// ignore: unused_field
final $Res Function(PairGraph) _then;
@override
$Res call({
Object? period = freezed,
Object? points = freezed,
}) {
return _then(_value.copyWith(
period: period == freezed
? _value.period
: period // ignore: cast_nullable_to_non_nullable
as String,
points: points == freezed
? _value.points
: points // ignore: cast_nullable_to_non_nullable
as List<Points>,
));
}
}
/// @nodoc
abstract class _$PairGraphCopyWith<$Res> implements $PairGraphCopyWith<$Res> {
factory _$PairGraphCopyWith(
_PairGraph value, $Res Function(_PairGraph) then) =
__$PairGraphCopyWithImpl<$Res>;
@override
$Res call({String period, List<Points> points});
}
/// @nodoc
class __$PairGraphCopyWithImpl<$Res> extends _$PairGraphCopyWithImpl<$Res>
implements _$PairGraphCopyWith<$Res> {
__$PairGraphCopyWithImpl(_PairGraph _value, $Res Function(_PairGraph) _then)
: super(_value, (v) => _then(v as _PairGraph));
@override
_PairGraph get _value => super._value as _PairGraph;
@override
$Res call({
Object? period = freezed,
Object? points = freezed,
}) {
return _then(_PairGraph(
period: period == freezed
? _value.period
: period // ignore: cast_nullable_to_non_nullable
as String,
points: points == freezed
? _value.points
: points // ignore: cast_nullable_to_non_nullable
as List<Points>,
));
}
}
/// @nodoc
class _$_PairGraph implements _PairGraph {
const _$_PairGraph({required this.period, required this.points});
@override
final String period;
@override
final List<Points> points;
@override
String toString() {
return 'PairGraph(period: $period, points: $points)';
}
@override
bool operator ==(dynamic other) {
return identical(this, other) ||
(other is _PairGraph &&
(identical(other.period, period) ||
const DeepCollectionEquality().equals(other.period, period)) &&
(identical(other.points, points) ||
const DeepCollectionEquality().equals(other.points, points)));
}
@override
int get hashCode =>
runtimeType.hashCode ^
const DeepCollectionEquality().hash(period) ^
const DeepCollectionEquality().hash(points);
@JsonKey(ignore: true)
@override
_$PairGraphCopyWith<_PairGraph> get copyWith =>
__$PairGraphCopyWithImpl<_PairGraph>(this, _$identity);
}
abstract class _PairGraph implements PairGraph {
const factory _PairGraph(
{required String period, required List<Points> points}) = _$_PairGraph;
@override
String get period => throw _privateConstructorUsedError;
@override
List<Points> get points => throw _privateConstructorUsedError;
@override
@JsonKey(ignore: true)
_$PairGraphCopyWith<_PairGraph> get copyWith =>
throw _privateConstructorUsedError;
}

Some files were not shown because too many files have changed in this diff Show More