Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f66f706b65 | ||
|
|
6d05385e66 | ||
|
|
4ee16d3855 | ||
|
|
84cae9e789 | ||
|
|
38850b281f | ||
|
|
e5515d5871 | ||
|
|
cb5e5e70bf | ||
|
|
671dd3a5d0 | ||
|
|
66d59ee59e | ||
|
|
57fb56303a | ||
|
|
8f0a5d3fb5 | ||
|
|
5a8b020256 | ||
|
|
e273785268 | ||
|
|
5ba60747a8 | ||
|
|
c35d0eedbe | ||
|
|
bc751246d8 | ||
|
|
f5e3075205 | ||
|
|
5954510b93 | ||
|
|
2560c1890b | ||
|
|
7887704a5c | ||
|
|
4c12244d3c | ||
|
|
f4f775b9ed | ||
|
|
44d48d41d4 | ||
|
|
a09fda0585 |
@@ -0,0 +1,47 @@
|
|||||||
|
name: Build Android APK (split per ABI)
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-apk:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: "temurin"
|
||||||
|
java-version: "17"
|
||||||
|
cache: "gradle"
|
||||||
|
|
||||||
|
- name: Setup Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: "stable"
|
||||||
|
# Samain dengan versi di ios.yml biar konsisten.
|
||||||
|
flutter-version: "3.47.0"
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
# ── Build ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Build APK (split per ABI)
|
||||||
|
run: flutter build apk --release --split-per-abi
|
||||||
|
|
||||||
|
# ── Artifact ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Upload APKs as Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: android-apk
|
||||||
|
path: build/app/outputs/flutter-apk/app-*-release.apk
|
||||||
|
retention-days: 7
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
name: Build & Deploy iOS to TestFlight
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-deploy:
|
||||||
|
runs-on: macos-26
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Flutter
|
||||||
|
uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: "stable"
|
||||||
|
# Dipin biar CI nggak ikut naik versi diam-diam.
|
||||||
|
# Flutter 3.47 mensyaratkan iOS deployment target minimal 15.0.
|
||||||
|
flutter-version: "3.47.0"
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: Install Dependencies
|
||||||
|
run: flutter pub get
|
||||||
|
|
||||||
|
# ── Code Signing Setup ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Install Apple Certificate
|
||||||
|
env:
|
||||||
|
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
|
||||||
|
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
|
||||||
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
|
||||||
|
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
|
||||||
|
|
||||||
|
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||||
|
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
||||||
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||||
|
|
||||||
|
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A \
|
||||||
|
-t cert -f pkcs12 -k $KEYCHAIN_PATH
|
||||||
|
security set-key-partition-list -S apple-tool:,apple: \
|
||||||
|
-s -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
||||||
|
security list-keychain -d user -s $KEYCHAIN_PATH
|
||||||
|
|
||||||
|
- name: Install Provisioning Profile
|
||||||
|
env:
|
||||||
|
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
|
||||||
|
run: |
|
||||||
|
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
|
||||||
|
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
|
||||||
|
|
||||||
|
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
|
||||||
|
|
||||||
|
# Xcode requires the filename to be the profile's UUID
|
||||||
|
UUID=$(security cms -D -i $PP_PATH | plutil -extract UUID raw -)
|
||||||
|
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles/$UUID.mobileprovision
|
||||||
|
echo "Installed provisioning profile UUID: $UUID"
|
||||||
|
|
||||||
|
# ── Disable SPM ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Disable Swift Package Manager
|
||||||
|
run: flutter config --no-enable-swift-package-manager
|
||||||
|
|
||||||
|
# ── CocoaPods ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Install CocoaPods Dependencies
|
||||||
|
run: |
|
||||||
|
cd ios
|
||||||
|
rm -rf Pods Podfile.lock
|
||||||
|
pod install --repo-update
|
||||||
|
|
||||||
|
# ── Build & Archive ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Build iOS (no codesign)
|
||||||
|
run: flutter build ios --release --no-codesign
|
||||||
|
|
||||||
|
- name: Re-run pod install to apply Podfile signing settings
|
||||||
|
run: |
|
||||||
|
cd ios
|
||||||
|
pod install
|
||||||
|
|
||||||
|
- name: Archive with Xcode
|
||||||
|
env:
|
||||||
|
TEAM_ID: ${{ secrets.TEAM_ID }}
|
||||||
|
run: |
|
||||||
|
cat > $RUNNER_TEMP/signing.xcconfig << 'XCCONFIG'
|
||||||
|
CODE_SIGN_STYLE = Manual
|
||||||
|
CODE_SIGN_IDENTITY = iPhone Distribution
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = Enaklo Customer
|
||||||
|
CODE_SIGNING_REQUIRED = YES
|
||||||
|
XCCONFIG
|
||||||
|
|
||||||
|
xcodebuild archive \
|
||||||
|
-workspace ios/Runner.xcworkspace \
|
||||||
|
-scheme Runner \
|
||||||
|
-configuration Release \
|
||||||
|
-archivePath $RUNNER_TEMP/Runner.xcarchive \
|
||||||
|
-destination "generic/platform=iOS" \
|
||||||
|
-xcconfig $RUNNER_TEMP/signing.xcconfig \
|
||||||
|
DEVELOPMENT_TEAM="$TEAM_ID"
|
||||||
|
|
||||||
|
- name: Export IPA
|
||||||
|
run: |
|
||||||
|
xcodebuild -exportArchive \
|
||||||
|
-archivePath $RUNNER_TEMP/Runner.xcarchive \
|
||||||
|
-exportPath $RUNNER_TEMP/export \
|
||||||
|
-exportOptionsPlist ios/ExportOptions.plist
|
||||||
|
|
||||||
|
mkdir -p build/ios/ipa
|
||||||
|
cp $RUNNER_TEMP/export/*.ipa build/ios/ipa/
|
||||||
|
|
||||||
|
# ── Upload to TestFlight ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Upload to TestFlight via Transporter
|
||||||
|
env:
|
||||||
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
|
APP_SPECIFIC_PASSWORD: ${{ secrets.APP_SPECIFIC_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
IPA_PATH=$(find build/ios/ipa -name "*.ipa" | head -1)
|
||||||
|
echo "Uploading: $IPA_PATH"
|
||||||
|
xcrun altool --upload-app \
|
||||||
|
--type ios \
|
||||||
|
--file "$IPA_PATH" \
|
||||||
|
--username "$APPLE_ID" \
|
||||||
|
--password "$APP_SPECIFIC_PASSWORD" \
|
||||||
|
--verbose
|
||||||
|
|
||||||
|
# ── Cleanup ─────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Clean Up Keychain and Provisioning Profile
|
||||||
|
if: ${{ always() }}
|
||||||
|
run: |
|
||||||
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db || true
|
||||||
|
rm -rf ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision || true
|
||||||
|
|
||||||
|
# ── Artifact ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
- name: Upload IPA as Artifact
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ios-ipa
|
||||||
|
path: build/ios/ipa/*.ipa
|
||||||
|
retention-days: 7
|
||||||
@@ -43,3 +43,10 @@ app.*.map.json
|
|||||||
/android/app/debug
|
/android/app/debug
|
||||||
/android/app/profile
|
/android/app/profile
|
||||||
/android/app/release
|
/android/app/release
|
||||||
|
|
||||||
|
# Signing credentials — never commit these
|
||||||
|
*.p12
|
||||||
|
*.pfx
|
||||||
|
*.cer
|
||||||
|
*.mobileprovision
|
||||||
|
*.certSigningRequest
|
||||||
|
|||||||
@@ -18,3 +18,10 @@ analyzer:
|
|||||||
- test/generated/**
|
- test/generated/**
|
||||||
- "**/**.g.dart"
|
- "**/**.g.dart"
|
||||||
- "**/**.freezed.dart"
|
- "**/**.freezed.dart"
|
||||||
|
- build/**
|
||||||
|
- android/**
|
||||||
|
- ios/**
|
||||||
|
- web/**
|
||||||
|
- windows/**
|
||||||
|
- macos/**
|
||||||
|
- linux/**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.appskel.enaklo"
|
namespace = "com.apskel.enaklocustomer"
|
||||||
compileSdk = flutter.compileSdkVersion
|
compileSdk = flutter.compileSdkVersion
|
||||||
ndkVersion = "27.0.12077973"
|
ndkVersion = "27.0.12077973"
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||||
applicationId = "com.appskel.enaklo"
|
applicationId = "com.apskel.enaklocustomer"
|
||||||
// You can update the following values to match your application needs.
|
// You can update the following values to match your application needs.
|
||||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||||
minSdk = flutter.minSdkVersion
|
minSdk = flutter.minSdkVersion
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.apskel.enaklocustomer
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import io.flutter.plugins.webviewflutter.WebViewFlutterAndroidExternalApi
|
||||||
|
|
||||||
|
class MainActivity : FlutterActivity() {
|
||||||
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
|
super.configureFlutterEngine(flutterEngine)
|
||||||
|
|
||||||
|
// Pengaturan WebView yang tidak disediakan plugin webview_flutter.
|
||||||
|
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, WEBVIEW_CHANNEL)
|
||||||
|
.setMethodCallHandler { call, result ->
|
||||||
|
when (call.method) {
|
||||||
|
"enableOffscreenPreRaster" -> {
|
||||||
|
val id = call.argument<Number>("webViewId")?.toLong()
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
val webView = id?.let {
|
||||||
|
WebViewFlutterAndroidExternalApi.getWebView(flutterEngine, it)
|
||||||
|
}
|
||||||
|
if (webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
webView.settings.offscreenPreRaster = true
|
||||||
|
}
|
||||||
|
result.success(webView != null)
|
||||||
|
}
|
||||||
|
else -> result.notImplemented()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val WEBVIEW_CHANNEL = "com.apskel.enaklocustomer/webview"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.appskel.enaklo
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
|
|
||||||
class MainActivity : FlutterActivity()
|
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
# This builtInKotlin flag was added automatically by Flutter migrator
|
||||||
|
android.builtInKotlin=false
|
||||||
|
# This newDsl flag was added automatically by Flutter migrator
|
||||||
|
android.newDsl=false
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-all.zip
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ pluginManagement {
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
||||||
id("com.android.application") version "8.7.3" apply false
|
id("com.android.application") version "8.11.1" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
include(":app")
|
include(":app")
|
||||||
|
|||||||
|
After Width: | Height: | Size: 332 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 174 KiB |
|
After Width: | Height: | Size: 159 KiB |
|
After Width: | Height: | Size: 165 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 790 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
After Width: | Height: | Size: 176 KiB |
|
After Width: | Height: | Size: 367 KiB |
@@ -0,0 +1,799 @@
|
|||||||
|
# Integrasi Mobile App Customer: EnakPoint, EnakCoin, EnakGame & Voucher
|
||||||
|
|
||||||
|
**Untuk:** tim aplikasi mobile customer · **Base URL:** `/api/v1` · **Per:** 8 Okt 2026
|
||||||
|
|
||||||
|
Kamu mengerjakan aplikasi mobile untuk **customer** (bukan kasir, bukan backoffice).
|
||||||
|
Tugasmu: membangun fitur loyalitas di aplikasi, yaitu saldo EnakPoint & EnakCoin,
|
||||||
|
PIN, tukar, transfer, voucher, dan pintu masuk ke game EnakGame. Semuanya memakai API
|
||||||
|
backend yang sudah jadi dan dijelaskan di dokumen ini. Jangan mengarang endpoint,
|
||||||
|
field, atau aturan yang tidak tertulis di sini; kalau ada yang kurang jelas, tanyakan
|
||||||
|
dulu.
|
||||||
|
|
||||||
|
Dokumen ini menggantikan `mobile-customer-enakpoint.md`, `integration-enakpoint.md`,
|
||||||
|
`api-enakpoint.md`, dan `enakgame-spin.md` untuk sisi aplikasi customer. Game-nya
|
||||||
|
sendiri (Phaser) dikerjakan tim EnakGame dengan
|
||||||
|
[`integration-enakgame.md`](./integration-enakgame.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Konteks bisnis
|
||||||
|
|
||||||
|
| | EnakPoint (`POINT`) | EnakCoin (`COIN`) |
|
||||||
|
|---|---|---|
|
||||||
|
| Didapat dari | Belanja (order lunas), tukar EnakCoin, koreksi admin | Belanja, **hadiah game**, koreksi admin |
|
||||||
|
| Dipakai untuk | **Ditukar ke voucher** (tidak bisa membayar order) | **Main game**, ditukar ke EnakPoint |
|
||||||
|
| Bisa dikirim ke customer lain | Ya | Ya |
|
||||||
|
| Bisa kedaluwarsa | Ya, bila owner mengaktifkan | Ya, bila owner mengaktifkan |
|
||||||
|
|
||||||
|
Tidak ada lagi "token". Semua yang dulu token sekarang EnakCoin.
|
||||||
|
|
||||||
|
### Aturan yang wajib dipatuhi di UI
|
||||||
|
|
||||||
|
1. **Semua jumlah bilangan bulat.** Tidak ada desimal pada EnakPoint atau EnakCoin.
|
||||||
|
2. **Saldo bukan uang.** Nilai rupiah EnakPoint selalu ditulis **"setara potongan
|
||||||
|
Rp …"**, tidak pernah "saldo Rp …" atau "uang". Tidak ada tarik tunai, dan EnakPoint
|
||||||
|
tidak bisa dipakai membayar. Jangan membangun layar bayar atau kode bayar.
|
||||||
|
3. **PIN 6 digit wajib** untuk: tukar EnakCoin, transfer, dan **tukar EnakPoint ke
|
||||||
|
voucher**. Main game, melihat saldo, dan riwayat tidak butuh PIN.
|
||||||
|
4. **PIN terpisah dari password login** dan selalu dikirim sebagai **string** (supaya
|
||||||
|
nol di depan tidak hilang). Jangan pernah menyimpan PIN di perangkat, log, atau
|
||||||
|
analytics.
|
||||||
|
5. **Satu akun customer = satu organisasi.** Saldo berlaku di semua outlet organisasi itu.
|
||||||
|
6. **Waktu memakai WIB.** Tanggal kedaluwarsa berarti saldo masih bisa dipakai sampai
|
||||||
|
23:59:59 WIB di tanggal itu.
|
||||||
|
7. **Hadiah game ditentukan server.** Aplikasi tidak menghitung atau mengirim hadiah.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Koneksi ke API
|
||||||
|
|
||||||
|
- Base URL: `/api/v1`
|
||||||
|
- Semua endpoint customer: header `Authorization: Bearer <token login customer>`
|
||||||
|
- Semua jumlah di request dan response berupa integer.
|
||||||
|
- Belum ada endpoint refresh token: bila token ditolak (§2.2, `entity` `auth_handler`),
|
||||||
|
customer login ulang.
|
||||||
|
|
||||||
|
### 2.1 Registrasi customer
|
||||||
|
|
||||||
|
`POST /api/v1/customer-auth/register/start` menerima `organization_id` (opsional):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "phone_number": "0812…", "name": "Budi", "birth_date": "2000-01-31", "organization_id": "648b96a0-1d1d-414e-baee-37e9d6317b4e" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Customer terdaftar di satu organisasi, dan saldonya berlaku di semua outlet organisasi itu.
|
||||||
|
- Bila `organization_id` tidak dikirim dan backend hanya punya satu organisasi, customer
|
||||||
|
otomatis masuk ke organisasi itu. Bila ada lebih dari satu, registrasi ditolak
|
||||||
|
("organization_id is required"), jadi sebaiknya app selalu mengirimnya dari config per
|
||||||
|
environment/brand.
|
||||||
|
- `organization_id` yang dikirim harus ada; bila tidak, registrasi ditolak sebelum OTP dikirim.
|
||||||
|
- Wallet customer baru belum punya baris sampai saldo pertama kali bergerak;
|
||||||
|
`GET /customer/wallet` tetap menjawab saldo 0.
|
||||||
|
|
||||||
|
### 2.2 Format response
|
||||||
|
|
||||||
|
Sukses:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": true, "data": { … }, "errors": null }
|
||||||
|
```
|
||||||
|
|
||||||
|
Semua contoh response di dokumen ini adalah isi `data`. Untuk daftar berhalaman, isi
|
||||||
|
itu sendiri berbentuk `{ "data": [ … ], "pagination": { … } }`, jadi array-nya ada di
|
||||||
|
`data.data` pada response mentah.
|
||||||
|
|
||||||
|
Gagal:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": false, "data": null, "errors": [{ "code": "304", "entity": "wallet_service", "cause": "wallet move refused: not enough EnakCoin" }] }
|
||||||
|
```
|
||||||
|
|
||||||
|
| `errors[0].code` | HTTP | Arti | Yang dilakukan app |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `303`, `310` | 400 | Request tidak lengkap / salah format | Bug di app; tampilkan pesan umum |
|
||||||
|
| `304` | 400 | Ditolak aturan bisnis, **atau token tidak berlaku** bila `entity` = `auth_handler` | Pesan yang ramah per fitur; `cause` berbahasa Inggris, jangan tampilkan mentah. Token: login ulang |
|
||||||
|
| `404` | 404 | Tidak ditemukan, juga untuk data milik customer lain | Tampilkan "tidak ditemukan" |
|
||||||
|
| `429` | 429 | Minta OTP terlalu cepat | Hitung mundur sebelum boleh minta lagi |
|
||||||
|
| `PIN_NOT_SET` | 403 | Belum punya PIN | Buka alur buat PIN (§6.2) |
|
||||||
|
| `PIN_INVALID` | 400 | PIN salah | §6.5 |
|
||||||
|
| `PIN_LOCKED` | 423 | PIN terkunci | §6.5 |
|
||||||
|
| `TRANSFER_BLOCKED` | 403 | Transfer ditahan setelah reset PIN | §6.5 |
|
||||||
|
| `900` | 500 | Error server | "Terjadi kesalahan, coba lagi" |
|
||||||
|
|
||||||
|
### 2.3 Idempotency-Key
|
||||||
|
|
||||||
|
Endpoint **tukar**, **transfer**, dan **tukar voucher** wajib header `Idempotency-Key`
|
||||||
|
(string unik, maks. 50 karakter, mis. UUID v4; `X-Idempotency-Key` juga diterima).
|
||||||
|
|
||||||
|
- Buat **satu key baru saat customer menekan tombol konfirmasi**.
|
||||||
|
- Bila request gagal karena jaringan/timeout, **kirim ulang dengan key yang sama**.
|
||||||
|
Server mengembalikan hasil pertama dengan `"replayed": true` dan tidak memotong saldo
|
||||||
|
dua kali.
|
||||||
|
- Jangan pakai ulang key untuk transaksi yang berbeda; server menolaknya (`304`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Layar yang perlu dibuat
|
||||||
|
|
||||||
|
| Layar | Endpoint utama | Butuh PIN |
|
||||||
|
|---|---|---|
|
||||||
|
| Beranda wallet | `GET /customer/wallet` | – |
|
||||||
|
| Riwayat mutasi | `GET /customer/wallet/transactions` | – |
|
||||||
|
| Saldo akan kedaluwarsa | `GET /customer/wallet/expiring` | – |
|
||||||
|
| Daftar outlet | `GET /customer/outlets` | – |
|
||||||
|
| Riwayat order + detail | `GET /customer/orders`, `GET /customer/orders/:id` | – |
|
||||||
|
| Tukar EnakCoin | `GET …/exchange/preview`, `POST /customer/wallet/exchange` | Ya |
|
||||||
|
| Transfer | `GET …/transfer/recipient`, `POST /customer/wallet/transfer` | Ya |
|
||||||
|
| PIN (buat, ganti, lupa) | `/customer/pin/*` | – |
|
||||||
|
| Daftar game + webview game | `GET /customer/enakgame/games` | – |
|
||||||
|
| Riwayat main | `GET /customer/enakgame/sessions` | – |
|
||||||
|
| Katalog voucher | `GET /customer/vouchers` | – |
|
||||||
|
| Tukar voucher | `POST /customer/vouchers/:id/redeem` | Ya |
|
||||||
|
| Voucher saya | `GET /customer/vouchers/redemptions` | – |
|
||||||
|
| (latar belakang) registrasi push | `PUT` / `DELETE /customer/devices` | – |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Beranda wallet, riwayat, kedaluwarsa
|
||||||
|
|
||||||
|
### 4.1 Beranda — `GET /customer/wallet`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"point_balance": 12500,
|
||||||
|
"coin_balance": 8,
|
||||||
|
"point_value": 1,
|
||||||
|
"point_discount_value": 12500,
|
||||||
|
"nearest_expiring": {
|
||||||
|
"point": { "amount": 150, "date": "2026-12-31" },
|
||||||
|
"coin": null
|
||||||
|
},
|
||||||
|
"recent_transactions": [ /* sama dengan item riwayat §4.2, maksimal 5 */ ]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tampilkan:
|
||||||
|
- Saldo EnakPoint (`point_balance`) dengan keterangan "setara potongan Rp
|
||||||
|
{point_discount_value}" (format ribuan Indonesia: `Rp 12.500`).
|
||||||
|
- Saldo EnakCoin (`coin_balance`).
|
||||||
|
- Bila `nearest_expiring.point` / `.coin` tidak `null`: banner "{amount} EnakPoint akan
|
||||||
|
kedaluwarsa pada {date}" yang membuka layar §4.3.
|
||||||
|
- 5 mutasi terakhir dari `recent_transactions`, dengan tautan "Lihat semua" ke §4.2.
|
||||||
|
- Tombol aksi: Tukar EnakCoin (§7.1), Transfer (§7.2), Main game (§8), Voucher (§9).
|
||||||
|
|
||||||
|
Muat ulang beranda setelah setiap transaksi, saat webview game ditutup, dan saat
|
||||||
|
menerima push (§5).
|
||||||
|
|
||||||
|
Field `total_points`, `points_history`, `last_updated` di response ini **deprecated**;
|
||||||
|
jangan dipakai.
|
||||||
|
|
||||||
|
### 4.2 Riwayat — `GET /customer/wallet/transactions`
|
||||||
|
|
||||||
|
Query (semua opsional):
|
||||||
|
|
||||||
|
| Query | Contoh | Keterangan |
|
||||||
|
|---|---|---|
|
||||||
|
| `page` | `1` | Mulai dari 1 |
|
||||||
|
| `limit` | `20` | 1–100, default 20 |
|
||||||
|
| `currency` | `POINT` | `POINT` atau `COIN`; untuk tab EnakPoint / EnakCoin |
|
||||||
|
| `type` | `EARN,TRANSFER_IN` | Satu atau beberapa tipe dipisah koma, untuk filter |
|
||||||
|
| `from`, `to` | `2026-09-01` | Tanggal WIB, inklusif |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"currency": "POINT",
|
||||||
|
"type": "EARN",
|
||||||
|
"amount": 875,
|
||||||
|
"balance_after": 12500,
|
||||||
|
"description": "Belanja #ORD-0123 di Outlet Kemang",
|
||||||
|
"source": { "type": "ORDER", "id": "…" },
|
||||||
|
"outlet_id": "…",
|
||||||
|
"group_id": null,
|
||||||
|
"expires_at": "2026-12-31T23:59:59+07:00",
|
||||||
|
"lots": [{ "amount": 875, "remaining": 875, "expires_at": "2026-12-31T23:59:59+07:00" }],
|
||||||
|
"created_at": "2026-09-30T12:01:00Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "page": 1, "limit": 20, "total_count": 42, "total_pages": 3 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Aturan tampilan:
|
||||||
|
- `amount` bertanda: positif tampil hijau dengan `+`, negatif merah dengan `−`.
|
||||||
|
- Penambahan membawa `source`, pengurangan membawa `destination`, keduanya `{ type, id }`.
|
||||||
|
- `description` sudah siap tampil (nama lawan transfer sudah disamarkan, nama game dan
|
||||||
|
voucher sudah tertulis). Tampilkan apa adanya.
|
||||||
|
- Mutasi masuk yang punya `expires_at` menampilkan "Berlaku sampai {tanggal}".
|
||||||
|
- Infinite scroll memakai `pagination.total_pages`.
|
||||||
|
- Riwayat tidak pernah berubah atau hilang; koreksi muncul sebagai baris baru.
|
||||||
|
|
||||||
|
Label tipe:
|
||||||
|
|
||||||
|
| `type` | Mata uang | Label | Arah |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `EARN` | keduanya | Dari belanja | + |
|
||||||
|
| `EARN_REVERSAL` | keduanya | Dibatalkan (order di-void/refund) | − |
|
||||||
|
| `EXCHANGE_OUT` | EnakCoin | Ditukar ke EnakPoint | − |
|
||||||
|
| `EXCHANGE_IN` | EnakPoint | Hasil tukar EnakCoin | + |
|
||||||
|
| `TRANSFER_OUT` | keduanya | Transfer keluar | − |
|
||||||
|
| `TRANSFER_IN` | keduanya | Transfer masuk | + |
|
||||||
|
| `GAME_SPEND` | EnakCoin | Main game | − |
|
||||||
|
| `GAME_SPEND_REFUND` | EnakCoin | Biaya main dikembalikan | + |
|
||||||
|
| `GAME_REWARD` | EnakCoin | Hadiah game | + |
|
||||||
|
| `REWARD_REDEEM` | EnakPoint | Ditukar ke voucher | − |
|
||||||
|
| `REWARD_REDEEM_REFUND` | EnakPoint | Penukaran voucher dibatalkan | + |
|
||||||
|
| `EXPIRE` | keduanya | Kedaluwarsa | − |
|
||||||
|
| `ADJUSTMENT` | keduanya | Koreksi | + / − |
|
||||||
|
| `MIGRATION` | keduanya | Saldo awal | + |
|
||||||
|
|
||||||
|
Tipe yang tidak dikenal (bila backend menambah tipe baru): tampilkan `description` dan
|
||||||
|
arah dari tanda `amount`, tanpa label.
|
||||||
|
|
||||||
|
### 4.3 Akan kedaluwarsa — `GET /customer/wallet/expiring`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"point": [
|
||||||
|
{ "amount": 150, "date": "2026-10-31" },
|
||||||
|
{ "amount": 200, "date": "2026-12-31" }
|
||||||
|
],
|
||||||
|
"coin": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Daftar per tanggal, paling dekat di atas. Daftar kosong: tampilkan "Tidak ada saldo
|
||||||
|
yang akan kedaluwarsa". Saldo yang kedaluwarsa hangus tanpa kompensasi.
|
||||||
|
|
||||||
|
### 4.4 Daftar outlet — `GET /customer/outlets`
|
||||||
|
|
||||||
|
Outlet aktif di organisasi customer, tempat saldo EnakPoint & EnakCoin berlaku. Urut
|
||||||
|
berdasarkan nama.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"name": "Gokuna Kemang",
|
||||||
|
"address": "Jl. Kemang Raya 10",
|
||||||
|
"earns_points": true,
|
||||||
|
"earns_coins": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `address` bisa `null`.
|
||||||
|
- `earns_points` / `earns_coins`: belanja di outlet ini memberi EnakPoint / EnakCoin.
|
||||||
|
- Belum ada telepon, koordinat, atau jam buka; data itu belum disimpan di backend.
|
||||||
|
|
||||||
|
### 4.5 Riwayat order — `GET /customer/orders` dan `GET /customer/orders/:id`
|
||||||
|
|
||||||
|
Order milik customer yang login di semua outlet organisasinya, terbaru di atas. Order
|
||||||
|
hanya masuk ke sini bila kasir mengaitkannya ke customer.
|
||||||
|
|
||||||
|
`GET /api/v1/customer/orders?page=1&limit=20` (`limit` 1–100, default 20):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"order_number": "ORD-0123",
|
||||||
|
"outlet_id": "…",
|
||||||
|
"outlet_name": "Gokuna 1",
|
||||||
|
"order_type": "dine_in",
|
||||||
|
"status": "completed",
|
||||||
|
"payment_status": "completed",
|
||||||
|
"total_amount": 99000,
|
||||||
|
"item_count": 2,
|
||||||
|
"is_void": false,
|
||||||
|
"is_refund": false,
|
||||||
|
"points_earned": 865,
|
||||||
|
"coins_earned": 3,
|
||||||
|
"created_at": "2026-09-30T12:01:00Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "page": 1, "limit": 20, "total_count": 42, "total_pages": 3 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`GET /api/v1/customer/orders/{id}` mengembalikan field yang sama, ditambah:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"table_number": "A3",
|
||||||
|
"subtotal": 90000,
|
||||||
|
"discount_amount": 0,
|
||||||
|
"tax_amount": 9000,
|
||||||
|
"refund_amount": 0,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"product_id": "…",
|
||||||
|
"product_name": "Kopi Susu",
|
||||||
|
"variant_name": "Large",
|
||||||
|
"quantity": 2,
|
||||||
|
"unit_price": 25000,
|
||||||
|
"total_price": 50000,
|
||||||
|
"refund_quantity": 0,
|
||||||
|
"modifiers": [],
|
||||||
|
"status": "completed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"product_id": "…",
|
||||||
|
"product_name": "Ikan Tude",
|
||||||
|
"variant_name": null,
|
||||||
|
"quantity": 1,
|
||||||
|
"weight": 4.2,
|
||||||
|
"unit_name": "ons",
|
||||||
|
"unit_price": 4500,
|
||||||
|
"total_price": 18900,
|
||||||
|
"refund_quantity": 0,
|
||||||
|
"modifiers": [],
|
||||||
|
"status": "completed"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payments": [
|
||||||
|
{ "id": "…", "method_name": "Cash", "method_type": "cash", "amount": 99000, "status": "completed", "refund_amount": 0, "created_at": "…" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Order customer lain atau yang tidak ada → `404`.
|
||||||
|
- `points_earned` / `coins_earned`: yang didapat dari order ini; 0 bila tidak ada.
|
||||||
|
- Item timbangan membawa `weight` dan `unit_name`; tampilkan "1 × 4,2 ons".
|
||||||
|
- Order yang `is_void` atau `is_refund` tetap tampil, beri label "Dibatalkan" /
|
||||||
|
"Direfund".
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Notifikasi push (FCM)
|
||||||
|
|
||||||
|
### 5.1 Registrasi device
|
||||||
|
|
||||||
|
Setelah login berhasil **dan** setiap kali FCM memberi token baru (`onTokenRefresh`):
|
||||||
|
|
||||||
|
`PUT /api/v1/customer/devices`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "device_id": "<id unik & stabil per instalasi>", "fcm_token": "<token FCM>", "platform": "android", "app_version": "2.4.0" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- `device_id` wajib, stabil untuk satu instalasi (simpan di secure storage).
|
||||||
|
- `platform`: `android`, `ios`, atau `web`.
|
||||||
|
- Satu token FCM hanya milik satu customer: bila customer lain login di HP yang sama,
|
||||||
|
customer sebelumnya tidak lagi menerima notifikasi di HP itu.
|
||||||
|
- Saat **logout**, panggil `DELETE /api/v1/customer/devices/{device_id}` sebelum
|
||||||
|
menghapus token login.
|
||||||
|
|
||||||
|
Tanpa registrasi ini, customer tidak menerima push apa pun.
|
||||||
|
|
||||||
|
### 5.2 Tipe push
|
||||||
|
|
||||||
|
Semua nilai di `data` berupa string.
|
||||||
|
|
||||||
|
| `data.type` | Kapan | Isi `data` lain | Aksi saat di-tap |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `WALLET_TRANSFER_IN` | Menerima transfer | `transaction_id`, `group_id`, `currency`, `amount` | Buka riwayat, sorot transaksi itu |
|
||||||
|
| `WALLET_EXPIRING` | `reminder_days` hari sebelum saldo hangus | `currency`, `amount`, `expiry_date` | Buka layar kedaluwarsa (§4.3) |
|
||||||
|
| `WALLET_EXPIRED` | Saldo baru saja hangus | `currency`, `amount` | Buka riwayat |
|
||||||
|
| `PIN_LOCKED` | PIN terkunci setelah 5 kali salah | `locked_until` (RFC3339 UTC) | Buka layar lupa PIN (§6.4) |
|
||||||
|
|
||||||
|
Saat app terbuka dan menerima push wallet, muat ulang beranda.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. PIN
|
||||||
|
|
||||||
|
### 6.1 Kapan diminta
|
||||||
|
|
||||||
|
Jangan minta PIN saat registrasi. Minta saat customer **pertama kali** melakukan aksi
|
||||||
|
yang butuh PIN (tukar, transfer, tukar voucher). Cek dengan:
|
||||||
|
|
||||||
|
`GET /api/v1/customer/pin/status` → `{ "has_pin": false, "locked_until": null, "transfer_blocked_until": null }`
|
||||||
|
|
||||||
|
Bila `has_pin: false`, arahkan ke alur buat PIN, lalu kembali ke aksi semula.
|
||||||
|
|
||||||
|
### 6.2 Buat PIN
|
||||||
|
|
||||||
|
1. `POST /api/v1/customer/pin/otp` dengan `{ "purpose": "pin_setup" }`.
|
||||||
|
Response: `{ "purpose": "pin_setup", "otp_token": "…", "expires_at": "…" }`.
|
||||||
|
OTP dikirim ke WhatsApp customer.
|
||||||
|
2. Customer memasukkan kode OTP, lalu PIN dua kali.
|
||||||
|
3. `POST /api/v1/customer/pin` dengan
|
||||||
|
`{ "otp_token": "…", "otp_code": "123456", "pin": "482913", "confirm_pin": "482913" }`.
|
||||||
|
Response: status PIN.
|
||||||
|
|
||||||
|
Validasi di app sebelum kirim (server juga memeriksa, jawab `304`):
|
||||||
|
- Tepat 6 digit angka, dan konfirmasi sama.
|
||||||
|
- Bukan satu digit berulang (`111111`).
|
||||||
|
- Bukan berurutan naik/turun (`123456`, `654321`).
|
||||||
|
- Bukan tanggal lahir customer (`DDMMYY` atau `YYMMDD`).
|
||||||
|
|
||||||
|
Minta OTP lagi terlalu cepat → `429`: tampilkan hitung mundur.
|
||||||
|
|
||||||
|
### 6.3 Ganti PIN
|
||||||
|
|
||||||
|
`PUT /api/v1/customer/pin` dengan `{ "old_pin": "…", "pin": "…", "confirm_pin": "…" }`.
|
||||||
|
|
||||||
|
### 6.4 Lupa PIN
|
||||||
|
|
||||||
|
1. `POST /customer/pin/otp` dengan `{ "purpose": "pin_reset" }`.
|
||||||
|
2. `POST /customer/pin/reset` dengan `{ "otp_token", "otp_code", "pin", "confirm_pin" }`.
|
||||||
|
|
||||||
|
Reset juga membuka PIN yang terkunci. Setelah reset, **transfer keluar ditahan 24 jam**;
|
||||||
|
tukar EnakCoin dan tukar voucher tetap bisa. Beri tahu customer hal ini di layar sukses.
|
||||||
|
|
||||||
|
### 6.5 Menangani error PIN
|
||||||
|
|
||||||
|
Semua endpoint yang menerima `pin` bisa menjawab error PIN. Pada error ini **`data`
|
||||||
|
tidak `null`**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": false, "data": { "code": "PIN_INVALID", "remaining_attempts": 3 }, "errors": [ … ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
| `data.code` | Field tambahan | Tampilan |
|
||||||
|
|---|---|---|
|
||||||
|
| `PIN_NOT_SET` | – | Buka alur buat PIN (§6.2) |
|
||||||
|
| `PIN_INVALID` | `remaining_attempts` | "PIN salah, sisa {n} percobaan." Kosongkan input PIN |
|
||||||
|
| `PIN_LOCKED` | `locked_until` | "PIN terkunci sampai {jam}." Tombol "Lupa PIN" |
|
||||||
|
| `TRANSFER_BLOCKED` | `transfer_blocked_until` | "Transfer bisa dilakukan lagi pada {waktu}." |
|
||||||
|
|
||||||
|
5 kali salah berturut-turut mengunci PIN 30 menit; selama terkunci PIN yang benar pun
|
||||||
|
ditolak. Penghitung ada di server, jadi jangan membuat penghitung sendiri di app.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Tukar dan transfer
|
||||||
|
|
||||||
|
### 7.1 Tukar EnakCoin → EnakPoint
|
||||||
|
|
||||||
|
1. Customer mengetik jumlah EnakCoin. Panggil preview (debounce saat mengetik):
|
||||||
|
|
||||||
|
`GET /api/v1/customer/wallet/exchange/preview?coins=30`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "coin_amount": 10, "point_amount": 3, "coin_balance": 35, "coins": 30, "points": 9, "valid": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Kurs: `coin_amount` EnakCoin = `point_amount` EnakPoint. Tampilkan "10 EnakCoin =
|
||||||
|
3 EnakPoint".
|
||||||
|
- Bila `valid: false`, tampilkan `reason` sebagai alasan dan nonaktifkan tombol. Jumlah
|
||||||
|
harus kelipatan `coin_amount`.
|
||||||
|
- Tampilkan "Kamu akan mendapat {points} EnakPoint".
|
||||||
|
|
||||||
|
2. Konfirmasi (tukar tidak bisa dibatalkan) → minta PIN →
|
||||||
|
|
||||||
|
`POST /api/v1/customer/wallet/exchange` + header `Idempotency-Key`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "coins": 30, "pin": "482913" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"group_id": "…",
|
||||||
|
"coins": 30,
|
||||||
|
"points": 9,
|
||||||
|
"coin_amount": 10,
|
||||||
|
"point_amount": 3,
|
||||||
|
"lots": [{ "amount": 9, "expires_at": "2026-12-31T23:59:59+07:00" }],
|
||||||
|
"coin_balance": 5,
|
||||||
|
"point_balance": 9,
|
||||||
|
"replayed": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Layar sukses: saldo baru, dan bila `lots[].expires_at` ada, "EnakPoint ini berlaku
|
||||||
|
sampai {tanggal}". EnakPoint hasil tukar tidak bisa hidup lebih lama dari EnakCoin
|
||||||
|
asalnya.
|
||||||
|
|
||||||
|
Jumlah yang salah ditolak sebelum PIN dicek, jadi tidak memakan jatah percobaan PIN.
|
||||||
|
|
||||||
|
### 7.2 Transfer
|
||||||
|
|
||||||
|
1. Pilih mata uang (EnakPoint / EnakCoin), isi nomor HP penerima dan jumlah.
|
||||||
|
2. Cek penerima:
|
||||||
|
|
||||||
|
`GET /api/v1/customer/wallet/transfer/recipient?phone=081234561234`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Bu*** Sa***", "phone_number": "08**-****-1234" }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Hasil | Tampilan |
|
||||||
|
|---|---|
|
||||||
|
| Sukses | "Kirim ke Bu*** Sa*** (08**-****-1234)?" |
|
||||||
|
| `404` | "Nomor ini tidak terdaftar" |
|
||||||
|
| `304` | "Tidak bisa mengirim ke nomor ini" (diri sendiri, akun nonaktif) |
|
||||||
|
|
||||||
|
3. Konfirmasi (transfer final, tidak bisa dibatalkan) → minta PIN →
|
||||||
|
|
||||||
|
`POST /api/v1/customer/wallet/transfer` + header `Idempotency-Key`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "currency": "POINT", "amount": 120, "recipient_phone": "081234561234", "pin": "482913" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"group_id": "…",
|
||||||
|
"currency": "POINT",
|
||||||
|
"amount": 120,
|
||||||
|
"recipient": { "name": "Bu*** Sa***", "phone_number": "08**-****-1234" },
|
||||||
|
"lots": [
|
||||||
|
{ "amount": 100, "expires_at": "2026-12-31T23:59:59+07:00" },
|
||||||
|
{ "amount": 20, "expires_at": null }
|
||||||
|
],
|
||||||
|
"balance": 30,
|
||||||
|
"replayed": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Layar sukses: saldo tersisa (`balance`). Bila ada `lots[].expires_at`, tampilkan
|
||||||
|
"Saldo yang dikirim berlaku sampai {tanggal}" (tanggal kedaluwarsa ikut terbawa ke
|
||||||
|
penerima).
|
||||||
|
|
||||||
|
Penolakan `304` yang mungkin: transfer dimatikan owner, di bawah minimal, di atas
|
||||||
|
maksimal per transaksi, melewati batas harian (reset tengah malam WIB), saldo tidak
|
||||||
|
cukup. Tampilkan pesan umum "Transfer tidak bisa diproses" plus alasan yang sesuai
|
||||||
|
bila bisa dikenali. Bila kena `TRANSFER_BLOCKED`, ikuti §6.5.
|
||||||
|
|
||||||
|
Penerima mendapat push `WALLET_TRANSFER_IN`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Game (EnakGame)
|
||||||
|
|
||||||
|
Game dimainkan di **webview** yang memuat `game_url` tiap game. Pembagian tugasnya:
|
||||||
|
aplikasi menampilkan daftar game, membuka webview, dan memberi token lewat bridge; game
|
||||||
|
EnakGame sendiri yang memulai session, memotong EnakCoin, mengirim hasil, dan
|
||||||
|
menampilkan hadiah ([`integration-enakgame.md`](./integration-enakgame.md)). Aplikasi
|
||||||
|
**tidak** memanggil `POST /customer/enakgame/sessions` atau `…/complete`.
|
||||||
|
|
||||||
|
### 8.1 Daftar game — `GET /customer/enakgame/games`
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "8a1f…",
|
||||||
|
"slug": "spin",
|
||||||
|
"name": "Spin Harian",
|
||||||
|
"description": null,
|
||||||
|
"thumbnail_url": "https://…/spin.png",
|
||||||
|
"game_url": "https://…/spin/index.html",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"entry_cost": 5,
|
||||||
|
"session_ttl_seconds": 600,
|
||||||
|
"events": [
|
||||||
|
{ "id": "…", "name": "Ramadan 2x", "banner_url": "https://…", "multiplier": 2, "bonus": null, "end_at": "2026-10-31T16:59:59Z" }
|
||||||
|
],
|
||||||
|
"prizes": [ { "entry": 1, "label": "Zonk", "amount": 0 } ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Tampilkan:
|
||||||
|
- Kartu per game: `thumbnail_url`, `name`, biaya "{entry_cost} EnakCoin".
|
||||||
|
- Badge event bila `events` tidak kosong: `name` atau `banner_url`, dan "berakhir
|
||||||
|
{end_at}" (tampilkan dalam WIB).
|
||||||
|
- Tombol Main nonaktif dengan teks "EnakCoin kurang" bila `coin_balance` (§4.1) lebih
|
||||||
|
kecil dari `entry_cost`.
|
||||||
|
- `prizes` hanya dipakai game spin di dalam webview; aplikasi boleh mengabaikannya.
|
||||||
|
|
||||||
|
Game yang dinonaktifkan admin hilang dari daftar ini. Muat ulang daftar setiap kali
|
||||||
|
layar dibuka.
|
||||||
|
|
||||||
|
### 8.2 Membuka game
|
||||||
|
|
||||||
|
1. Customer menekan Main → buka webview layar penuh dengan `game_url`.
|
||||||
|
2. Pasang bridge (§8.3) **sebelum** halaman dimuat.
|
||||||
|
3. Saat game mengirim `ready`, jawab dengan `init`.
|
||||||
|
4. Saat game mengirim `close`, tutup webview, lalu muat ulang beranda wallet (§4.1).
|
||||||
|
|
||||||
|
Jangan menaruh token di URL `game_url` (query string atau fragment): URL bisa tercatat di
|
||||||
|
log server game dan riwayat webview.
|
||||||
|
|
||||||
|
### 8.3 Bridge (sisi aplikasi)
|
||||||
|
|
||||||
|
> **Usulan.** Kontrak ini sama dengan [`integration-enakgame.md`](./integration-enakgame.md)
|
||||||
|
> §2 dan belum diimplementasikan. Sepakati dengan tim EnakGame sebelum mulai.
|
||||||
|
|
||||||
|
- Game → aplikasi: JavaScript channel webview bernama **`EnakGameHost`**; setiap pesan
|
||||||
|
berupa JSON string.
|
||||||
|
- Aplikasi → game: jalankan `window.enakGame.receive('<json>')` di webview.
|
||||||
|
|
||||||
|
| Pesan masuk dari game | Yang dilakukan aplikasi |
|
||||||
|
|---|---|
|
||||||
|
| `{ "type": "ready" }` | Kirim `{ "type": "init", "api_base_url": "<base URL>/api/v1", "token": "<token customer>", "game_id": "<id game yang dibuka>" }` |
|
||||||
|
| `{ "type": "token_expired" }` | Login ulang customer (tidak ada refresh token), lalu kirim `{ "type": "token", "token": "<token baru>" }` |
|
||||||
|
| `{ "type": "balance_changed", "coin_balance": 15 }` | Perbarui saldo EnakCoin yang ditampilkan aplikasi |
|
||||||
|
| `{ "type": "close" }` | Tutup webview, muat ulang beranda |
|
||||||
|
|
||||||
|
Abaikan pesan dengan `type` lain. Tombol back Android jangan langsung menutup webview:
|
||||||
|
tampilkan konfirmasi "Keluar dari game? EnakCoin yang sudah dipakai untuk main tidak
|
||||||
|
kembali", lalu tutup. Tidak perlu mengirim pesan ke game.
|
||||||
|
|
||||||
|
### 8.4 Riwayat main — `GET /customer/enakgame/sessions?page=1&limit=20`
|
||||||
|
|
||||||
|
Query opsional `game_id` (riwayat satu game) dan `status` (`STARTED`, `COMPLETED`,
|
||||||
|
`REFUNDED`, `EXPIRED`) untuk filter atau tab.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "…", "game_id": "8a1f…", "status": "COMPLETED", "entry_cost": 5, "reward_total": 10,
|
||||||
|
"started_at": "…", "expires_at": "…", "ended_at": "…", "refund_reason": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "page": 1, "limit": 20, "total_count": 3, "total_pages": 1 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| `status` | Label | Keterangan |
|
||||||
|
|---|---|---|
|
||||||
|
| `STARTED` | Sedang dimainkan | |
|
||||||
|
| `COMPLETED` | Selesai | "Dapat {reward_total} EnakCoin" |
|
||||||
|
| `REFUNDED` | Dikembalikan | Entry cost kembali; `refund_reason` `SYSTEM_ERROR` atau `GAME_DEACTIVATED` |
|
||||||
|
| `EXPIRED` | Tidak selesai | Hasil tidak dikirim sebelum batas waktu; entry cost tidak kembali |
|
||||||
|
|
||||||
|
Nama game diambil dari daftar game (§8.1) lewat `game_id`. Detail satu session:
|
||||||
|
`GET /customer/enakgame/sessions/:id`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Voucher (tukar EnakPoint)
|
||||||
|
|
||||||
|
### 9.1 Katalog — `GET /customer/vouchers`
|
||||||
|
|
||||||
|
Voucher yang bisa ditukar sekarang: aktif, dalam masa berlaku, dan masih ada stoknya.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"name": "Kopi Susu Gratis",
|
||||||
|
"description": "Berlaku untuk ukuran regular",
|
||||||
|
"image_url": "https://…/kopi.png",
|
||||||
|
"voucher_type": "FREE_ITEM",
|
||||||
|
"face_value": 20000,
|
||||||
|
"point_cost": 15000,
|
||||||
|
"max_per_customer": 2,
|
||||||
|
"valid_until": "2026-12-31T16:59:59Z",
|
||||||
|
"terms": { "…": "syarat & ketentuan, objek JSON bebas" },
|
||||||
|
"available": 120
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `point_cost`: EnakPoint yang dipotong. Tombol Tukar nonaktif bila `point_balance`
|
||||||
|
kurang.
|
||||||
|
- `face_value`: nilai voucher dalam rupiah, tampilkan sebagai "senilai Rp 20.000".
|
||||||
|
- `available`: sisa stok; `null` berarti stok tidak dihitung. Bila 0, tampilkan "Habis".
|
||||||
|
- `max_per_customer`: batas tukar per customer; `null` = tanpa batas.
|
||||||
|
- `terms`: objek JSON yang isinya diatur admin. Sepakati bentuknya dengan tim
|
||||||
|
backoffice; sebelum itu tampilkan `description` saja.
|
||||||
|
|
||||||
|
| `voucher_type` | Label usulan |
|
||||||
|
|---|---|
|
||||||
|
| `FIXED_VALUE` | Potongan Rp {face_value} |
|
||||||
|
| `PERCENTAGE` | Potongan persen |
|
||||||
|
| `FREE_ITEM` | Gratis item |
|
||||||
|
| `MERCHANT_BENEFIT` | Benefit merchant |
|
||||||
|
|
||||||
|
### 9.2 Tukar — `POST /customer/vouchers/:id/redeem`
|
||||||
|
|
||||||
|
Konfirmasi ("Tukar {point_cost} EnakPoint dengan {name}? Tidak bisa dibatalkan.") →
|
||||||
|
minta PIN → kirim dengan header `Idempotency-Key`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "pin": "482913" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"voucher_id": "…",
|
||||||
|
"voucher_name": "Kopi Susu Gratis",
|
||||||
|
"voucher_image_url": "https://…/kopi.png",
|
||||||
|
"voucher_type": "FREE_ITEM",
|
||||||
|
"status": "COMPLETED",
|
||||||
|
"face_value": 20000,
|
||||||
|
"point_cost": 15000,
|
||||||
|
"code": "KOPI-7F3C-2291",
|
||||||
|
"code_expires_at": "2026-12-31T16:59:59Z",
|
||||||
|
"completed_at": "…",
|
||||||
|
"created_at": "…",
|
||||||
|
"point_balance": 2500,
|
||||||
|
"replayed": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Layar sukses: voucher, `code` bila ada (bisa disalin), masa berlaku, dan saldo
|
||||||
|
EnakPoint baru (`point_balance`).
|
||||||
|
- `code` bisa `null`: voucher ini tidak memakai kode; tunjukkan layar voucher ke kasir.
|
||||||
|
- `status: "PENDING"`: voucher sedang diproses penyedia luar (belum ada voucher seperti
|
||||||
|
ini di katalog, tapi tangani dari sekarang). EnakPoint sudah terpotong;
|
||||||
|
tampilkan "Voucher sedang diproses" dan cek lagi di Voucher saya (§9.3). Bila akhirnya
|
||||||
|
`FAILED`, EnakPoint dikembalikan otomatis (mutasi `REWARD_REDEEM_REFUND`).
|
||||||
|
- Error PIN ditangani sesuai §6.5.
|
||||||
|
|
||||||
|
| Penolakan `304` (`cause`) | Tampilan |
|
||||||
|
|---|---|
|
||||||
|
| `not enough EnakPoint` | "EnakPoint kamu kurang." |
|
||||||
|
| `the voucher is out of stock` | "Voucher sudah habis." Muat ulang katalog |
|
||||||
|
| `this voucher can be redeemed at most … times per customer` | "Kamu sudah mencapai batas penukaran voucher ini." |
|
||||||
|
| `the voucher is not available`, `… cannot be redeemed yet`, `… has ended`, `… not available yet` | "Voucher tidak tersedia." Muat ulang katalog |
|
||||||
|
| `the customer is not active` | "Akun tidak aktif." |
|
||||||
|
| `this Idempotency-Key was already used to redeem another voucher` | Bug di app: key dipakai ulang |
|
||||||
|
|
||||||
|
### 9.3 Voucher saya — `GET /customer/vouchers/redemptions?page=1&limit=20`
|
||||||
|
|
||||||
|
Daftar penukaran customer, terbaru di atas, dengan bentuk item sama seperti response
|
||||||
|
§9.2 (tanpa `point_balance` dan `replayed`). Seperti semua daftar berhalaman di dokumen
|
||||||
|
ini, array-nya ada di `data.data` dan pagination di `data.pagination` di dalam amplop
|
||||||
|
response (§2.2); daftar kosong berupa `[]`.
|
||||||
|
|
||||||
|
| `status` | Tampilan |
|
||||||
|
|---|---|
|
||||||
|
| `COMPLETED` | Voucher siap dipakai: nama, `code` (bila ada), berlaku sampai `code_expires_at` |
|
||||||
|
| `PENDING` | "Sedang diproses" |
|
||||||
|
| `FAILED` | "Gagal, EnakPoint sudah dikembalikan" |
|
||||||
|
|
||||||
|
**Memakai voucher di outlet:** customer menunjukkan layar voucher ke kasir. POS belum
|
||||||
|
bisa menandai voucher terpakai, jadi aplikasi belum bisa menampilkan status "sudah
|
||||||
|
dipakai" ([`integration-pos.md`](./integration-pos.md) §5).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Yang sudah dihapus / deprecated
|
||||||
|
|
||||||
|
Sudah **dihapus** dari API (jangan dipanggil, akan error / tidak ada):
|
||||||
|
|
||||||
|
| Lama | Pengganti |
|
||||||
|
|---|---|
|
||||||
|
| `POST /customer/spin` | Game EnakGame di webview (§8) |
|
||||||
|
| `GET /customer/games`, `GET /customer/ferris-wheel` | `GET /customer/enakgame/games` |
|
||||||
|
| `coins_used`, `coins_remaining`, `prize_won`, `game_play` di response spin | Tidak ada; hasil game ditampilkan di dalam game |
|
||||||
|
| `metadata.coin_cost` pada data game | `entry_cost` |
|
||||||
|
| `GET /customer/tokens` | `GET /customer/wallet` → `coin_balance` |
|
||||||
|
| `total_tokens`, `tokens_history`, `token_used`, `tokens_remaining` | `coin_balance`, `GET /customer/wallet/transactions?currency=COIN` |
|
||||||
|
| `POST /customer/wallet/payment-code` | Tidak ada; EnakPoint tidak bisa untuk bayar |
|
||||||
|
| `POST /customer/orders/:id/pay-with-points` | Tidak ada; EnakPoint tidak bisa untuk bayar |
|
||||||
|
| `accepts_point_payment` di `GET /customer/outlets` | – |
|
||||||
|
| `points_used`, `point_value` di `payments` pada `GET /customer/orders/:id` | – |
|
||||||
|
| Tipe mutasi `PAYMENT`, `PAYMENT_REFUND` di riwayat | Tidak ditulis lagi |
|
||||||
|
|
||||||
|
Masih ada tapi **deprecated** (akan dihapus, jangan dipakai di kode baru):
|
||||||
|
|
||||||
|
| Lama | Pengganti |
|
||||||
|
|---|---|
|
||||||
|
| `GET /customer/points` | `GET /customer/wallet` → `point_balance` |
|
||||||
|
| `total_points`, `points_history`, `last_updated` di `/customer/wallet` | `point_balance`, `recent_transactions` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Checklist selesai
|
||||||
|
|
||||||
|
- [ ] Beranda menampilkan saldo EnakPoint ("setara potongan Rp …"), EnakCoin, dan banner kedaluwarsa terdekat.
|
||||||
|
- [ ] Riwayat dengan tab per mata uang, filter tipe/tanggal, infinite scroll, dan label semua tipe di §4.2, termasuk tipe game dan voucher.
|
||||||
|
- [ ] Layar saldo akan kedaluwarsa.
|
||||||
|
- [ ] Registrasi device FCM setelah login dan saat token berganti; unregister saat logout.
|
||||||
|
- [ ] Penanganan tap untuk keempat tipe push.
|
||||||
|
- [ ] PIN diminta hanya saat aksi yang membutuhkan; alur buat, ganti, dan lupa PIN lewat OTP.
|
||||||
|
- [ ] Keempat error PIN ditangani di semua layar yang meminta PIN (tukar, transfer, voucher).
|
||||||
|
- [ ] Tukar dengan preview, kelipatan kurs, konfirmasi, `Idempotency-Key`, retry dengan key sama.
|
||||||
|
- [ ] Transfer dengan cek penerima tersamar, konfirmasi, `Idempotency-Key`, retry dengan key sama.
|
||||||
|
- [ ] Daftar game dengan biaya, badge event, dan tombol nonaktif bila EnakCoin kurang.
|
||||||
|
- [ ] Webview game dengan bridge §8.3; token tidak pernah di URL; beranda dimuat ulang saat game ditutup.
|
||||||
|
- [ ] Riwayat main dengan label status.
|
||||||
|
- [ ] Katalog voucher, tukar dengan PIN dan `Idempotency-Key`, status `PENDING` ditangani.
|
||||||
|
- [ ] Voucher saya dengan kode yang bisa disalin.
|
||||||
|
- [ ] Riwayat order dengan pagination dan layar detail (item, pembayaran, EnakPoint/EnakCoin yang didapat).
|
||||||
|
- [ ] Tidak ada pemakaian endpoint atau field di §10.
|
||||||
|
- [ ] PIN dan token tidak pernah disimpan sembarangan, di-log, atau dikirim ke analytics.
|
||||||
@@ -0,0 +1,617 @@
|
|||||||
|
# Prompt: fitur EnakPoint & EnakCoin di Mobile App Customer
|
||||||
|
|
||||||
|
Kamu mengerjakan aplikasi mobile untuk **customer** (bukan kasir, bukan backoffice).
|
||||||
|
Tugasmu: membangun fitur loyalitas EnakPoint & EnakCoin di aplikasi, memakai API backend
|
||||||
|
yang sudah jadi dan dijelaskan di dokumen ini. Jangan mengarang endpoint, field, atau
|
||||||
|
aturan yang tidak tertulis di sini; kalau ada yang kurang jelas, tanyakan dulu.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Konteks bisnis
|
||||||
|
|
||||||
|
| | EnakPoint (`POINT`) | EnakCoin (`COIN`) |
|
||||||
|
| ----------------------------- | ---------------------------------------------------- | ----------------------------------- |
|
||||||
|
| Didapat dari | Belanja (order lunas), koreksi admin, tukar EnakCoin | Belanja, koreksi admin |
|
||||||
|
| Dipakai untuk | **Membayar order** | **Main game**, ditukar ke EnakPoint |
|
||||||
|
| Bisa dikirim ke customer lain | Ya | Ya |
|
||||||
|
| Bisa kedaluwarsa | Ya, bila owner mengaktifkan | Ya, bila owner mengaktifkan |
|
||||||
|
|
||||||
|
Tidak ada lagi "token". Semua yang dulu token sekarang EnakCoin, dan endpoint serta
|
||||||
|
field bernama token sudah dihapus dari API.
|
||||||
|
|
||||||
|
### Aturan yang wajib dipatuhi di UI
|
||||||
|
|
||||||
|
1. **Semua jumlah bilangan bulat.** Tidak ada desimal pada EnakPoint atau EnakCoin.
|
||||||
|
2. **Saldo bukan uang.** Nilai rupiah EnakPoint selalu ditulis **"setara potongan
|
||||||
|
Rp …"**, tidak pernah "saldo Rp …" atau "uang". Tidak ada fitur tarik tunai.
|
||||||
|
3. **PIN 6 digit wajib** untuk: membuat kode bayar, tukar
|
||||||
|
EnakCoin, dan transfer. **Main game tidak butuh PIN.** Melihat saldo dan riwayat
|
||||||
|
tidak butuh PIN.
|
||||||
|
4. **PIN terpisah dari password login** dan selalu dikirim sebagai **string** (supaya
|
||||||
|
nol di depan tidak hilang). Jangan pernah menyimpan PIN di perangkat, log, atau
|
||||||
|
analytics.
|
||||||
|
5. **Satu akun customer = satu organisasi.** Saldo berlaku di semua outlet organisasi itu.
|
||||||
|
6. **Waktu memakai WIB.** Tanggal kedaluwarsa berarti saldo masih bisa dipakai sampai
|
||||||
|
23:59:59 WIB di tanggal itu.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Koneksi ke API
|
||||||
|
|
||||||
|
- Base URL: `/api/v1`
|
||||||
|
- Semua endpoint customer: header `Authorization: Bearer <token login customer>`
|
||||||
|
- Semua jumlah di request dan response berupa integer.
|
||||||
|
|
||||||
|
### Registrasi customer
|
||||||
|
|
||||||
|
`POST /api/v1/customer-auth/register/start` menerima `organization_id` (opsional):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "phone_number": "0812…", "name": "Budi", "birth_date": "2000-01-31", "organization_id": "648b96a0-1d1d-414e-baee-37e9d6317b4e" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Customer terdaftar di satu organisasi, dan saldonya berlaku di semua outlet organisasi itu.
|
||||||
|
- Bila `organization_id` tidak dikirim dan backend hanya punya satu organisasi, customer
|
||||||
|
otomatis masuk ke organisasi itu. Bila ada lebih dari satu, registrasi ditolak
|
||||||
|
("organization_id is required"), jadi sebaiknya app selalu mengirimnya dari config per
|
||||||
|
environment/brand.
|
||||||
|
- `organization_id` yang dikirim harus ada; bila tidak, registrasi ditolak sebelum OTP dikirim.
|
||||||
|
- Wallet customer baru belum punya baris sampai saldo pertama kali bergerak;
|
||||||
|
`GET /customer/wallet` tetap menjawab saldo 0.
|
||||||
|
|
||||||
|
### Format response
|
||||||
|
|
||||||
|
Sukses:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": true, "data": { … }, "errors": null }
|
||||||
|
```
|
||||||
|
|
||||||
|
Gagal:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": false, "data": null, "errors": [{ "code": "304", "entity": "wallet_service", "cause": "wallet move refused: not enough EnakCoin" }] }
|
||||||
|
```
|
||||||
|
|
||||||
|
| `errors[0].code` | HTTP | Arti | Yang dilakukan app |
|
||||||
|
| ------------------ | ---- | ------------------------------------ | ------------------------------------------------------------------------------------------------- |
|
||||||
|
| `303`, `310` | 400 | Request tidak lengkap / salah format | Bug di app; tampilkan pesan umum |
|
||||||
|
| `304` | 400 | Ditolak aturan bisnis | Tampilkan pesan yang ramah (lihat tiap fitur); `cause` berbahasa Inggris, jangan tampilkan mentah |
|
||||||
|
| `404` | 404 | Tidak ditemukan | Tampilkan "tidak ditemukan" |
|
||||||
|
| `429` | 429 | Minta OTP terlalu cepat | Tampilkan hitung mundur sebelum boleh minta lagi |
|
||||||
|
| `PIN_NOT_SET` | 403 | Belum punya PIN | Buka alur buat PIN (§6.2) |
|
||||||
|
| `PIN_INVALID` | 400 | PIN salah | §6.5 |
|
||||||
|
| `PIN_LOCKED` | 423 | PIN terkunci | §6.5 |
|
||||||
|
| `TRANSFER_BLOCKED` | 403 | Transfer ditahan setelah reset PIN | §6.5 |
|
||||||
|
| `900` | 500 | Error server | "Terjadi kesalahan, coba lagi" |
|
||||||
|
|
||||||
|
### Idempotency-Key
|
||||||
|
|
||||||
|
Endpoint **tukar** dan **transfer** wajib header `Idempotency-Key` (string unik, maks.
|
||||||
|
50 karakter, mis. UUID v4).
|
||||||
|
|
||||||
|
- Buat **satu key baru saat customer menekan tombol konfirmasi**.
|
||||||
|
- Bila request gagal karena jaringan/timeout, **kirim ulang dengan key yang sama**.
|
||||||
|
Server mengembalikan hasil pertama dengan `"replayed": true` dan tidak memotong saldo
|
||||||
|
dua kali.
|
||||||
|
- Jangan pakai ulang key untuk transaksi yang berbeda; server menolaknya (`304`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Layar yang perlu dibuat
|
||||||
|
|
||||||
|
| Layar | Endpoint utama | Butuh PIN |
|
||||||
|
| -------------------------------- | ------------------------------------------------------------ | --------- |
|
||||||
|
| Beranda wallet | `GET /customer/wallet` | – |
|
||||||
|
| Riwayat mutasi | `GET /customer/wallet/transactions` | – |
|
||||||
|
| Saldo akan kedaluwarsa | `GET /customer/wallet/expiring` | – |
|
||||||
|
| Daftar outlet | `GET /customer/outlets` | – |
|
||||||
|
| Riwayat order + detail | `GET /customer/orders`, `GET /customer/orders/:id` | – |
|
||||||
|
| Kode bayar (angka + QR) | `POST /customer/wallet/payment-code` | Ya |
|
||||||
|
| Tukar EnakCoin | `GET …/exchange/preview`, `POST /customer/wallet/exchange` | Ya |
|
||||||
|
| Transfer | `GET …/transfer/recipient`, `POST /customer/wallet/transfer` | Ya |
|
||||||
|
| PIN (buat, ganti, lupa) | `/customer/pin/*` | – |
|
||||||
|
| Game | `POST /customer/spin` | – |
|
||||||
|
| (latar belakang) registrasi push | `PUT` / `DELETE /customer/devices` | – |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Beranda wallet, riwayat, kedaluwarsa
|
||||||
|
|
||||||
|
### 4.1 Beranda — `GET /customer/wallet`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"point_balance": 12500,
|
||||||
|
"coin_balance": 8,
|
||||||
|
"point_value": 1,
|
||||||
|
"point_discount_value": 12500,
|
||||||
|
"nearest_expiring": {
|
||||||
|
"point": { "amount": 150, "date": "2026-12-31" },
|
||||||
|
"coin": null
|
||||||
|
},
|
||||||
|
"recent_transactions": [
|
||||||
|
/* sama dengan item riwayat §4.2, maksimal 5 */
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tampilkan:
|
||||||
|
|
||||||
|
- Saldo EnakPoint (`point_balance`) dengan keterangan "setara potongan Rp
|
||||||
|
{point_discount_value}" (format ribuan Indonesia: `Rp 12.500`).
|
||||||
|
- Saldo EnakCoin (`coin_balance`).
|
||||||
|
- Bila `nearest_expiring.point` / `.coin` tidak `null`: banner "{amount} EnakPoint akan
|
||||||
|
kedaluwarsa pada {date}" yang membuka layar §4.3.
|
||||||
|
- 5 mutasi terakhir dari `recent_transactions`, dengan tautan "Lihat semua" ke §4.2.
|
||||||
|
- Tombol aksi: Bayar di kasir (§7.1), Tukar EnakCoin (§8.1), Transfer (§8.2), Main game (§9).
|
||||||
|
|
||||||
|
Muat ulang beranda setelah setiap transaksi dan saat menerima push (§5).
|
||||||
|
|
||||||
|
Field `total_points`, `points_history`, `last_updated` di response ini **deprecated**;
|
||||||
|
jangan dipakai.
|
||||||
|
|
||||||
|
### 4.2 Riwayat — `GET /customer/wallet/transactions`
|
||||||
|
|
||||||
|
Query (semua opsional):
|
||||||
|
|
||||||
|
| Query | Contoh | Keterangan |
|
||||||
|
| ------------ | -------------- | --------------------------------------------------- |
|
||||||
|
| `page` | `1` | Mulai dari 1 |
|
||||||
|
| `limit` | `20` | 1–100, default 20 |
|
||||||
|
| `currency` | `POINT` | `POINT` atau `COIN`; untuk tab EnakPoint / EnakCoin |
|
||||||
|
| `type` | `EARN,PAYMENT` | Satu atau beberapa tipe dipisah koma, untuk filter |
|
||||||
|
| `from`, `to` | `2026-09-01` | Tanggal WIB, inklusif |
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"currency": "POINT",
|
||||||
|
"type": "EARN",
|
||||||
|
"amount": 875,
|
||||||
|
"balance_after": 12500,
|
||||||
|
"description": "Belanja #ORD-0123 di Outlet Kemang",
|
||||||
|
"source": { "type": "ORDER", "id": "…" },
|
||||||
|
"outlet_id": "…",
|
||||||
|
"group_id": null,
|
||||||
|
"expires_at": "2026-12-31T23:59:59+07:00",
|
||||||
|
"lots": [{ "amount": 875, "remaining": 875, "expires_at": "2026-12-31T23:59:59+07:00" }],
|
||||||
|
"created_at": "2026-09-30T12:01:00Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "page": 1, "limit": 20, "total_count": 42, "total_pages": 3 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Aturan tampilan:
|
||||||
|
|
||||||
|
- `amount` bertanda: positif tampil hijau dengan `+`, negatif merah dengan `−`.
|
||||||
|
- `description` sudah siap tampil (nama lawan transfer sudah disamarkan). Tampilkan apa
|
||||||
|
adanya.
|
||||||
|
- Mutasi masuk yang punya `expires_at` menampilkan "Berlaku sampai {tanggal}".
|
||||||
|
- Infinite scroll memakai `pagination.total_pages`.
|
||||||
|
- Riwayat tidak pernah berubah atau hilang; koreksi muncul sebagai baris baru.
|
||||||
|
|
||||||
|
Label tipe:
|
||||||
|
|
||||||
|
| `type` | Label | Arah |
|
||||||
|
| ---------------- | --------------------------------- | ----- |
|
||||||
|
| `EARN` | Dari belanja | + |
|
||||||
|
| `EARN_REVERSAL` | Dibatalkan (order di-void/refund) | − |
|
||||||
|
| `PAYMENT` | Bayar pesanan | − |
|
||||||
|
| `PAYMENT_REFUND` | Pengembalian pembayaran | + |
|
||||||
|
| `EXCHANGE_OUT` | Ditukar ke EnakPoint | − |
|
||||||
|
| `EXCHANGE_IN` | Hasil tukar EnakCoin | + |
|
||||||
|
| `TRANSFER_OUT` | Transfer keluar | − |
|
||||||
|
| `TRANSFER_IN` | Transfer masuk | + |
|
||||||
|
| `GAME_SPEND` | Main game | − |
|
||||||
|
| `EXPIRE` | Kedaluwarsa | − |
|
||||||
|
| `ADJUSTMENT` | Koreksi | + / − |
|
||||||
|
| `MIGRATION` | Saldo awal | + |
|
||||||
|
|
||||||
|
### 4.3 Akan kedaluwarsa — `GET /customer/wallet/expiring`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"point": [
|
||||||
|
{ "amount": 150, "date": "2026-10-31" },
|
||||||
|
{ "amount": 200, "date": "2026-12-31" }
|
||||||
|
],
|
||||||
|
"coin": []
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Daftar per tanggal, paling dekat di atas. Daftar kosong: tampilkan "Tidak ada saldo
|
||||||
|
yang akan kedaluwarsa". Saldo yang kedaluwarsa hangus tanpa kompensasi.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4.4 Daftar outlet — `GET /customer/outlets`
|
||||||
|
|
||||||
|
Outlet aktif di organisasi customer, tempat saldo EnakPoint & EnakCoin berlaku. Urut
|
||||||
|
berdasarkan nama.
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"name": "Gokuna Kemang",
|
||||||
|
"address": "Jl. Kemang Raya 10",
|
||||||
|
"accepts_point_payment": true,
|
||||||
|
"earns_points": true,
|
||||||
|
"earns_coins": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
- `address` bisa `null`.
|
||||||
|
- `accepts_point_payment`: kasir di outlet ini menerima pembayaran EnakPoint. Pakai
|
||||||
|
untuk label "Bisa bayar pakai EnakPoint".
|
||||||
|
- `earns_points` / `earns_coins`: belanja di outlet ini memberi EnakPoint / EnakCoin.
|
||||||
|
- Belum ada telepon, koordinat, atau jam buka; data itu belum disimpan di backend.
|
||||||
|
|
||||||
|
### 4.5 Riwayat order — `GET /customer/orders` dan `GET /customer/orders/:id`
|
||||||
|
|
||||||
|
Order milik customer yang login di semua outlet organisasinya, terbaru di atas. Order
|
||||||
|
hanya masuk ke sini bila kasir mengaitkannya ke customer.
|
||||||
|
|
||||||
|
`GET /api/v1/customer/orders?page=1&limit=20` (`limit` 1–100, default 20):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"order_number": "ORD-0123",
|
||||||
|
"outlet_id": "…",
|
||||||
|
"outlet_name": "Gokuna 1",
|
||||||
|
"order_type": "dine_in",
|
||||||
|
"status": "completed",
|
||||||
|
"payment_status": "completed",
|
||||||
|
"total_amount": 99000,
|
||||||
|
"item_count": 2,
|
||||||
|
"is_void": false,
|
||||||
|
"is_refund": false,
|
||||||
|
"points_earned": 865,
|
||||||
|
"coins_earned": 3,
|
||||||
|
"created_at": "2026-09-30T12:01:00Z"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pagination": { "page": 1, "limit": 20, "total_count": 42, "total_pages": 3 }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`GET /api/v1/customer/orders/{id}` mengembalikan field yang sama, ditambah:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"table_number": "A3",
|
||||||
|
"subtotal": 90000,
|
||||||
|
"discount_amount": 0,
|
||||||
|
"tax_amount": 9000,
|
||||||
|
"refund_amount": 0,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"product_id": "…",
|
||||||
|
"product_name": "Kopi Susu",
|
||||||
|
"variant_name": "Large",
|
||||||
|
"quantity": 2,
|
||||||
|
"unit_price": 25000,
|
||||||
|
"total_price": 50000,
|
||||||
|
"refund_quantity": 0,
|
||||||
|
"modifiers": [],
|
||||||
|
"status": "completed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "…",
|
||||||
|
"product_id": "…",
|
||||||
|
"product_name": "Ikan Tude",
|
||||||
|
"variant_name": null,
|
||||||
|
"quantity": 1,
|
||||||
|
"weight": 4.2,
|
||||||
|
"unit_name": "ons",
|
||||||
|
"unit_price": 4500,
|
||||||
|
"total_price": 18900,
|
||||||
|
"refund_quantity": 0,
|
||||||
|
"modifiers": [],
|
||||||
|
"status": "completed"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payments": [
|
||||||
|
{ "id": "…", "method_name": "EnakPoint", "method_type": "point", "amount": 12500, "status": "completed", "refund_amount": 0, "points_used": 12500, "point_value": 1, "created_at": "…" },
|
||||||
|
{ "id": "…", "method_name": "Cash", "method_type": "cash", "amount": 86500, "status": "completed", "refund_amount": 0, "created_at": "…" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Order customer lain atau yang tidak ada → `404`.
|
||||||
|
- `points_earned` / `coins_earned`: yang didapat dari order ini; 0 bila tidak ada.
|
||||||
|
- Item timbangan membawa `weight` dan `unit_name`; tampilkan "1 × 4,2 ons".
|
||||||
|
- Pembayaran EnakPoint membawa `points_used`; tampilkan "EnakPoint 12.500 (Rp 12.500)".
|
||||||
|
- Order yang `is_void` atau `is_refund` tetap tampil, beri label "Dibatalkan" /
|
||||||
|
"Direfund".
|
||||||
|
|
||||||
|
## 5. Notifikasi push (FCM)
|
||||||
|
|
||||||
|
### 5.1 Registrasi device
|
||||||
|
|
||||||
|
Setelah login berhasil **dan** setiap kali FCM memberi token baru (`onTokenRefresh`):
|
||||||
|
|
||||||
|
`PUT /api/v1/customer/devices`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "device_id": "<id unik & stabil per instalasi>", "fcm_token": "<token FCM>", "platform": "android", "app_version": "2.4.0" }
|
||||||
|
```
|
||||||
|
|
||||||
|
- `device_id` wajib, stabil untuk satu instalasi (simpan di secure storage).
|
||||||
|
- `platform`: `android`, `ios`, atau `web`.
|
||||||
|
- Saat **logout**, panggil `DELETE /api/v1/customer/devices/{device_id}` sebelum
|
||||||
|
menghapus token login, supaya HP itu tidak lagi menerima notifikasi akun ini.
|
||||||
|
|
||||||
|
Tanpa registrasi ini, customer tidak menerima push apa pun.
|
||||||
|
|
||||||
|
### 5.2 Tipe push
|
||||||
|
|
||||||
|
Semua nilai di `data` berupa string.
|
||||||
|
|
||||||
|
| `data.type` | Kapan | Isi `data` lain | Aksi saat di-tap |
|
||||||
|
| -------------------- | ---------------------------------- | -------------------------------------------------- | --------------------------------- |
|
||||||
|
| `WALLET_TRANSFER_IN` | Menerima transfer | `transaction_id`, `group_id`, `currency`, `amount` | Buka riwayat, sorot transaksi itu |
|
||||||
|
| `WALLET_EXPIRING` | Beberapa hari sebelum saldo hangus | `currency`, `amount`, `expiry_date` | Buka layar kedaluwarsa (§4.3) |
|
||||||
|
| `WALLET_EXPIRED` | Saldo baru saja hangus | `currency`, `amount` | Buka riwayat |
|
||||||
|
| `PIN_LOCKED` | PIN terkunci setelah 5 kali salah | `locked_until` (RFC3339 UTC) | Buka layar lupa PIN (§6.4) |
|
||||||
|
|
||||||
|
Saat app terbuka dan menerima push wallet, muat ulang beranda.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. PIN
|
||||||
|
|
||||||
|
### 6.1 Kapan diminta
|
||||||
|
|
||||||
|
Jangan minta PIN saat registrasi. Minta saat customer **pertama kali** melakukan aksi
|
||||||
|
yang butuh PIN. Cek dengan:
|
||||||
|
|
||||||
|
`GET /api/v1/customer/pin/status` → `{ "has_pin": false, "locked_until": null, "transfer_blocked_until": null }`
|
||||||
|
|
||||||
|
Bila `has_pin: false`, arahkan ke alur buat PIN, lalu kembali ke aksi semula.
|
||||||
|
|
||||||
|
### 6.2 Buat PIN
|
||||||
|
|
||||||
|
1. `POST /api/v1/customer/pin/otp` dengan `{ "purpose": "pin_setup" }`.
|
||||||
|
Response: `{ "purpose": "pin_setup", "otp_token": "…", "expires_at": "…" }`.
|
||||||
|
OTP dikirim ke WhatsApp customer.
|
||||||
|
2. Customer memasukkan kode OTP, lalu PIN dua kali.
|
||||||
|
3. `POST /api/v1/customer/pin` dengan
|
||||||
|
`{ "otp_token": "…", "otp_code": "123456", "pin": "482913", "confirm_pin": "482913" }`.
|
||||||
|
Response: status PIN.
|
||||||
|
|
||||||
|
Validasi di app sebelum kirim (server juga memeriksa, jawab `304`):
|
||||||
|
|
||||||
|
- Tepat 6 digit angka, dan konfirmasi sama.
|
||||||
|
- Bukan satu digit berulang (`111111`).
|
||||||
|
- Bukan berurutan naik/turun (`123456`, `654321`).
|
||||||
|
- Bukan tanggal lahir customer (`DDMMYY` atau `YYMMDD`).
|
||||||
|
|
||||||
|
Minta OTP lagi terlalu cepat → `429`: tampilkan hitung mundur.
|
||||||
|
|
||||||
|
### 6.3 Ganti PIN
|
||||||
|
|
||||||
|
`PUT /api/v1/customer/pin` dengan `{ "old_pin": "…", "pin": "…", "confirm_pin": "…" }`.
|
||||||
|
|
||||||
|
### 6.4 Lupa PIN
|
||||||
|
|
||||||
|
1. `POST /customer/pin/otp` dengan `{ "purpose": "pin_reset" }`.
|
||||||
|
2. `POST /customer/pin/reset` dengan `{ "otp_token", "otp_code", "pin", "confirm_pin" }`.
|
||||||
|
|
||||||
|
Reset juga membuka PIN yang terkunci. Setelah reset, **transfer keluar ditahan 24 jam**;
|
||||||
|
bayar dan tukar tetap bisa. Beri tahu customer hal ini di layar sukses.
|
||||||
|
|
||||||
|
### 6.5 Menangani error PIN
|
||||||
|
|
||||||
|
Semua endpoint yang menerima `pin` bisa menjawab error PIN. Pada error ini **`data`
|
||||||
|
tidak `null`**:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "success": false, "data": { "code": "PIN_INVALID", "remaining_attempts": 3 }, "errors": [ … ] }
|
||||||
|
```
|
||||||
|
|
||||||
|
| `data.code` | Field tambahan | Tampilan |
|
||||||
|
| ------------------ | ------------------------ | ---------------------------------------------------- |
|
||||||
|
| `PIN_NOT_SET` | – | Buka alur buat PIN (§6.2) |
|
||||||
|
| `PIN_INVALID` | `remaining_attempts` | "PIN salah, sisa {n} percobaan." Kosongkan input PIN |
|
||||||
|
| `PIN_LOCKED` | `locked_until` | "PIN terkunci sampai {jam}." Tombol "Lupa PIN" |
|
||||||
|
| `TRANSFER_BLOCKED` | `transfer_blocked_until` | "Transfer bisa dilakukan lagi pada {waktu}." |
|
||||||
|
|
||||||
|
5 kali salah berturut-turut mengunci PIN 30 menit; selama terkunci PIN yang benar pun
|
||||||
|
ditolak. Penghitung ada di server, jadi jangan membuat penghitung sendiri di app.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Membayar dengan EnakPoint
|
||||||
|
|
||||||
|
App customer tidak membuat atau membayar order; order hanya bisa dilihat (§4.5).
|
||||||
|
EnakPoint hanya dipakai membayar di kasir, lewat kode bayar dari app. Jangan membangun
|
||||||
|
layar checkout atau memanggil `POST /customer/orders/:id/pay-with-points`.
|
||||||
|
|
||||||
|
### 7.1 Di kasir — kode bayar
|
||||||
|
|
||||||
|
Customer tidak pernah mengetik PIN di mesin kasir. Alurnya:
|
||||||
|
|
||||||
|
1. Customer membuka "Bayar di kasir" dan memasukkan PIN.
|
||||||
|
2. `POST /api/v1/customer/wallet/payment-code` dengan `{ "pin": "482913" }`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "code": "482913", "qr_payload": "enakpoint:482913", "expires_at": "2026-09-30T05:02:00Z" }
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Tampilkan `code` besar (angka) **dan** QR dari `qr_payload` (string apa adanya).
|
||||||
|
4. Tampilkan hitung mundur ke `expires_at` (2 menit). Setelah habis, sembunyikan kode
|
||||||
|
dan tampilkan tombol "Buat kode baru".
|
||||||
|
5. Kasir memindai/mengetik kode dan memilih jumlah EnakPoint. App tidak menerima
|
||||||
|
callback; setelah customer kembali ke beranda, muat ulang saldo.
|
||||||
|
|
||||||
|
Kode sekali pakai. Membuat kode baru membatalkan kode lama.
|
||||||
|
|
||||||
|
### 7.2 Refund
|
||||||
|
|
||||||
|
Bila order yang dibayar EnakPoint dibatalkan atau direfund, EnakPoint kembali sebagai
|
||||||
|
EnakPoint (tidak pernah tunai) dan muncul di riwayat sebagai `PAYMENT_REFUND`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Tukar dan transfer
|
||||||
|
|
||||||
|
### 8.1 Tukar EnakCoin → EnakPoint
|
||||||
|
|
||||||
|
1. Customer mengetik jumlah EnakCoin. Panggil preview (debounce saat mengetik):
|
||||||
|
|
||||||
|
`GET /api/v1/customer/wallet/exchange/preview?coins=30`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "coin_amount": 10, "point_amount": 3, "coin_balance": 35, "coins": 30, "points": 9, "valid": true }
|
||||||
|
```
|
||||||
|
|
||||||
|
- Kurs: `coin_amount` EnakCoin = `point_amount` EnakPoint. Tampilkan "10 EnakCoin =
|
||||||
|
3 EnakPoint".
|
||||||
|
- Bila `valid: false`, tampilkan `reason` sebagai alasan dan nonaktifkan tombol. Jumlah
|
||||||
|
harus kelipatan `coin_amount`.
|
||||||
|
- Tampilkan "Kamu akan mendapat {points} EnakPoint".
|
||||||
|
|
||||||
|
2. Konfirmasi (tukar tidak bisa dibatalkan) → minta PIN →
|
||||||
|
|
||||||
|
`POST /api/v1/customer/wallet/exchange` + header `Idempotency-Key`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "coins": 30, "pin": "482913" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"group_id": "…",
|
||||||
|
"coins": 30,
|
||||||
|
"points": 9,
|
||||||
|
"coin_amount": 10,
|
||||||
|
"point_amount": 3,
|
||||||
|
"lots": [{ "amount": 9, "expires_at": "2026-12-31T23:59:59+07:00" }],
|
||||||
|
"coin_balance": 5,
|
||||||
|
"point_balance": 9,
|
||||||
|
"replayed": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Layar sukses: saldo baru, dan bila `lots[].expires_at` ada, "EnakPoint ini berlaku
|
||||||
|
sampai {tanggal}".
|
||||||
|
|
||||||
|
### 8.2 Transfer
|
||||||
|
|
||||||
|
1. Pilih mata uang (EnakPoint / EnakCoin), isi nomor HP penerima dan jumlah.
|
||||||
|
2. Cek penerima:
|
||||||
|
|
||||||
|
`GET /api/v1/customer/wallet/transfer/recipient?phone=081234561234`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "name": "Bu*** Sa***", "phone_number": "08**-****-1234" }
|
||||||
|
```
|
||||||
|
|
||||||
|
| Hasil | Tampilan |
|
||||||
|
| ------ | ---------------------------------------------------------------- |
|
||||||
|
| Sukses | "Kirim ke Bu*** Sa*** (08**-\*\***-1234)?" |
|
||||||
|
| `404` | "Nomor ini tidak terdaftar" |
|
||||||
|
| `304` | "Tidak bisa mengirim ke nomor ini" (diri sendiri, akun nonaktif) |
|
||||||
|
|
||||||
|
3. Konfirmasi (transfer final, tidak bisa dibatalkan) → minta PIN →
|
||||||
|
|
||||||
|
`POST /api/v1/customer/wallet/transfer` + header `Idempotency-Key`
|
||||||
|
|
||||||
|
```json
|
||||||
|
{ "currency": "POINT", "amount": 120, "recipient_phone": "081234561234", "pin": "482913" }
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"group_id": "…",
|
||||||
|
"currency": "POINT",
|
||||||
|
"amount": 120,
|
||||||
|
"recipient": { "name": "Bu*** Sa***", "phone_number": "08**-****-1234" },
|
||||||
|
"lots": [
|
||||||
|
{ "amount": 100, "expires_at": "2026-12-31T23:59:59+07:00" },
|
||||||
|
{ "amount": 20, "expires_at": null }
|
||||||
|
],
|
||||||
|
"balance": 30,
|
||||||
|
"replayed": false
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Layar sukses: saldo tersisa (`balance`). Bila ada `lots[].expires_at`, tampilkan
|
||||||
|
"Saldo yang dikirim berlaku sampai {tanggal}" (tanggal kedaluwarsa ikut terbawa ke
|
||||||
|
penerima).
|
||||||
|
|
||||||
|
Penolakan `304` yang mungkin: transfer dimatikan owner, di bawah minimal, di atas
|
||||||
|
maksimal per transaksi, melewati batas harian (reset tengah malam WIB), saldo tidak
|
||||||
|
cukup. Tampilkan pesan umum "Transfer tidak bisa diproses" plus alasan yang sesuai
|
||||||
|
bila bisa dikenali. Bila kena `TRANSFER_BLOCKED`, ikuti §6.5.
|
||||||
|
|
||||||
|
Penerima mendapat push `WALLET_TRANSFER_IN`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Game (memakai EnakCoin)
|
||||||
|
|
||||||
|
`POST /api/v1/customer/spin` dengan `{ "spin_id": "<id game>" }`. Tanpa PIN.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"game_play": { "id": "…", "game_id": "…", "coins_used": 1, "created_at": "…" },
|
||||||
|
"prize_won": { "id": "…", "name": "Voucher 10rb" },
|
||||||
|
"coins_remaining": 7
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Setiap game punya biaya sendiri: `metadata.coin_cost` pada data game dari
|
||||||
|
`GET /api/v1/customer/games` (atau `GET /customer/ferris-wheel`), default 1 bila kosong.
|
||||||
|
Tampilkan biaya sebelum main, dan nonaktifkan tombol bila `coin_balance` kurang.
|
||||||
|
- `304`: EnakCoin kurang, game nonaktif, atau hadiah baru saja habis. Tidak ada
|
||||||
|
EnakCoin yang terpotong; tampilkan pesan dan biarkan customer mencoba lagi.
|
||||||
|
- Setelah main, perbarui saldo EnakCoin dari `coins_remaining`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Yang sudah dihapus / deprecated
|
||||||
|
|
||||||
|
Sudah **dihapus** dari API (jangan dipanggil, akan error / tidak ada):
|
||||||
|
|
||||||
|
| Lama | Pengganti |
|
||||||
|
| ------------------------------------------------- | ----------------------------------------------------------------- |
|
||||||
|
| `GET /customer/tokens` | `GET /customer/wallet` → `coin_balance` |
|
||||||
|
| `total_tokens`, `tokens_history` | `coin_balance`, `GET /customer/wallet/transactions?currency=COIN` |
|
||||||
|
| `token_used`, `tokens_remaining` di response game | `coins_used`, `coins_remaining` |
|
||||||
|
|
||||||
|
Masih ada tapi **deprecated** (akan dihapus, jangan dipakai di kode baru):
|
||||||
|
|
||||||
|
| Lama | Pengganti |
|
||||||
|
| ---------------------------------------------------------------------- | ---------------------------------------- |
|
||||||
|
| `GET /customer/points` | `GET /customer/wallet` → `point_balance` |
|
||||||
|
| `total_points`, `points_history`, `last_updated` di `/customer/wallet` | `point_balance`, `recent_transactions` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Checklist selesai
|
||||||
|
|
||||||
|
- [ ] Beranda menampilkan saldo EnakPoint ("setara potongan Rp …"), EnakCoin, dan banner kedaluwarsa terdekat.
|
||||||
|
- [ ] Riwayat dengan tab per mata uang, filter tipe/tanggal, infinite scroll, label tipe sesuai §4.2.
|
||||||
|
- [ ] Layar saldo akan kedaluwarsa.
|
||||||
|
- [ ] Registrasi device FCM setelah login dan saat token berganti; unregister saat logout.
|
||||||
|
- [ ] Penanganan tap untuk keempat tipe push.
|
||||||
|
- [ ] PIN diminta hanya saat aksi yang membutuhkan; alur buat, ganti, dan lupa PIN lewat OTP.
|
||||||
|
- [ ] Keempat error PIN ditangani di semua layar yang meminta PIN.
|
||||||
|
- [ ] Kode bayar: angka + QR, hitung mundur 2 menit, tombol buat ulang.
|
||||||
|
- [ ] Tukar dengan preview, kelipatan kurs, konfirmasi, `Idempotency-Key`, retry dengan key sama.
|
||||||
|
- [ ] Transfer dengan cek penerima tersamar, konfirmasi, `Idempotency-Key`, retry dengan key sama.
|
||||||
|
- [ ] Game memakai `coins_used` / `coins_remaining` dan menampilkan biaya per game.
|
||||||
|
- [ ] Riwayat order dengan pagination dan layar detail (item, pembayaran, EnakPoint/EnakCoin yang didapat).
|
||||||
|
- [ ] Tidak ada pemakaian endpoint atau field di §10.
|
||||||
|
- [ ] PIN tidak pernah disimpan, di-log, atau dikirim ke analytics.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?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>
|
||||||
|
<!-- Ganti "app-store-connect" jika perlu: ad-hoc, enterprise, development -->
|
||||||
|
<key>method</key>
|
||||||
|
<string>app-store-connect</string>
|
||||||
|
|
||||||
|
<!-- Team ID dari Apple Developer account -->
|
||||||
|
<key>teamID</key>
|
||||||
|
<string>5TRC3M8UZG</string>
|
||||||
|
|
||||||
|
<!-- Signing style: manual (pakai provisioning profile eksplisit) -->
|
||||||
|
<key>signingStyle</key>
|
||||||
|
<string>manual</string>
|
||||||
|
|
||||||
|
<!-- Provisioning profiles: key = bundle ID, value = nama profile -->
|
||||||
|
<key>provisioningProfiles</key>
|
||||||
|
<dict>
|
||||||
|
<key>com.apskel.enaklocustomer</key>
|
||||||
|
<string>Enaklo Customer</string>
|
||||||
|
</dict>
|
||||||
|
|
||||||
|
<key>stripSwiftSymbols</key>
|
||||||
|
<true/>
|
||||||
|
|
||||||
|
<key>uploadBitcode</key>
|
||||||
|
<false/>
|
||||||
|
|
||||||
|
<key>uploadSymbols</key>
|
||||||
|
<true/>
|
||||||
|
|
||||||
|
<key>compileBitcode</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -21,6 +21,6 @@
|
|||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>MinimumOSVersion</key>
|
<key>MinimumOSVersion</key>
|
||||||
<string>12.0</string>
|
<string>15.0</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Uncomment this line to define a global platform for your project
|
# Uncomment this line to define a global platform for your project
|
||||||
# platform :ios, '12.0'
|
platform :ios, '15.0'
|
||||||
|
|
||||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
@@ -39,5 +39,12 @@ end
|
|||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
|
||||||
|
# Disable code signing for all Pod targets — only Runner needs signing
|
||||||
|
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
||||||
|
config.build_settings['CODE_SIGNING_REQUIRED'] = 'NO'
|
||||||
|
config.build_settings['CODE_SIGN_IDENTITY'] = ''
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -346,7 +346,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
@@ -368,7 +368,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -384,7 +384,7 @@
|
|||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -401,7 +401,7 @@
|
|||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||||
@@ -416,7 +416,7 @@
|
|||||||
CURRENT_PROJECT_VERSION = 1;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo.RunnerTests;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer.RunnerTests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||||
@@ -472,7 +472,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = YES;
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
@@ -523,7 +523,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTED_PLATFORMS = iphoneos;
|
SUPPORTED_PLATFORMS = iphoneos;
|
||||||
@@ -547,7 +547,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -569,7 +569,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.appskel.enaklo;
|
PRODUCT_BUNDLE_IDENTIFIER = com.apskel.enaklocustomer;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
part of 'auth_bloc.dart';
|
part of 'auth_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class AuthEvent with _$AuthEvent {
|
abstract class AuthEvent with _$AuthEvent {
|
||||||
const factory AuthEvent.fetchCurrentUser() = _FetchCurrentUser;
|
const factory AuthEvent.fetchCurrentUser() = _FetchCurrentUser;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'auth_bloc.dart';
|
part of 'auth_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class AuthState with _$AuthState {
|
abstract class AuthState with _$AuthState {
|
||||||
const AuthState._();
|
const AuthState._();
|
||||||
|
|
||||||
const factory AuthState({
|
const factory AuthState({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'check_phone_form_bloc.dart';
|
part of 'check_phone_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class CheckPhoneFormEvent with _$CheckPhoneFormEvent {
|
abstract class CheckPhoneFormEvent with _$CheckPhoneFormEvent {
|
||||||
const factory CheckPhoneFormEvent.phoneNumberChanged(String phoneNumber) =
|
const factory CheckPhoneFormEvent.phoneNumberChanged(String phoneNumber) =
|
||||||
_PhoneNumberChanged;
|
_PhoneNumberChanged;
|
||||||
const factory CheckPhoneFormEvent.submitted() = _Submitted;
|
const factory CheckPhoneFormEvent.submitted() = _Submitted;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'check_phone_form_bloc.dart';
|
part of 'check_phone_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class CheckPhoneFormState with _$CheckPhoneFormState {
|
abstract class CheckPhoneFormState with _$CheckPhoneFormState {
|
||||||
const factory CheckPhoneFormState({
|
const factory CheckPhoneFormState({
|
||||||
required String phoneNumber,
|
required String phoneNumber,
|
||||||
required Option<Either<AuthFailure, CheckPhone>> failureOrCheckPhoneOption,
|
required Option<Either<AuthFailure, CheckPhone>> failureOrCheckPhoneOption,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'login_form_bloc.dart';
|
part of 'login_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class LoginFormEvent with _$LoginFormEvent {
|
abstract class LoginFormEvent with _$LoginFormEvent {
|
||||||
const factory LoginFormEvent.phoneNumberChanged(String phoneNumber) =
|
const factory LoginFormEvent.phoneNumberChanged(String phoneNumber) =
|
||||||
_PhoneNumberChanged;
|
_PhoneNumberChanged;
|
||||||
const factory LoginFormEvent.passwordChanged(String password) =
|
const factory LoginFormEvent.passwordChanged(String password) =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'login_form_bloc.dart';
|
part of 'login_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class LoginFormState with _$LoginFormState {
|
abstract class LoginFormState with _$LoginFormState {
|
||||||
const factory LoginFormState({
|
const factory LoginFormState({
|
||||||
required String phoneNumber,
|
required String phoneNumber,
|
||||||
required String password,
|
required String password,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:freezed_annotation/freezed_annotation.dart';
|
|||||||
import 'package:injectable/injectable.dart';
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
import '../../../domain/auth/auth.dart';
|
import '../../../domain/auth/auth.dart';
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
part 'logout_form_event.dart';
|
part 'logout_form_event.dart';
|
||||||
part 'logout_form_state.dart';
|
part 'logout_form_state.dart';
|
||||||
@@ -12,8 +13,10 @@ part 'logout_form_bloc.freezed.dart';
|
|||||||
@injectable
|
@injectable
|
||||||
class LogoutFormBloc extends Bloc<LogoutFormEvent, LogoutFormState> {
|
class LogoutFormBloc extends Bloc<LogoutFormEvent, LogoutFormState> {
|
||||||
final IAuthRepository _repository;
|
final IAuthRepository _repository;
|
||||||
|
final IDeviceRepository _deviceRepository;
|
||||||
|
|
||||||
LogoutFormBloc(this._repository) : super(LogoutFormState.initial()) {
|
LogoutFormBloc(this._repository, this._deviceRepository)
|
||||||
|
: super(LogoutFormState.initial()) {
|
||||||
on<LogoutFormEvent>(_onLogoutFormEvent);
|
on<LogoutFormEvent>(_onLogoutFormEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,6 +27,9 @@ class LogoutFormBloc extends Bloc<LogoutFormEvent, LogoutFormState> {
|
|||||||
return event.map(
|
return event.map(
|
||||||
submitted: (e) async {
|
submitted: (e) async {
|
||||||
emit(state.copyWith(isSubmitting: true, failureOrAuthOption: none()));
|
emit(state.copyWith(isSubmitting: true, failureOrAuthOption: none()));
|
||||||
|
// Hapus registrasi push sebelum token login dihapus. Kegagalannya
|
||||||
|
// tidak menghalangi logout.
|
||||||
|
await _deviceRepository.unregister();
|
||||||
final failureOrAuth = await _repository.logout();
|
final failureOrAuth = await _repository.logout();
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// coverage:ignore-file
|
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
// ignore_for_file: type=lint
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
// 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, invalid_annotation_target, unnecessary_question_mark
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
part of 'logout_form_bloc.dart';
|
part of 'logout_form_bloc.dart';
|
||||||
@@ -9,327 +9,466 @@ part of 'logout_form_bloc.dart';
|
|||||||
// FreezedGenerator
|
// FreezedGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
T _$identity<T>(T value) => value;
|
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 information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
|
|
||||||
);
|
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$LogoutFormEvent {
|
mixin _$LogoutFormEvent {
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() submitted,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
@override
|
||||||
TResult? Function()? submitted,
|
bool operator ==(Object other) {
|
||||||
}) => throw _privateConstructorUsedError;
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is LogoutFormEvent);
|
||||||
@optionalTypeArgs
|
}
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? submitted,
|
|
||||||
required TResult orElse(),
|
@override
|
||||||
}) => throw _privateConstructorUsedError;
|
int get hashCode => runtimeType.hashCode;
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
@override
|
||||||
required TResult Function(_Submitted value) submitted,
|
String toString() {
|
||||||
}) => throw _privateConstructorUsedError;
|
return 'LogoutFormEvent()';
|
||||||
@optionalTypeArgs
|
}
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Submitted value)? submitted,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Submitted value)? submitted,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $LogoutFormEventCopyWith<$Res> {
|
class $LogoutFormEventCopyWith<$Res> {
|
||||||
factory $LogoutFormEventCopyWith(
|
$LogoutFormEventCopyWith(LogoutFormEvent _, $Res Function(LogoutFormEvent) __);
|
||||||
LogoutFormEvent value,
|
|
||||||
$Res Function(LogoutFormEvent) then,
|
|
||||||
) = _$LogoutFormEventCopyWithImpl<$Res, LogoutFormEvent>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$LogoutFormEventCopyWithImpl<$Res, $Val extends LogoutFormEvent>
|
|
||||||
implements $LogoutFormEventCopyWith<$Res> {
|
|
||||||
_$LogoutFormEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
/// Adds pattern-matching-related methods to [LogoutFormEvent].
|
||||||
final $Val _value;
|
extension LogoutFormEventPatterns on LogoutFormEvent {
|
||||||
// ignore: unused_field
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
final $Res Function($Val) _then;
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
/// Create a copy of LogoutFormEvent
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted();case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted();case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted();case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$SubmittedImplCopyWith<$Res> {
|
|
||||||
factory _$$SubmittedImplCopyWith(
|
|
||||||
_$SubmittedImpl value,
|
|
||||||
$Res Function(_$SubmittedImpl) then,
|
|
||||||
) = __$$SubmittedImplCopyWithImpl<$Res>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$SubmittedImplCopyWithImpl<$Res>
|
|
||||||
extends _$LogoutFormEventCopyWithImpl<$Res, _$SubmittedImpl>
|
|
||||||
implements _$$SubmittedImplCopyWith<$Res> {
|
|
||||||
__$$SubmittedImplCopyWithImpl(
|
|
||||||
_$SubmittedImpl _value,
|
|
||||||
$Res Function(_$SubmittedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$SubmittedImpl implements _Submitted {
|
|
||||||
const _$SubmittedImpl();
|
|
||||||
|
|
||||||
@override
|
class _Submitted implements LogoutFormEvent {
|
||||||
String toString() {
|
const _Submitted();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
return 'LogoutFormEvent.submitted()';
|
return 'LogoutFormEvent.submitted()';
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType && other is _$SubmittedImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => runtimeType.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() submitted,
|
|
||||||
}) {
|
|
||||||
return submitted();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? submitted,
|
|
||||||
}) {
|
|
||||||
return submitted?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? submitted,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (submitted != null) {
|
|
||||||
return submitted();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Submitted value) submitted,
|
|
||||||
}) {
|
|
||||||
return submitted(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Submitted value)? submitted,
|
|
||||||
}) {
|
|
||||||
return submitted?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Submitted value)? submitted,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (submitted != null) {
|
|
||||||
return submitted(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _Submitted implements LogoutFormEvent {
|
|
||||||
const factory _Submitted() = _$SubmittedImpl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
mixin _$LogoutFormState {
|
mixin _$LogoutFormState {
|
||||||
Option<Either<AuthFailure, Unit>> get failureOrAuthOption =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isSubmitting => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormState
|
Option<Either<AuthFailure, Unit>> get failureOrAuthOption; bool get isSubmitting;
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// Create a copy of LogoutFormState
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
$LogoutFormStateCopyWith<LogoutFormState> get copyWith =>
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
throw _privateConstructorUsedError;
|
@pragma('vm:prefer-inline')
|
||||||
|
$LogoutFormStateCopyWith<LogoutFormState> get copyWith => _$LogoutFormStateCopyWithImpl<LogoutFormState>(this as LogoutFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as LogoutFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is LogoutFormState&&(identical(other.failureOrAuthOption, _this.failureOrAuthOption) || other.failureOrAuthOption == _this.failureOrAuthOption)&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as LogoutFormState;
|
||||||
|
return Object.hash(runtimeType,_this.failureOrAuthOption,_this.isSubmitting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as LogoutFormState;
|
||||||
|
return 'LogoutFormState(failureOrAuthOption: ${_this.failureOrAuthOption}, isSubmitting: ${_this.isSubmitting})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
abstract class $LogoutFormStateCopyWith<$Res> {
|
abstract mixin class $LogoutFormStateCopyWith<$Res> {
|
||||||
factory $LogoutFormStateCopyWith(
|
factory $LogoutFormStateCopyWith(LogoutFormState value, $Res Function(LogoutFormState) _then) = _$LogoutFormStateCopyWithImpl;
|
||||||
LogoutFormState value,
|
@useResult
|
||||||
$Res Function(LogoutFormState) then,
|
$Res call({
|
||||||
) = _$LogoutFormStateCopyWithImpl<$Res, LogoutFormState>;
|
Option<Either<AuthFailure, Unit>> failureOrAuthOption, bool isSubmitting
|
||||||
@useResult
|
});
|
||||||
$Res call({
|
|
||||||
Option<Either<AuthFailure, Unit>> failureOrAuthOption,
|
|
||||||
bool isSubmitting,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
class _$LogoutFormStateCopyWithImpl<$Res, $Val extends LogoutFormState>
|
class _$LogoutFormStateCopyWithImpl<$Res>
|
||||||
implements $LogoutFormStateCopyWith<$Res> {
|
implements $LogoutFormStateCopyWith<$Res> {
|
||||||
_$LogoutFormStateCopyWithImpl(this._value, this._then);
|
_$LogoutFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
// ignore: unused_field
|
final LogoutFormState _self;
|
||||||
final $Val _value;
|
final $Res Function(LogoutFormState) _then;
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormState
|
/// Create a copy of LogoutFormState
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
@pragma('vm:prefer-inline')
|
@pragma('vm:prefer-inline') @override $Res call({Object? failureOrAuthOption = null,Object? isSubmitting = null,}) {
|
||||||
@override
|
return _then(LogoutFormState(
|
||||||
$Res call({Object? failureOrAuthOption = null, Object? isSubmitting = null}) {
|
failureOrAuthOption: null == failureOrAuthOption ? _self.failureOrAuthOption : failureOrAuthOption // ignore: cast_nullable_to_non_nullable
|
||||||
return _then(
|
as Option<Either<AuthFailure, Unit>>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
_value.copyWith(
|
as bool,
|
||||||
failureOrAuthOption: null == failureOrAuthOption
|
));
|
||||||
? _value.failureOrAuthOption
|
|
||||||
: failureOrAuthOption // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<Either<AuthFailure, Unit>>,
|
|
||||||
isSubmitting: null == isSubmitting
|
|
||||||
? _value.isSubmitting
|
|
||||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$LogoutFormStateImplCopyWith<$Res>
|
|
||||||
implements $LogoutFormStateCopyWith<$Res> {
|
|
||||||
factory _$$LogoutFormStateImplCopyWith(
|
|
||||||
_$LogoutFormStateImpl value,
|
|
||||||
$Res Function(_$LogoutFormStateImpl) then,
|
|
||||||
) = __$$LogoutFormStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
Option<Either<AuthFailure, Unit>> failureOrAuthOption,
|
|
||||||
bool isSubmitting,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$LogoutFormStateImplCopyWithImpl<$Res>
|
|
||||||
extends _$LogoutFormStateCopyWithImpl<$Res, _$LogoutFormStateImpl>
|
|
||||||
implements _$$LogoutFormStateImplCopyWith<$Res> {
|
|
||||||
__$$LogoutFormStateImplCopyWithImpl(
|
|
||||||
_$LogoutFormStateImpl _value,
|
|
||||||
$Res Function(_$LogoutFormStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormState
|
/// Adds pattern-matching-related methods to [LogoutFormState].
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
extension LogoutFormStatePatterns on LogoutFormState {
|
||||||
@pragma('vm:prefer-inline')
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
@override
|
///
|
||||||
$Res call({Object? failureOrAuthOption = null, Object? isSubmitting = null}) {
|
/// It is equivalent to doing:
|
||||||
return _then(
|
/// ```dart
|
||||||
_$LogoutFormStateImpl(
|
/// switch (sealedClass) {
|
||||||
failureOrAuthOption: null == failureOrAuthOption
|
/// case final Subclass value:
|
||||||
? _value.failureOrAuthOption
|
/// return ...;
|
||||||
: failureOrAuthOption // ignore: cast_nullable_to_non_nullable
|
/// case _:
|
||||||
as Option<Either<AuthFailure, Unit>>,
|
/// return orElse();
|
||||||
isSubmitting: null == isSubmitting
|
/// }
|
||||||
? _value.isSubmitting
|
/// ```
|
||||||
: isSubmitting // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _LogoutFormState value)? $default,{required TResult orElse(),}){
|
||||||
),
|
final _that = this;
|
||||||
);
|
switch (_that) {
|
||||||
}
|
case _LogoutFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _LogoutFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _LogoutFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _LogoutFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _LogoutFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Option<Either<AuthFailure, Unit>> failureOrAuthOption, bool isSubmitting)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _LogoutFormState() when $default != null:
|
||||||
|
return $default(_that.failureOrAuthOption,_that.isSubmitting);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Option<Either<AuthFailure, Unit>> failureOrAuthOption, bool isSubmitting) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _LogoutFormState():
|
||||||
|
return $default(_that.failureOrAuthOption,_that.isSubmitting);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Option<Either<AuthFailure, Unit>> failureOrAuthOption, bool isSubmitting)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _LogoutFormState() when $default != null:
|
||||||
|
return $default(_that.failureOrAuthOption,_that.isSubmitting);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @nodoc
|
/// @nodoc
|
||||||
|
|
||||||
class _$LogoutFormStateImpl implements _LogoutFormState {
|
|
||||||
const _$LogoutFormStateImpl({
|
|
||||||
required this.failureOrAuthOption,
|
|
||||||
this.isSubmitting = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
class _LogoutFormState implements LogoutFormState {
|
||||||
final Option<Either<AuthFailure, Unit>> failureOrAuthOption;
|
const _LogoutFormState({required this.failureOrAuthOption, this.isSubmitting = false});
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isSubmitting;
|
|
||||||
|
|
||||||
@override
|
@override final Option<Either<AuthFailure, Unit>> failureOrAuthOption;
|
||||||
String toString() {
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
|
||||||
|
/// Create a copy of LogoutFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$LogoutFormStateCopyWith<_LogoutFormState> get copyWith => __$LogoutFormStateCopyWithImpl<_LogoutFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LogoutFormState&&(identical(other.failureOrAuthOption, failureOrAuthOption) || other.failureOrAuthOption == failureOrAuthOption)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,failureOrAuthOption,isSubmitting);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
return 'LogoutFormState(failureOrAuthOption: $failureOrAuthOption, isSubmitting: $isSubmitting)';
|
return 'LogoutFormState(failureOrAuthOption: $failureOrAuthOption, isSubmitting: $isSubmitting)';
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$LogoutFormStateImpl &&
|
|
||||||
(identical(other.failureOrAuthOption, failureOrAuthOption) ||
|
|
||||||
other.failureOrAuthOption == failureOrAuthOption) &&
|
|
||||||
(identical(other.isSubmitting, isSubmitting) ||
|
|
||||||
other.isSubmitting == isSubmitting));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode =>
|
|
||||||
Object.hash(runtimeType, failureOrAuthOption, isSubmitting);
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$LogoutFormStateImplCopyWith<_$LogoutFormStateImpl> get copyWith =>
|
|
||||||
__$$LogoutFormStateImplCopyWithImpl<_$LogoutFormStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class _LogoutFormState implements LogoutFormState {
|
|
||||||
const factory _LogoutFormState({
|
|
||||||
required final Option<Either<AuthFailure, Unit>> failureOrAuthOption,
|
|
||||||
final bool isSubmitting,
|
|
||||||
}) = _$LogoutFormStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Option<Either<AuthFailure, Unit>> get failureOrAuthOption;
|
|
||||||
@override
|
|
||||||
bool get isSubmitting;
|
|
||||||
|
|
||||||
/// Create a copy of LogoutFormState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$LogoutFormStateImplCopyWith<_$LogoutFormStateImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$LogoutFormStateCopyWith<$Res> implements $LogoutFormStateCopyWith<$Res> {
|
||||||
|
factory _$LogoutFormStateCopyWith(_LogoutFormState value, $Res Function(_LogoutFormState) _then) = __$LogoutFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
Option<Either<AuthFailure, Unit>> failureOrAuthOption, bool isSubmitting
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$LogoutFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$LogoutFormStateCopyWith<$Res> {
|
||||||
|
__$LogoutFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _LogoutFormState _self;
|
||||||
|
final $Res Function(_LogoutFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LogoutFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? failureOrAuthOption = null,Object? isSubmitting = null,}) {
|
||||||
|
return _then(_LogoutFormState(
|
||||||
|
failureOrAuthOption: null == failureOrAuthOption ? _self.failureOrAuthOption : failureOrAuthOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<Either<AuthFailure, Unit>>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
part of 'logout_form_bloc.dart';
|
part of 'logout_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class LogoutFormEvent with _$LogoutFormEvent {
|
abstract class LogoutFormEvent with _$LogoutFormEvent {
|
||||||
const factory LogoutFormEvent.submitted() = _Submitted;
|
const factory LogoutFormEvent.submitted() = _Submitted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'logout_form_bloc.dart';
|
part of 'logout_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class LogoutFormState with _$LogoutFormState {
|
abstract class LogoutFormState with _$LogoutFormState {
|
||||||
const factory LogoutFormState({
|
const factory LogoutFormState({
|
||||||
required Option<Either<AuthFailure, Unit>> failureOrAuthOption,
|
required Option<Either<AuthFailure, Unit>> failureOrAuthOption,
|
||||||
@Default(false) bool isSubmitting,
|
@Default(false) bool isSubmitting,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'register_form_bloc.dart';
|
part of 'register_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class RegisterFormEvent with _$RegisterFormEvent {
|
abstract class RegisterFormEvent with _$RegisterFormEvent {
|
||||||
const factory RegisterFormEvent.phoneNumberChanged(String phoneNumber) =
|
const factory RegisterFormEvent.phoneNumberChanged(String phoneNumber) =
|
||||||
_PhoneNumberChanged;
|
_PhoneNumberChanged;
|
||||||
const factory RegisterFormEvent.nameChanged(String name) = _NameChanged;
|
const factory RegisterFormEvent.nameChanged(String name) = _NameChanged;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'register_form_bloc.dart';
|
part of 'register_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class RegisterFormState with _$RegisterFormState {
|
abstract class RegisterFormState with _$RegisterFormState {
|
||||||
const factory RegisterFormState({
|
const factory RegisterFormState({
|
||||||
required String phoneNumber,
|
required String phoneNumber,
|
||||||
required String name,
|
required String name,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'resend_form_bloc.dart';
|
part of 'resend_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ResendFormEvent with _$ResendFormEvent {
|
abstract class ResendFormEvent with _$ResendFormEvent {
|
||||||
const factory ResendFormEvent.phoneNumberChanged(String phoneNumber) =
|
const factory ResendFormEvent.phoneNumberChanged(String phoneNumber) =
|
||||||
_PhoneNumberChanged;
|
_PhoneNumberChanged;
|
||||||
const factory ResendFormEvent.purposeChanged(String purpose) =
|
const factory ResendFormEvent.purposeChanged(String purpose) =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'resend_form_bloc.dart';
|
part of 'resend_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class ResendFormState with _$ResendFormState {
|
abstract class ResendFormState with _$ResendFormState {
|
||||||
const factory ResendFormState({
|
const factory ResendFormState({
|
||||||
required String phoneNumber,
|
required String phoneNumber,
|
||||||
required String purpose,
|
required String purpose,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'set_password_form_bloc.dart';
|
part of 'set_password_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class SetPasswordFormEvent with _$SetPasswordFormEvent {
|
abstract class SetPasswordFormEvent with _$SetPasswordFormEvent {
|
||||||
const factory SetPasswordFormEvent.registrationTokenChanged(
|
const factory SetPasswordFormEvent.registrationTokenChanged(
|
||||||
String registrationToken,
|
String registrationToken,
|
||||||
) = _RegistrationTokenChanged;
|
) = _RegistrationTokenChanged;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'set_password_form_bloc.dart';
|
part of 'set_password_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class SetPasswordFormState with _$SetPasswordFormState {
|
abstract class SetPasswordFormState with _$SetPasswordFormState {
|
||||||
const factory SetPasswordFormState({
|
const factory SetPasswordFormState({
|
||||||
required String registrationToken,
|
required String registrationToken,
|
||||||
required String password,
|
required String password,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'verify_form_bloc.dart';
|
part of 'verify_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class VerifyFormEvent with _$VerifyFormEvent {
|
abstract class VerifyFormEvent with _$VerifyFormEvent {
|
||||||
const factory VerifyFormEvent.registrationTokenChanged(
|
const factory VerifyFormEvent.registrationTokenChanged(
|
||||||
String registrationToken,
|
String registrationToken,
|
||||||
) = _RegistrationTokenChanged;
|
) = _RegistrationTokenChanged;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
part of 'verify_form_bloc.dart';
|
part of 'verify_form_bloc.dart';
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
class VerifyFormState with _$VerifyFormState {
|
abstract class VerifyFormState with _$VerifyFormState {
|
||||||
const factory VerifyFormState({
|
const factory VerifyFormState({
|
||||||
required String registrationToken,
|
required String registrationToken,
|
||||||
required String otpCode,
|
required String otpCode,
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/customer/customer.dart';
|
|
||||||
|
|
||||||
part 'customer_point_loader_event.dart';
|
|
||||||
part 'customer_point_loader_state.dart';
|
|
||||||
part 'customer_point_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class CustomerPointLoaderBloc
|
|
||||||
extends Bloc<CustomerPointLoaderEvent, CustomerPointLoaderState> {
|
|
||||||
final ICustomerRepository _repository;
|
|
||||||
CustomerPointLoaderBloc(this._repository)
|
|
||||||
: super(CustomerPointLoaderState.initial()) {
|
|
||||||
on<CustomerPointLoaderEvent>(_onCustomerPointLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onCustomerPointLoaderEvent(
|
|
||||||
CustomerPointLoaderEvent event,
|
|
||||||
Emitter<CustomerPointLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
fetched: (e) async {
|
|
||||||
emit(
|
|
||||||
state.copyWith(isFetching: true, failureOptionCustomerPoint: none()),
|
|
||||||
);
|
|
||||||
|
|
||||||
final result = await _repository.getPoints();
|
|
||||||
|
|
||||||
var data = result.fold(
|
|
||||||
(f) => state.copyWith(failureOptionCustomerPoint: optionOf(f)),
|
|
||||||
(customerPoint) => state.copyWith(customerPoint: customerPoint),
|
|
||||||
);
|
|
||||||
|
|
||||||
emit(data.copyWith(isFetching: false));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
// coverage:ignore-file
|
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
// 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, invalid_annotation_target, unnecessary_question_mark
|
|
||||||
|
|
||||||
part of 'customer_point_loader_bloc.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 information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
|
|
||||||
);
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CustomerPointLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CustomerPointLoaderEventCopyWith<$Res> {
|
|
||||||
factory $CustomerPointLoaderEventCopyWith(
|
|
||||||
CustomerPointLoaderEvent value,
|
|
||||||
$Res Function(CustomerPointLoaderEvent) then,
|
|
||||||
) = _$CustomerPointLoaderEventCopyWithImpl<$Res, CustomerPointLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CustomerPointLoaderEventCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends CustomerPointLoaderEvent
|
|
||||||
>
|
|
||||||
implements $CustomerPointLoaderEventCopyWith<$Res> {
|
|
||||||
_$CustomerPointLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$FetchedImplCopyWith<$Res> {
|
|
||||||
factory _$$FetchedImplCopyWith(
|
|
||||||
_$FetchedImpl value,
|
|
||||||
$Res Function(_$FetchedImpl) then,
|
|
||||||
) = __$$FetchedImplCopyWithImpl<$Res>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$FetchedImplCopyWithImpl<$Res>
|
|
||||||
extends _$CustomerPointLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CustomerPointLoaderEvent.fetched()';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType && other is _$FetchedImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => runtimeType.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({required TResult Function() fetched}) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
|
|
||||||
return fetched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements CustomerPointLoaderEvent {
|
|
||||||
const factory _Fetched() = _$FetchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$CustomerPointLoaderState {
|
|
||||||
CustomerPoint get customerPoint => throw _privateConstructorUsedError;
|
|
||||||
Option<CustomerFailure> get failureOptionCustomerPoint =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$CustomerPointLoaderStateCopyWith<CustomerPointLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $CustomerPointLoaderStateCopyWith<$Res> {
|
|
||||||
factory $CustomerPointLoaderStateCopyWith(
|
|
||||||
CustomerPointLoaderState value,
|
|
||||||
$Res Function(CustomerPointLoaderState) then,
|
|
||||||
) = _$CustomerPointLoaderStateCopyWithImpl<$Res, CustomerPointLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
CustomerPoint customerPoint,
|
|
||||||
Option<CustomerFailure> failureOptionCustomerPoint,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
$CustomerPointCopyWith<$Res> get customerPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$CustomerPointLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends CustomerPointLoaderState
|
|
||||||
>
|
|
||||||
implements $CustomerPointLoaderStateCopyWith<$Res> {
|
|
||||||
_$CustomerPointLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? customerPoint = null,
|
|
||||||
Object? failureOptionCustomerPoint = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
customerPoint: null == customerPoint
|
|
||||||
? _value.customerPoint
|
|
||||||
: customerPoint // ignore: cast_nullable_to_non_nullable
|
|
||||||
as CustomerPoint,
|
|
||||||
failureOptionCustomerPoint: null == failureOptionCustomerPoint
|
|
||||||
? _value.failureOptionCustomerPoint
|
|
||||||
: failureOptionCustomerPoint // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<CustomerFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$CustomerPointCopyWith<$Res> get customerPoint {
|
|
||||||
return $CustomerPointCopyWith<$Res>(_value.customerPoint, (value) {
|
|
||||||
return _then(_value.copyWith(customerPoint: value) as $Val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$CustomerPointLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $CustomerPointLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$CustomerPointLoaderStateImplCopyWith(
|
|
||||||
_$CustomerPointLoaderStateImpl value,
|
|
||||||
$Res Function(_$CustomerPointLoaderStateImpl) then,
|
|
||||||
) = __$$CustomerPointLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
CustomerPoint customerPoint,
|
|
||||||
Option<CustomerFailure> failureOptionCustomerPoint,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
$CustomerPointCopyWith<$Res> get customerPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$CustomerPointLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends
|
|
||||||
_$CustomerPointLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
_$CustomerPointLoaderStateImpl
|
|
||||||
>
|
|
||||||
implements _$$CustomerPointLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$CustomerPointLoaderStateImplCopyWithImpl(
|
|
||||||
_$CustomerPointLoaderStateImpl _value,
|
|
||||||
$Res Function(_$CustomerPointLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? customerPoint = null,
|
|
||||||
Object? failureOptionCustomerPoint = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$CustomerPointLoaderStateImpl(
|
|
||||||
customerPoint: null == customerPoint
|
|
||||||
? _value.customerPoint
|
|
||||||
: customerPoint // ignore: cast_nullable_to_non_nullable
|
|
||||||
as CustomerPoint,
|
|
||||||
failureOptionCustomerPoint: null == failureOptionCustomerPoint
|
|
||||||
? _value.failureOptionCustomerPoint
|
|
||||||
: failureOptionCustomerPoint // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<CustomerFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$CustomerPointLoaderStateImpl implements _CustomerPointLoaderState {
|
|
||||||
const _$CustomerPointLoaderStateImpl({
|
|
||||||
required this.customerPoint,
|
|
||||||
required this.failureOptionCustomerPoint,
|
|
||||||
this.isFetching = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
final CustomerPoint customerPoint;
|
|
||||||
@override
|
|
||||||
final Option<CustomerFailure> failureOptionCustomerPoint;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'CustomerPointLoaderState(customerPoint: $customerPoint, failureOptionCustomerPoint: $failureOptionCustomerPoint, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$CustomerPointLoaderStateImpl &&
|
|
||||||
(identical(other.customerPoint, customerPoint) ||
|
|
||||||
other.customerPoint == customerPoint) &&
|
|
||||||
(identical(
|
|
||||||
other.failureOptionCustomerPoint,
|
|
||||||
failureOptionCustomerPoint,
|
|
||||||
) ||
|
|
||||||
other.failureOptionCustomerPoint ==
|
|
||||||
failureOptionCustomerPoint) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
customerPoint,
|
|
||||||
failureOptionCustomerPoint,
|
|
||||||
isFetching,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$CustomerPointLoaderStateImplCopyWith<_$CustomerPointLoaderStateImpl>
|
|
||||||
get copyWith =>
|
|
||||||
__$$CustomerPointLoaderStateImplCopyWithImpl<
|
|
||||||
_$CustomerPointLoaderStateImpl
|
|
||||||
>(this, _$identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _CustomerPointLoaderState implements CustomerPointLoaderState {
|
|
||||||
const factory _CustomerPointLoaderState({
|
|
||||||
required final CustomerPoint customerPoint,
|
|
||||||
required final Option<CustomerFailure> failureOptionCustomerPoint,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$CustomerPointLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
CustomerPoint get customerPoint;
|
|
||||||
@override
|
|
||||||
Option<CustomerFailure> get failureOptionCustomerPoint;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of CustomerPointLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$CustomerPointLoaderStateImplCopyWith<_$CustomerPointLoaderStateImpl>
|
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
part of 'customer_point_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CustomerPointLoaderEvent with _$CustomerPointLoaderEvent {
|
|
||||||
const factory CustomerPointLoaderEvent.fetched() = _Fetched;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
part of 'customer_point_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class CustomerPointLoaderState with _$CustomerPointLoaderState {
|
|
||||||
const factory CustomerPointLoaderState({
|
|
||||||
required CustomerPoint customerPoint,
|
|
||||||
required Option<CustomerFailure> failureOptionCustomerPoint,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _CustomerPointLoaderState;
|
|
||||||
|
|
||||||
factory CustomerPointLoaderState.initial() => CustomerPointLoaderState(
|
|
||||||
customerPoint: CustomerPoint.empty(),
|
|
||||||
failureOptionCustomerPoint: none(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
|
||||||
import 'package:dartz/dartz.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:injectable/injectable.dart';
|
|
||||||
|
|
||||||
import '../../../domain/game/game.dart';
|
|
||||||
|
|
||||||
part 'ferris_wheel_loader_event.dart';
|
|
||||||
part 'ferris_wheel_loader_state.dart';
|
|
||||||
part 'ferris_wheel_loader_bloc.freezed.dart';
|
|
||||||
|
|
||||||
@injectable
|
|
||||||
class FerrisWheelLoaderBloc
|
|
||||||
extends Bloc<FerrisWheelLoaderEvent, FerrisWheelLoaderState> {
|
|
||||||
final IGameRepository _repository;
|
|
||||||
FerrisWheelLoaderBloc(this._repository)
|
|
||||||
: super(FerrisWheelLoaderState.initial()) {
|
|
||||||
on<FerrisWheelLoaderEvent>(_onFerrisWheelLoaderEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _onFerrisWheelLoaderEvent(
|
|
||||||
FerrisWheelLoaderEvent event,
|
|
||||||
Emitter<FerrisWheelLoaderState> emit,
|
|
||||||
) {
|
|
||||||
return event.map(
|
|
||||||
fetched: (e) async {
|
|
||||||
emit(
|
|
||||||
state.copyWith(isFetching: true, failureOptionFerrisWheel: none()),
|
|
||||||
);
|
|
||||||
|
|
||||||
final result = await _repository.ferrisWheel();
|
|
||||||
|
|
||||||
var data = result.fold(
|
|
||||||
(f) => state.copyWith(failureOptionFerrisWheel: optionOf(f)),
|
|
||||||
(ferrisWheel) => state.copyWith(ferrisWheel: ferrisWheel),
|
|
||||||
);
|
|
||||||
|
|
||||||
emit(data.copyWith(isFetching: false));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,388 +0,0 @@
|
|||||||
// coverage:ignore-file
|
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
// 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, invalid_annotation_target, unnecessary_question_mark
|
|
||||||
|
|
||||||
part of 'ferris_wheel_loader_bloc.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 information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
|
|
||||||
);
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$FerrisWheelLoaderEvent {
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({
|
|
||||||
required TResult Function() fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function()? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $FerrisWheelLoaderEventCopyWith<$Res> {
|
|
||||||
factory $FerrisWheelLoaderEventCopyWith(
|
|
||||||
FerrisWheelLoaderEvent value,
|
|
||||||
$Res Function(FerrisWheelLoaderEvent) then,
|
|
||||||
) = _$FerrisWheelLoaderEventCopyWithImpl<$Res, FerrisWheelLoaderEvent>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$FerrisWheelLoaderEventCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends FerrisWheelLoaderEvent
|
|
||||||
>
|
|
||||||
implements $FerrisWheelLoaderEventCopyWith<$Res> {
|
|
||||||
_$FerrisWheelLoaderEventCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$FetchedImplCopyWith<$Res> {
|
|
||||||
factory _$$FetchedImplCopyWith(
|
|
||||||
_$FetchedImpl value,
|
|
||||||
$Res Function(_$FetchedImpl) then,
|
|
||||||
) = __$$FetchedImplCopyWithImpl<$Res>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$FetchedImplCopyWithImpl<$Res>
|
|
||||||
extends _$FerrisWheelLoaderEventCopyWithImpl<$Res, _$FetchedImpl>
|
|
||||||
implements _$$FetchedImplCopyWith<$Res> {
|
|
||||||
__$$FetchedImplCopyWithImpl(
|
|
||||||
_$FetchedImpl _value,
|
|
||||||
$Res Function(_$FetchedImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderEvent
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FetchedImpl implements _Fetched {
|
|
||||||
const _$FetchedImpl();
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'FerrisWheelLoaderEvent.fetched()';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType && other is _$FetchedImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => runtimeType.hashCode;
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult when<TResult extends Object?>({required TResult Function() fetched}) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched}) {
|
|
||||||
return fetched?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeWhen<TResult extends Object?>({
|
|
||||||
TResult Function()? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched();
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult map<TResult extends Object?>({
|
|
||||||
required TResult Function(_Fetched value) fetched,
|
|
||||||
}) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult? mapOrNull<TResult extends Object?>({
|
|
||||||
TResult? Function(_Fetched value)? fetched,
|
|
||||||
}) {
|
|
||||||
return fetched?.call(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
@optionalTypeArgs
|
|
||||||
TResult maybeMap<TResult extends Object?>({
|
|
||||||
TResult Function(_Fetched value)? fetched,
|
|
||||||
required TResult orElse(),
|
|
||||||
}) {
|
|
||||||
if (fetched != null) {
|
|
||||||
return fetched(this);
|
|
||||||
}
|
|
||||||
return orElse();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _Fetched implements FerrisWheelLoaderEvent {
|
|
||||||
const factory _Fetched() = _$FetchedImpl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$FerrisWheelLoaderState {
|
|
||||||
Game get ferrisWheel => throw _privateConstructorUsedError;
|
|
||||||
Option<GameFailure> get failureOptionFerrisWheel =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
bool get isFetching => throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
$FerrisWheelLoaderStateCopyWith<FerrisWheelLoaderState> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $FerrisWheelLoaderStateCopyWith<$Res> {
|
|
||||||
factory $FerrisWheelLoaderStateCopyWith(
|
|
||||||
FerrisWheelLoaderState value,
|
|
||||||
$Res Function(FerrisWheelLoaderState) then,
|
|
||||||
) = _$FerrisWheelLoaderStateCopyWithImpl<$Res, FerrisWheelLoaderState>;
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
Game ferrisWheel,
|
|
||||||
Option<GameFailure> failureOptionFerrisWheel,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
$GameCopyWith<$Res> get ferrisWheel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$FerrisWheelLoaderStateCopyWithImpl<
|
|
||||||
$Res,
|
|
||||||
$Val extends FerrisWheelLoaderState
|
|
||||||
>
|
|
||||||
implements $FerrisWheelLoaderStateCopyWith<$Res> {
|
|
||||||
_$FerrisWheelLoaderStateCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? ferrisWheel = null,
|
|
||||||
Object? failureOptionFerrisWheel = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_value.copyWith(
|
|
||||||
ferrisWheel: null == ferrisWheel
|
|
||||||
? _value.ferrisWheel
|
|
||||||
: ferrisWheel // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Game,
|
|
||||||
failureOptionFerrisWheel: null == failureOptionFerrisWheel
|
|
||||||
? _value.failureOptionFerrisWheel
|
|
||||||
: failureOptionFerrisWheel // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<GameFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
)
|
|
||||||
as $Val,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
$GameCopyWith<$Res> get ferrisWheel {
|
|
||||||
return $GameCopyWith<$Res>(_value.ferrisWheel, (value) {
|
|
||||||
return _then(_value.copyWith(ferrisWheel: value) as $Val);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$FerrisWheelLoaderStateImplCopyWith<$Res>
|
|
||||||
implements $FerrisWheelLoaderStateCopyWith<$Res> {
|
|
||||||
factory _$$FerrisWheelLoaderStateImplCopyWith(
|
|
||||||
_$FerrisWheelLoaderStateImpl value,
|
|
||||||
$Res Function(_$FerrisWheelLoaderStateImpl) then,
|
|
||||||
) = __$$FerrisWheelLoaderStateImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call({
|
|
||||||
Game ferrisWheel,
|
|
||||||
Option<GameFailure> failureOptionFerrisWheel,
|
|
||||||
bool isFetching,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
$GameCopyWith<$Res> get ferrisWheel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$FerrisWheelLoaderStateImplCopyWithImpl<$Res>
|
|
||||||
extends
|
|
||||||
_$FerrisWheelLoaderStateCopyWithImpl<$Res, _$FerrisWheelLoaderStateImpl>
|
|
||||||
implements _$$FerrisWheelLoaderStateImplCopyWith<$Res> {
|
|
||||||
__$$FerrisWheelLoaderStateImplCopyWithImpl(
|
|
||||||
_$FerrisWheelLoaderStateImpl _value,
|
|
||||||
$Res Function(_$FerrisWheelLoaderStateImpl) _then,
|
|
||||||
) : super(_value, _then);
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? ferrisWheel = null,
|
|
||||||
Object? failureOptionFerrisWheel = null,
|
|
||||||
Object? isFetching = null,
|
|
||||||
}) {
|
|
||||||
return _then(
|
|
||||||
_$FerrisWheelLoaderStateImpl(
|
|
||||||
ferrisWheel: null == ferrisWheel
|
|
||||||
? _value.ferrisWheel
|
|
||||||
: ferrisWheel // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Game,
|
|
||||||
failureOptionFerrisWheel: null == failureOptionFerrisWheel
|
|
||||||
? _value.failureOptionFerrisWheel
|
|
||||||
: failureOptionFerrisWheel // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Option<GameFailure>,
|
|
||||||
isFetching: null == isFetching
|
|
||||||
? _value.isFetching
|
|
||||||
: isFetching // ignore: cast_nullable_to_non_nullable
|
|
||||||
as bool,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
|
|
||||||
class _$FerrisWheelLoaderStateImpl implements _FerrisWheelLoaderState {
|
|
||||||
const _$FerrisWheelLoaderStateImpl({
|
|
||||||
required this.ferrisWheel,
|
|
||||||
required this.failureOptionFerrisWheel,
|
|
||||||
this.isFetching = false,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
final Game ferrisWheel;
|
|
||||||
@override
|
|
||||||
final Option<GameFailure> failureOptionFerrisWheel;
|
|
||||||
@override
|
|
||||||
@JsonKey()
|
|
||||||
final bool isFetching;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'FerrisWheelLoaderState(ferrisWheel: $ferrisWheel, failureOptionFerrisWheel: $failureOptionFerrisWheel, isFetching: $isFetching)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$FerrisWheelLoaderStateImpl &&
|
|
||||||
(identical(other.ferrisWheel, ferrisWheel) ||
|
|
||||||
other.ferrisWheel == ferrisWheel) &&
|
|
||||||
(identical(
|
|
||||||
other.failureOptionFerrisWheel,
|
|
||||||
failureOptionFerrisWheel,
|
|
||||||
) ||
|
|
||||||
other.failureOptionFerrisWheel == failureOptionFerrisWheel) &&
|
|
||||||
(identical(other.isFetching, isFetching) ||
|
|
||||||
other.isFetching == isFetching));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(
|
|
||||||
runtimeType,
|
|
||||||
ferrisWheel,
|
|
||||||
failureOptionFerrisWheel,
|
|
||||||
isFetching,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$FerrisWheelLoaderStateImplCopyWith<_$FerrisWheelLoaderStateImpl>
|
|
||||||
get copyWith =>
|
|
||||||
__$$FerrisWheelLoaderStateImplCopyWithImpl<_$FerrisWheelLoaderStateImpl>(
|
|
||||||
this,
|
|
||||||
_$identity,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _FerrisWheelLoaderState implements FerrisWheelLoaderState {
|
|
||||||
const factory _FerrisWheelLoaderState({
|
|
||||||
required final Game ferrisWheel,
|
|
||||||
required final Option<GameFailure> failureOptionFerrisWheel,
|
|
||||||
final bool isFetching,
|
|
||||||
}) = _$FerrisWheelLoaderStateImpl;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Game get ferrisWheel;
|
|
||||||
@override
|
|
||||||
Option<GameFailure> get failureOptionFerrisWheel;
|
|
||||||
@override
|
|
||||||
bool get isFetching;
|
|
||||||
|
|
||||||
/// Create a copy of FerrisWheelLoaderState
|
|
||||||
/// with the given fields replaced by the non-null parameter values.
|
|
||||||
@override
|
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
|
||||||
_$$FerrisWheelLoaderStateImplCopyWith<_$FerrisWheelLoaderStateImpl>
|
|
||||||
get copyWith => throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
part of 'ferris_wheel_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class FerrisWheelLoaderEvent with _$FerrisWheelLoaderEvent {
|
|
||||||
const factory FerrisWheelLoaderEvent.fetched() = _Fetched;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
part of 'ferris_wheel_loader_bloc.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class FerrisWheelLoaderState with _$FerrisWheelLoaderState {
|
|
||||||
const factory FerrisWheelLoaderState({
|
|
||||||
required Game ferrisWheel,
|
|
||||||
required Option<GameFailure> failureOptionFerrisWheel,
|
|
||||||
@Default(false) bool isFetching,
|
|
||||||
}) = _FerrisWheelLoaderState;
|
|
||||||
|
|
||||||
factory FerrisWheelLoaderState.initial() => FerrisWheelLoaderState(
|
|
||||||
ferrisWheel: Game.empty(),
|
|
||||||
failureOptionFerrisWheel: none(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'order_detail_loader_event.dart';
|
||||||
|
part 'order_detail_loader_state.dart';
|
||||||
|
part 'order_detail_loader_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class OrderDetailLoaderBloc
|
||||||
|
extends Bloc<OrderDetailLoaderEvent, OrderDetailLoaderState> {
|
||||||
|
final IOrderRepository _repository;
|
||||||
|
|
||||||
|
OrderDetailLoaderBloc(this._repository)
|
||||||
|
: super(OrderDetailLoaderState.initial()) {
|
||||||
|
on<OrderDetailLoaderEvent>(_onOrderDetailLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onOrderDetailLoaderEvent(
|
||||||
|
OrderDetailLoaderEvent event,
|
||||||
|
Emitter<OrderDetailLoaderState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
fetched: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getOrderDetail(e.orderId);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(detail) => state.copyWith(detailOption: some(detail)),
|
||||||
|
)
|
||||||
|
.copyWith(isFetching: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,549 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'order_detail_loader_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OrderDetailLoaderEvent {
|
||||||
|
|
||||||
|
String get orderId;
|
||||||
|
/// Create a copy of OrderDetailLoaderEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$OrderDetailLoaderEventCopyWith<OrderDetailLoaderEvent> get copyWith => _$OrderDetailLoaderEventCopyWithImpl<OrderDetailLoaderEvent>(this as OrderDetailLoaderEvent, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as OrderDetailLoaderEvent;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OrderDetailLoaderEvent&&(identical(other.orderId, _this.orderId) || other.orderId == _this.orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as OrderDetailLoaderEvent;
|
||||||
|
return Object.hash(runtimeType,_this.orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as OrderDetailLoaderEvent;
|
||||||
|
return 'OrderDetailLoaderEvent(orderId: ${_this.orderId})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $OrderDetailLoaderEventCopyWith<$Res> {
|
||||||
|
factory $OrderDetailLoaderEventCopyWith(OrderDetailLoaderEvent value, $Res Function(OrderDetailLoaderEvent) _then) = _$OrderDetailLoaderEventCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String orderId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$OrderDetailLoaderEventCopyWithImpl<$Res>
|
||||||
|
implements $OrderDetailLoaderEventCopyWith<$Res> {
|
||||||
|
_$OrderDetailLoaderEventCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final OrderDetailLoaderEvent _self;
|
||||||
|
final $Res Function(OrderDetailLoaderEvent) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? orderId = null,}) {
|
||||||
|
return _then(OrderDetailLoaderEvent.fetched(
|
||||||
|
null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OrderDetailLoaderEvent].
|
||||||
|
extension OrderDetailLoaderEventPatterns on OrderDetailLoaderEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Fetched value)? fetched,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Fetched value) fetched,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Fetched value)? fetched,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String orderId)? fetched,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that.orderId);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String orderId) fetched,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched(_that.orderId);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String orderId)? fetched,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that.orderId);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Fetched implements OrderDetailLoaderEvent {
|
||||||
|
const _Fetched(this.orderId);
|
||||||
|
|
||||||
|
|
||||||
|
@override final String orderId;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$FetchedCopyWith<_Fetched> get copyWith => __$FetchedCopyWithImpl<_Fetched>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Fetched&&(identical(other.orderId, orderId) || other.orderId == orderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderDetailLoaderEvent.fetched(orderId: $orderId)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$FetchedCopyWith<$Res> implements $OrderDetailLoaderEventCopyWith<$Res> {
|
||||||
|
factory _$FetchedCopyWith(_Fetched value, $Res Function(_Fetched) _then) = __$FetchedCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String orderId
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$FetchedCopyWithImpl<$Res>
|
||||||
|
implements _$FetchedCopyWith<$Res> {
|
||||||
|
__$FetchedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Fetched _self;
|
||||||
|
final $Res Function(_Fetched) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? orderId = null,}) {
|
||||||
|
return _then(_Fetched(
|
||||||
|
null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OrderDetailLoaderState {
|
||||||
|
|
||||||
|
Option<CustomerOrderDetail> get detailOption; Option<WalletFailure> get failureOption; bool get isFetching;
|
||||||
|
/// Create a copy of OrderDetailLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$OrderDetailLoaderStateCopyWith<OrderDetailLoaderState> get copyWith => _$OrderDetailLoaderStateCopyWithImpl<OrderDetailLoaderState>(this as OrderDetailLoaderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as OrderDetailLoaderState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OrderDetailLoaderState&&(identical(other.detailOption, _this.detailOption) || other.detailOption == _this.detailOption)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isFetching, _this.isFetching) || other.isFetching == _this.isFetching));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as OrderDetailLoaderState;
|
||||||
|
return Object.hash(runtimeType,_this.detailOption,_this.failureOption,_this.isFetching);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as OrderDetailLoaderState;
|
||||||
|
return 'OrderDetailLoaderState(detailOption: ${_this.detailOption}, failureOption: ${_this.failureOption}, isFetching: ${_this.isFetching})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $OrderDetailLoaderStateCopyWith<$Res> {
|
||||||
|
factory $OrderDetailLoaderStateCopyWith(OrderDetailLoaderState value, $Res Function(OrderDetailLoaderState) _then) = _$OrderDetailLoaderStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
Option<CustomerOrderDetail> detailOption, Option<WalletFailure> failureOption, bool isFetching
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$OrderDetailLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements $OrderDetailLoaderStateCopyWith<$Res> {
|
||||||
|
_$OrderDetailLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final OrderDetailLoaderState _self;
|
||||||
|
final $Res Function(OrderDetailLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? detailOption = null,Object? failureOption = null,Object? isFetching = null,}) {
|
||||||
|
return _then(OrderDetailLoaderState(
|
||||||
|
detailOption: null == detailOption ? _self.detailOption : detailOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<CustomerOrderDetail>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OrderDetailLoaderState].
|
||||||
|
extension OrderDetailLoaderStatePatterns on OrderDetailLoaderState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _OrderDetailLoaderState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _OrderDetailLoaderState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _OrderDetailLoaderState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( Option<CustomerOrderDetail> detailOption, Option<WalletFailure> failureOption, bool isFetching)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState() when $default != null:
|
||||||
|
return $default(_that.detailOption,_that.failureOption,_that.isFetching);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( Option<CustomerOrderDetail> detailOption, Option<WalletFailure> failureOption, bool isFetching) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState():
|
||||||
|
return $default(_that.detailOption,_that.failureOption,_that.isFetching);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( Option<CustomerOrderDetail> detailOption, Option<WalletFailure> failureOption, bool isFetching)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderDetailLoaderState() when $default != null:
|
||||||
|
return $default(_that.detailOption,_that.failureOption,_that.isFetching);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _OrderDetailLoaderState implements OrderDetailLoaderState {
|
||||||
|
const _OrderDetailLoaderState({required this.detailOption, required this.failureOption, this.isFetching = false});
|
||||||
|
|
||||||
|
|
||||||
|
@override final Option<CustomerOrderDetail> detailOption;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isFetching;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$OrderDetailLoaderStateCopyWith<_OrderDetailLoaderState> get copyWith => __$OrderDetailLoaderStateCopyWithImpl<_OrderDetailLoaderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _OrderDetailLoaderState&&(identical(other.detailOption, detailOption) || other.detailOption == detailOption)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isFetching, isFetching) || other.isFetching == isFetching));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,detailOption,failureOption,isFetching);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderDetailLoaderState(detailOption: $detailOption, failureOption: $failureOption, isFetching: $isFetching)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$OrderDetailLoaderStateCopyWith<$Res> implements $OrderDetailLoaderStateCopyWith<$Res> {
|
||||||
|
factory _$OrderDetailLoaderStateCopyWith(_OrderDetailLoaderState value, $Res Function(_OrderDetailLoaderState) _then) = __$OrderDetailLoaderStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
Option<CustomerOrderDetail> detailOption, Option<WalletFailure> failureOption, bool isFetching
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$OrderDetailLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements _$OrderDetailLoaderStateCopyWith<$Res> {
|
||||||
|
__$OrderDetailLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _OrderDetailLoaderState _self;
|
||||||
|
final $Res Function(_OrderDetailLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderDetailLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? detailOption = null,Object? failureOption = null,Object? isFetching = null,}) {
|
||||||
|
return _then(_OrderDetailLoaderState(
|
||||||
|
detailOption: null == detailOption ? _self.detailOption : detailOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<CustomerOrderDetail>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
part of 'order_detail_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OrderDetailLoaderEvent with _$OrderDetailLoaderEvent {
|
||||||
|
const factory OrderDetailLoaderEvent.fetched(String orderId) = _Fetched;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
part of 'order_detail_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OrderDetailLoaderState with _$OrderDetailLoaderState {
|
||||||
|
const factory OrderDetailLoaderState({
|
||||||
|
required Option<CustomerOrderDetail> detailOption,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
}) = _OrderDetailLoaderState;
|
||||||
|
|
||||||
|
factory OrderDetailLoaderState.initial() =>
|
||||||
|
OrderDetailLoaderState(detailOption: none(), failureOption: none());
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'order_loader_event.dart';
|
||||||
|
part 'order_loader_state.dart';
|
||||||
|
part 'order_loader_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class OrderLoaderBloc extends Bloc<OrderLoaderEvent, OrderLoaderState> {
|
||||||
|
final IOrderRepository _repository;
|
||||||
|
|
||||||
|
static const int _limit = 20;
|
||||||
|
|
||||||
|
OrderLoaderBloc(this._repository) : super(OrderLoaderState.initial()) {
|
||||||
|
on<OrderLoaderEvent>(_onOrderLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onOrderLoaderEvent(
|
||||||
|
OrderLoaderEvent event,
|
||||||
|
Emitter<OrderLoaderState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
refreshed: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getOrders(page: 1, limit: _limit);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(page) => state.copyWith(
|
||||||
|
items: page.items,
|
||||||
|
page: page.page,
|
||||||
|
totalPages: page.totalPages,
|
||||||
|
hasLoaded: true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isFetching: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
loadedMore: (e) async {
|
||||||
|
if (state.isFetching || state.isLoadingMore || !state.hasMore) return;
|
||||||
|
emit(state.copyWith(isLoadingMore: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getOrders(
|
||||||
|
page: state.page + 1,
|
||||||
|
limit: _limit,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(page) => state.copyWith(
|
||||||
|
items: [...state.items, ...page.items],
|
||||||
|
page: page.page,
|
||||||
|
totalPages: page.totalPages,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isLoadingMore: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,533 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'order_loader_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OrderLoaderEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OrderLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderLoaderEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $OrderLoaderEventCopyWith<$Res> {
|
||||||
|
$OrderLoaderEventCopyWith(OrderLoaderEvent _, $Res Function(OrderLoaderEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OrderLoaderEvent].
|
||||||
|
extension OrderLoaderEventPatterns on OrderLoaderEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Refreshed value)? refreshed,TResult Function( _LoadedMore value)? loadedMore,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed(_that);case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Refreshed value) refreshed,required TResult Function( _LoadedMore value) loadedMore,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed():
|
||||||
|
return refreshed(_that);case _LoadedMore():
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Refreshed value)? refreshed,TResult? Function( _LoadedMore value)? loadedMore,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed(_that);case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? refreshed,TResult Function()? loadedMore,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed();case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore();case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() refreshed,required TResult Function() loadedMore,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed():
|
||||||
|
return refreshed();case _LoadedMore():
|
||||||
|
return loadedMore();case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? refreshed,TResult? Function()? loadedMore,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed();case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore();case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Refreshed implements OrderLoaderEvent {
|
||||||
|
const _Refreshed();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Refreshed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderLoaderEvent.refreshed()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _LoadedMore implements OrderLoaderEvent {
|
||||||
|
const _LoadedMore();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoadedMore);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderLoaderEvent.loadedMore()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OrderLoaderState {
|
||||||
|
|
||||||
|
List<CustomerOrder> get items; int get page; int get totalPages; Option<WalletFailure> get failureOption; bool get isFetching; bool get isLoadingMore; bool get hasLoaded;
|
||||||
|
/// Create a copy of OrderLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$OrderLoaderStateCopyWith<OrderLoaderState> get copyWith => _$OrderLoaderStateCopyWithImpl<OrderLoaderState>(this as OrderLoaderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as OrderLoaderState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OrderLoaderState&&const DeepCollectionEquality().equals(other.items, _this.items)&&(identical(other.page, _this.page) || other.page == _this.page)&&(identical(other.totalPages, _this.totalPages) || other.totalPages == _this.totalPages)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isFetching, _this.isFetching) || other.isFetching == _this.isFetching)&&(identical(other.isLoadingMore, _this.isLoadingMore) || other.isLoadingMore == _this.isLoadingMore)&&(identical(other.hasLoaded, _this.hasLoaded) || other.hasLoaded == _this.hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as OrderLoaderState;
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_this.items),_this.page,_this.totalPages,_this.failureOption,_this.isFetching,_this.isLoadingMore,_this.hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as OrderLoaderState;
|
||||||
|
return 'OrderLoaderState(items: ${_this.items}, page: ${_this.page}, totalPages: ${_this.totalPages}, failureOption: ${_this.failureOption}, isFetching: ${_this.isFetching}, isLoadingMore: ${_this.isLoadingMore}, hasLoaded: ${_this.hasLoaded})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $OrderLoaderStateCopyWith<$Res> {
|
||||||
|
factory $OrderLoaderStateCopyWith(OrderLoaderState value, $Res Function(OrderLoaderState) _then) = _$OrderLoaderStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
List<CustomerOrder> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$OrderLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements $OrderLoaderStateCopyWith<$Res> {
|
||||||
|
_$OrderLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final OrderLoaderState _self;
|
||||||
|
final $Res Function(OrderLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? page = null,Object? totalPages = null,Object? failureOption = null,Object? isFetching = null,Object? isLoadingMore = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(OrderLoaderState(
|
||||||
|
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<CustomerOrder>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,totalPages: null == totalPages ? _self.totalPages : totalPages // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isLoadingMore: null == isLoadingMore ? _self.isLoadingMore : isLoadingMore // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OrderLoaderState].
|
||||||
|
extension OrderLoaderStatePatterns on OrderLoaderState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _OrderLoaderState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _OrderLoaderState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _OrderLoaderState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<CustomerOrder> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState() when $default != null:
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<CustomerOrder> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState():
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<CustomerOrder> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OrderLoaderState() when $default != null:
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _OrderLoaderState extends OrderLoaderState {
|
||||||
|
const _OrderLoaderState({required List<CustomerOrder> items, required this.page, required this.totalPages, required this.failureOption, this.isFetching = false, this.isLoadingMore = false, this.hasLoaded = false}): _items = items,super._();
|
||||||
|
|
||||||
|
|
||||||
|
final List<CustomerOrder> _items;
|
||||||
|
@override List<CustomerOrder> get items {
|
||||||
|
if (_items is EqualUnmodifiableListView) return _items;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final int page;
|
||||||
|
@override final int totalPages;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isFetching;
|
||||||
|
@override@JsonKey() final bool isLoadingMore;
|
||||||
|
@override@JsonKey() final bool hasLoaded;
|
||||||
|
|
||||||
|
/// Create a copy of OrderLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$OrderLoaderStateCopyWith<_OrderLoaderState> get copyWith => __$OrderLoaderStateCopyWithImpl<_OrderLoaderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _OrderLoaderState&&const DeepCollectionEquality().equals(other.items, _items)&&(identical(other.page, page) || other.page == page)&&(identical(other.totalPages, totalPages) || other.totalPages == totalPages)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isFetching, isFetching) || other.isFetching == isFetching)&&(identical(other.isLoadingMore, isLoadingMore) || other.isLoadingMore == isLoadingMore)&&(identical(other.hasLoaded, hasLoaded) || other.hasLoaded == hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_items),page,totalPages,failureOption,isFetching,isLoadingMore,hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OrderLoaderState(items: $items, page: $page, totalPages: $totalPages, failureOption: $failureOption, isFetching: $isFetching, isLoadingMore: $isLoadingMore, hasLoaded: $hasLoaded)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$OrderLoaderStateCopyWith<$Res> implements $OrderLoaderStateCopyWith<$Res> {
|
||||||
|
factory _$OrderLoaderStateCopyWith(_OrderLoaderState value, $Res Function(_OrderLoaderState) _then) = __$OrderLoaderStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
List<CustomerOrder> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$OrderLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements _$OrderLoaderStateCopyWith<$Res> {
|
||||||
|
__$OrderLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _OrderLoaderState _self;
|
||||||
|
final $Res Function(_OrderLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OrderLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,Object? page = null,Object? totalPages = null,Object? failureOption = null,Object? isFetching = null,Object? isLoadingMore = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(_OrderLoaderState(
|
||||||
|
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<CustomerOrder>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,totalPages: null == totalPages ? _self.totalPages : totalPages // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isLoadingMore: null == isLoadingMore ? _self.isLoadingMore : isLoadingMore // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
part of 'order_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OrderLoaderEvent with _$OrderLoaderEvent {
|
||||||
|
/// Muat ulang dari halaman pertama.
|
||||||
|
const factory OrderLoaderEvent.refreshed() = _Refreshed;
|
||||||
|
|
||||||
|
const factory OrderLoaderEvent.loadedMore() = _LoadedMore;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
part of 'order_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OrderLoaderState with _$OrderLoaderState {
|
||||||
|
const OrderLoaderState._();
|
||||||
|
|
||||||
|
const factory OrderLoaderState({
|
||||||
|
required List<CustomerOrder> items,
|
||||||
|
required int page,
|
||||||
|
required int totalPages,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
@Default(false) bool isLoadingMore,
|
||||||
|
@Default(false) bool hasLoaded,
|
||||||
|
}) = _OrderLoaderState;
|
||||||
|
|
||||||
|
factory OrderLoaderState.initial() => OrderLoaderState(
|
||||||
|
items: const [],
|
||||||
|
page: 0,
|
||||||
|
totalPages: 0,
|
||||||
|
failureOption: none(),
|
||||||
|
);
|
||||||
|
|
||||||
|
bool get hasMore => page < totalPages;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'outlet_loader_event.dart';
|
||||||
|
part 'outlet_loader_state.dart';
|
||||||
|
part 'outlet_loader_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class OutletLoaderBloc extends Bloc<OutletLoaderEvent, OutletLoaderState> {
|
||||||
|
final IOutletRepository _repository;
|
||||||
|
|
||||||
|
OutletLoaderBloc(this._repository) : super(OutletLoaderState.initial()) {
|
||||||
|
on<OutletLoaderEvent>(_onOutletLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onOutletLoaderEvent(
|
||||||
|
OutletLoaderEvent event,
|
||||||
|
Emitter<OutletLoaderState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
fetched: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getOutlets();
|
||||||
|
|
||||||
|
final data = result.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(outlets) => state.copyWith(outlets: outlets, hasLoaded: true),
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(data.copyWith(isFetching: false));
|
||||||
|
},
|
||||||
|
cleared: (e) async => emit(OutletLoaderState.initial()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,524 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'outlet_loader_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OutletLoaderEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OutletLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OutletLoaderEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $OutletLoaderEventCopyWith<$Res> {
|
||||||
|
$OutletLoaderEventCopyWith(OutletLoaderEvent _, $Res Function(OutletLoaderEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OutletLoaderEvent].
|
||||||
|
extension OutletLoaderEventPatterns on OutletLoaderEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Fetched value)? fetched,TResult Function( _Cleared value)? cleared,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _Cleared() when cleared != null:
|
||||||
|
return cleared(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Fetched value) fetched,required TResult Function( _Cleared value) cleared,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched(_that);case _Cleared():
|
||||||
|
return cleared(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Fetched value)? fetched,TResult? Function( _Cleared value)? cleared,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _Cleared() when cleared != null:
|
||||||
|
return cleared(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? fetched,TResult Function()? cleared,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched();case _Cleared() when cleared != null:
|
||||||
|
return cleared();case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() fetched,required TResult Function() cleared,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched();case _Cleared():
|
||||||
|
return cleared();case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched,TResult? Function()? cleared,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched();case _Cleared() when cleared != null:
|
||||||
|
return cleared();case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Fetched implements OutletLoaderEvent {
|
||||||
|
const _Fetched();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Fetched);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OutletLoaderEvent.fetched()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Cleared implements OutletLoaderEvent {
|
||||||
|
const _Cleared();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Cleared);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OutletLoaderEvent.cleared()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$OutletLoaderState {
|
||||||
|
|
||||||
|
List<Outlet> get outlets; Option<WalletFailure> get failureOption; bool get isFetching; bool get hasLoaded;
|
||||||
|
/// Create a copy of OutletLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$OutletLoaderStateCopyWith<OutletLoaderState> get copyWith => _$OutletLoaderStateCopyWithImpl<OutletLoaderState>(this as OutletLoaderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as OutletLoaderState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is OutletLoaderState&&const DeepCollectionEquality().equals(other.outlets, _this.outlets)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isFetching, _this.isFetching) || other.isFetching == _this.isFetching)&&(identical(other.hasLoaded, _this.hasLoaded) || other.hasLoaded == _this.hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as OutletLoaderState;
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_this.outlets),_this.failureOption,_this.isFetching,_this.hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as OutletLoaderState;
|
||||||
|
return 'OutletLoaderState(outlets: ${_this.outlets}, failureOption: ${_this.failureOption}, isFetching: ${_this.isFetching}, hasLoaded: ${_this.hasLoaded})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $OutletLoaderStateCopyWith<$Res> {
|
||||||
|
factory $OutletLoaderStateCopyWith(OutletLoaderState value, $Res Function(OutletLoaderState) _then) = _$OutletLoaderStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
List<Outlet> outlets, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$OutletLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements $OutletLoaderStateCopyWith<$Res> {
|
||||||
|
_$OutletLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final OutletLoaderState _self;
|
||||||
|
final $Res Function(OutletLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OutletLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? outlets = null,Object? failureOption = null,Object? isFetching = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(OutletLoaderState(
|
||||||
|
outlets: null == outlets ? _self.outlets : outlets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Outlet>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [OutletLoaderState].
|
||||||
|
extension OutletLoaderStatePatterns on OutletLoaderState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _OutletLoaderState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _OutletLoaderState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _OutletLoaderState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Outlet> outlets, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState() when $default != null:
|
||||||
|
return $default(_that.outlets,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Outlet> outlets, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState():
|
||||||
|
return $default(_that.outlets,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Outlet> outlets, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OutletLoaderState() when $default != null:
|
||||||
|
return $default(_that.outlets,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _OutletLoaderState implements OutletLoaderState {
|
||||||
|
const _OutletLoaderState({required List<Outlet> outlets, required this.failureOption, this.isFetching = false, this.hasLoaded = false}): _outlets = outlets;
|
||||||
|
|
||||||
|
|
||||||
|
final List<Outlet> _outlets;
|
||||||
|
@override List<Outlet> get outlets {
|
||||||
|
if (_outlets is EqualUnmodifiableListView) return _outlets;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_outlets);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isFetching;
|
||||||
|
@override@JsonKey() final bool hasLoaded;
|
||||||
|
|
||||||
|
/// Create a copy of OutletLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$OutletLoaderStateCopyWith<_OutletLoaderState> get copyWith => __$OutletLoaderStateCopyWithImpl<_OutletLoaderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _OutletLoaderState&&const DeepCollectionEquality().equals(other.outlets, _outlets)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isFetching, isFetching) || other.isFetching == isFetching)&&(identical(other.hasLoaded, hasLoaded) || other.hasLoaded == hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_outlets),failureOption,isFetching,hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'OutletLoaderState(outlets: $outlets, failureOption: $failureOption, isFetching: $isFetching, hasLoaded: $hasLoaded)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$OutletLoaderStateCopyWith<$Res> implements $OutletLoaderStateCopyWith<$Res> {
|
||||||
|
factory _$OutletLoaderStateCopyWith(_OutletLoaderState value, $Res Function(_OutletLoaderState) _then) = __$OutletLoaderStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
List<Outlet> outlets, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$OutletLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements _$OutletLoaderStateCopyWith<$Res> {
|
||||||
|
__$OutletLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _OutletLoaderState _self;
|
||||||
|
final $Res Function(_OutletLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of OutletLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? outlets = null,Object? failureOption = null,Object? isFetching = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(_OutletLoaderState(
|
||||||
|
outlets: null == outlets ? _self._outlets : outlets // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Outlet>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
part of 'outlet_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OutletLoaderEvent with _$OutletLoaderEvent {
|
||||||
|
const factory OutletLoaderEvent.fetched() = _Fetched;
|
||||||
|
|
||||||
|
/// Dipanggil saat logout supaya outlet organisasi akun sebelumnya hilang.
|
||||||
|
const factory OutletLoaderEvent.cleared() = _Cleared;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
part of 'outlet_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class OutletLoaderState with _$OutletLoaderState {
|
||||||
|
const factory OutletLoaderState({
|
||||||
|
required List<Outlet> outlets,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
@Default(false) bool hasLoaded,
|
||||||
|
}) = _OutletLoaderState;
|
||||||
|
|
||||||
|
factory OutletLoaderState.initial() =>
|
||||||
|
OutletLoaderState(outlets: const [], failureOption: none());
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'pin_change_form_event.dart';
|
||||||
|
part 'pin_change_form_state.dart';
|
||||||
|
part 'pin_change_form_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class PinChangeFormBloc extends Bloc<PinChangeFormEvent, PinChangeFormState> {
|
||||||
|
final IPinRepository _repository;
|
||||||
|
|
||||||
|
PinChangeFormBloc(this._repository) : super(PinChangeFormState.initial()) {
|
||||||
|
on<PinChangeFormEvent>(_onPinChangeFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onPinChangeFormEvent(
|
||||||
|
PinChangeFormEvent event,
|
||||||
|
Emitter<PinChangeFormState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
submitted: (e) async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(isSubmitting: true, failureOrSuccessOption: none()),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.change(
|
||||||
|
oldPin: e.oldPin,
|
||||||
|
pin: e.pin,
|
||||||
|
confirmPin: e.confirmPin,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: false,
|
||||||
|
failureOrSuccessOption: optionOf(result),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,552 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'pin_change_form_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$PinChangeFormEvent {
|
||||||
|
|
||||||
|
String get oldPin; String get pin; String get confirmPin;
|
||||||
|
/// Create a copy of PinChangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PinChangeFormEventCopyWith<PinChangeFormEvent> get copyWith => _$PinChangeFormEventCopyWithImpl<PinChangeFormEvent>(this as PinChangeFormEvent, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as PinChangeFormEvent;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is PinChangeFormEvent&&(identical(other.oldPin, _this.oldPin) || other.oldPin == _this.oldPin)&&(identical(other.pin, _this.pin) || other.pin == _this.pin)&&(identical(other.confirmPin, _this.confirmPin) || other.confirmPin == _this.confirmPin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as PinChangeFormEvent;
|
||||||
|
return Object.hash(runtimeType,_this.oldPin,_this.pin,_this.confirmPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as PinChangeFormEvent;
|
||||||
|
return 'PinChangeFormEvent(oldPin: ${_this.oldPin}, pin: ${_this.pin}, confirmPin: ${_this.confirmPin})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $PinChangeFormEventCopyWith<$Res> {
|
||||||
|
factory $PinChangeFormEventCopyWith(PinChangeFormEvent value, $Res Function(PinChangeFormEvent) _then) = _$PinChangeFormEventCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String oldPin, String pin, String confirmPin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$PinChangeFormEventCopyWithImpl<$Res>
|
||||||
|
implements $PinChangeFormEventCopyWith<$Res> {
|
||||||
|
_$PinChangeFormEventCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final PinChangeFormEvent _self;
|
||||||
|
final $Res Function(PinChangeFormEvent) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? oldPin = null,Object? pin = null,Object? confirmPin = null,}) {
|
||||||
|
return _then(PinChangeFormEvent.submitted(
|
||||||
|
oldPin: null == oldPin ? _self.oldPin : oldPin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,confirmPin: null == confirmPin ? _self.confirmPin : confirmPin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [PinChangeFormEvent].
|
||||||
|
extension PinChangeFormEventPatterns on PinChangeFormEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String oldPin, String pin, String confirmPin)? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.oldPin,_that.pin,_that.confirmPin);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String oldPin, String pin, String confirmPin) submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted(_that.oldPin,_that.pin,_that.confirmPin);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String oldPin, String pin, String confirmPin)? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.oldPin,_that.pin,_that.confirmPin);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Submitted implements PinChangeFormEvent {
|
||||||
|
const _Submitted({required this.oldPin, required this.pin, required this.confirmPin});
|
||||||
|
|
||||||
|
|
||||||
|
@override final String oldPin;
|
||||||
|
@override final String pin;
|
||||||
|
@override final String confirmPin;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SubmittedCopyWith<_Submitted> get copyWith => __$SubmittedCopyWithImpl<_Submitted>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted&&(identical(other.oldPin, oldPin) || other.oldPin == oldPin)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.confirmPin, confirmPin) || other.confirmPin == confirmPin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,oldPin,pin,confirmPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinChangeFormEvent.submitted(oldPin: $oldPin, pin: $pin, confirmPin: $confirmPin)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SubmittedCopyWith<$Res> implements $PinChangeFormEventCopyWith<$Res> {
|
||||||
|
factory _$SubmittedCopyWith(_Submitted value, $Res Function(_Submitted) _then) = __$SubmittedCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String oldPin, String pin, String confirmPin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SubmittedCopyWithImpl<$Res>
|
||||||
|
implements _$SubmittedCopyWith<$Res> {
|
||||||
|
__$SubmittedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Submitted _self;
|
||||||
|
final $Res Function(_Submitted) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? oldPin = null,Object? pin = null,Object? confirmPin = null,}) {
|
||||||
|
return _then(_Submitted(
|
||||||
|
oldPin: null == oldPin ? _self.oldPin : oldPin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,confirmPin: null == confirmPin ? _self.confirmPin : confirmPin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$PinChangeFormState {
|
||||||
|
|
||||||
|
bool get isSubmitting; Option<Either<WalletFailure, Unit>> get failureOrSuccessOption;
|
||||||
|
/// Create a copy of PinChangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PinChangeFormStateCopyWith<PinChangeFormState> get copyWith => _$PinChangeFormStateCopyWithImpl<PinChangeFormState>(this as PinChangeFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as PinChangeFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is PinChangeFormState&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting)&&(identical(other.failureOrSuccessOption, _this.failureOrSuccessOption) || other.failureOrSuccessOption == _this.failureOrSuccessOption));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as PinChangeFormState;
|
||||||
|
return Object.hash(runtimeType,_this.isSubmitting,_this.failureOrSuccessOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as PinChangeFormState;
|
||||||
|
return 'PinChangeFormState(isSubmitting: ${_this.isSubmitting}, failureOrSuccessOption: ${_this.failureOrSuccessOption})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $PinChangeFormStateCopyWith<$Res> {
|
||||||
|
factory $PinChangeFormStateCopyWith(PinChangeFormState value, $Res Function(PinChangeFormState) _then) = _$PinChangeFormStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$PinChangeFormStateCopyWithImpl<$Res>
|
||||||
|
implements $PinChangeFormStateCopyWith<$Res> {
|
||||||
|
_$PinChangeFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final PinChangeFormState _self;
|
||||||
|
final $Res Function(PinChangeFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? isSubmitting = null,Object? failureOrSuccessOption = null,}) {
|
||||||
|
return _then(PinChangeFormState(
|
||||||
|
isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,failureOrSuccessOption: null == failureOrSuccessOption ? _self.failureOrSuccessOption : failureOrSuccessOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<Either<WalletFailure, Unit>>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [PinChangeFormState].
|
||||||
|
extension PinChangeFormStatePatterns on PinChangeFormState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PinChangeFormState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PinChangeFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PinChangeFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState() when $default != null:
|
||||||
|
return $default(_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState():
|
||||||
|
return $default(_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinChangeFormState() when $default != null:
|
||||||
|
return $default(_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _PinChangeFormState implements PinChangeFormState {
|
||||||
|
const _PinChangeFormState({this.isSubmitting = false, required this.failureOrSuccessOption});
|
||||||
|
|
||||||
|
|
||||||
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
@override final Option<Either<WalletFailure, Unit>> failureOrSuccessOption;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$PinChangeFormStateCopyWith<_PinChangeFormState> get copyWith => __$PinChangeFormStateCopyWithImpl<_PinChangeFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PinChangeFormState&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.failureOrSuccessOption, failureOrSuccessOption) || other.failureOrSuccessOption == failureOrSuccessOption));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,isSubmitting,failureOrSuccessOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinChangeFormState(isSubmitting: $isSubmitting, failureOrSuccessOption: $failureOrSuccessOption)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$PinChangeFormStateCopyWith<$Res> implements $PinChangeFormStateCopyWith<$Res> {
|
||||||
|
factory _$PinChangeFormStateCopyWith(_PinChangeFormState value, $Res Function(_PinChangeFormState) _then) = __$PinChangeFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$PinChangeFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$PinChangeFormStateCopyWith<$Res> {
|
||||||
|
__$PinChangeFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _PinChangeFormState _self;
|
||||||
|
final $Res Function(_PinChangeFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinChangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? isSubmitting = null,Object? failureOrSuccessOption = null,}) {
|
||||||
|
return _then(_PinChangeFormState(
|
||||||
|
isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,failureOrSuccessOption: null == failureOrSuccessOption ? _self.failureOrSuccessOption : failureOrSuccessOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<Either<WalletFailure, Unit>>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
part of 'pin_change_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class PinChangeFormEvent with _$PinChangeFormEvent {
|
||||||
|
/// PIN hanya diteruskan ke API, tidak disimpan di state.
|
||||||
|
const factory PinChangeFormEvent.submitted({
|
||||||
|
required String oldPin,
|
||||||
|
required String pin,
|
||||||
|
required String confirmPin,
|
||||||
|
}) = _Submitted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
part of 'pin_change_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class PinChangeFormState with _$PinChangeFormState {
|
||||||
|
const factory PinChangeFormState({
|
||||||
|
@Default(false) bool isSubmitting,
|
||||||
|
required Option<Either<WalletFailure, Unit>> failureOrSuccessOption,
|
||||||
|
}) = _PinChangeFormState;
|
||||||
|
|
||||||
|
factory PinChangeFormState.initial() =>
|
||||||
|
PinChangeFormState(failureOrSuccessOption: none());
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'pin_setup_form_event.dart';
|
||||||
|
part 'pin_setup_form_state.dart';
|
||||||
|
part 'pin_setup_form_bloc.freezed.dart';
|
||||||
|
|
||||||
|
/// Alur buat PIN (`pin_setup`) dan lupa PIN (`pin_reset`) lewat OTP WhatsApp.
|
||||||
|
@injectable
|
||||||
|
class PinSetupFormBloc extends Bloc<PinSetupFormEvent, PinSetupFormState> {
|
||||||
|
final IPinRepository _repository;
|
||||||
|
|
||||||
|
PinSetupFormBloc(this._repository) : super(PinSetupFormState.initial()) {
|
||||||
|
on<PinSetupFormEvent>(_onPinSetupFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onPinSetupFormEvent(
|
||||||
|
PinSetupFormEvent event,
|
||||||
|
Emitter<PinSetupFormState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
otpRequested: (e) async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
purpose: e.purpose,
|
||||||
|
isRequestingOtp: true,
|
||||||
|
otpFailureOption: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.requestOtp(e.purpose);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(
|
||||||
|
otpFailureOption: optionOf(f),
|
||||||
|
resendAvailableAt: f.maybeMap(
|
||||||
|
tooManyRequests: (value) => DateTime.now().add(
|
||||||
|
Duration(seconds: value.retryAfterSeconds),
|
||||||
|
),
|
||||||
|
orElse: () => state.resendAvailableAt,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(otp) => state.copyWith(otp: otp),
|
||||||
|
)
|
||||||
|
.copyWith(isRequestingOtp: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
submitted: (e) async {
|
||||||
|
final otp = state.otp;
|
||||||
|
if (otp == null) return;
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(isSubmitting: true, failureOrSuccessOption: none()),
|
||||||
|
);
|
||||||
|
|
||||||
|
final Either<WalletFailure, Unit> result =
|
||||||
|
state.purpose == PinOtpPurpose.setup
|
||||||
|
? (await _repository.setup(
|
||||||
|
otpToken: otp.otpToken,
|
||||||
|
otpCode: e.otpCode,
|
||||||
|
pin: e.pin,
|
||||||
|
confirmPin: e.confirmPin,
|
||||||
|
)).map((_) => unit)
|
||||||
|
: await _repository.reset(
|
||||||
|
otpToken: otp.otpToken,
|
||||||
|
otpCode: e.otpCode,
|
||||||
|
pin: e.pin,
|
||||||
|
confirmPin: e.confirmPin,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: false,
|
||||||
|
failureOrSuccessOption: optionOf(result),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,631 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'pin_setup_form_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$PinSetupFormEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is PinSetupFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinSetupFormEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $PinSetupFormEventCopyWith<$Res> {
|
||||||
|
$PinSetupFormEventCopyWith(PinSetupFormEvent _, $Res Function(PinSetupFormEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [PinSetupFormEvent].
|
||||||
|
extension PinSetupFormEventPatterns on PinSetupFormEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _OtpRequested value)? otpRequested,TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested() when otpRequested != null:
|
||||||
|
return otpRequested(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _OtpRequested value) otpRequested,required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested():
|
||||||
|
return otpRequested(_that);case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _OtpRequested value)? otpRequested,TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested() when otpRequested != null:
|
||||||
|
return otpRequested(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( PinOtpPurpose purpose)? otpRequested,TResult Function( String otpCode, String pin, String confirmPin)? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested() when otpRequested != null:
|
||||||
|
return otpRequested(_that.purpose);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.otpCode,_that.pin,_that.confirmPin);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( PinOtpPurpose purpose) otpRequested,required TResult Function( String otpCode, String pin, String confirmPin) submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested():
|
||||||
|
return otpRequested(_that.purpose);case _Submitted():
|
||||||
|
return submitted(_that.otpCode,_that.pin,_that.confirmPin);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( PinOtpPurpose purpose)? otpRequested,TResult? Function( String otpCode, String pin, String confirmPin)? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _OtpRequested() when otpRequested != null:
|
||||||
|
return otpRequested(_that.purpose);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.otpCode,_that.pin,_that.confirmPin);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _OtpRequested implements PinSetupFormEvent {
|
||||||
|
const _OtpRequested(this.purpose);
|
||||||
|
|
||||||
|
|
||||||
|
final PinOtpPurpose purpose;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$OtpRequestedCopyWith<_OtpRequested> get copyWith => __$OtpRequestedCopyWithImpl<_OtpRequested>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _OtpRequested&&(identical(other.purpose, purpose) || other.purpose == purpose));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,purpose);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinSetupFormEvent.otpRequested(purpose: $purpose)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$OtpRequestedCopyWith<$Res> implements $PinSetupFormEventCopyWith<$Res> {
|
||||||
|
factory _$OtpRequestedCopyWith(_OtpRequested value, $Res Function(_OtpRequested) _then) = __$OtpRequestedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
PinOtpPurpose purpose
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$OtpRequestedCopyWithImpl<$Res>
|
||||||
|
implements _$OtpRequestedCopyWith<$Res> {
|
||||||
|
__$OtpRequestedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _OtpRequested _self;
|
||||||
|
final $Res Function(_OtpRequested) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? purpose = null,}) {
|
||||||
|
return _then(_OtpRequested(
|
||||||
|
null == purpose ? _self.purpose : purpose // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PinOtpPurpose,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Submitted implements PinSetupFormEvent {
|
||||||
|
const _Submitted({required this.otpCode, required this.pin, required this.confirmPin});
|
||||||
|
|
||||||
|
|
||||||
|
final String otpCode;
|
||||||
|
final String pin;
|
||||||
|
final String confirmPin;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SubmittedCopyWith<_Submitted> get copyWith => __$SubmittedCopyWithImpl<_Submitted>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted&&(identical(other.otpCode, otpCode) || other.otpCode == otpCode)&&(identical(other.pin, pin) || other.pin == pin)&&(identical(other.confirmPin, confirmPin) || other.confirmPin == confirmPin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,otpCode,pin,confirmPin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinSetupFormEvent.submitted(otpCode: $otpCode, pin: $pin, confirmPin: $confirmPin)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SubmittedCopyWith<$Res> implements $PinSetupFormEventCopyWith<$Res> {
|
||||||
|
factory _$SubmittedCopyWith(_Submitted value, $Res Function(_Submitted) _then) = __$SubmittedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String otpCode, String pin, String confirmPin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SubmittedCopyWithImpl<$Res>
|
||||||
|
implements _$SubmittedCopyWith<$Res> {
|
||||||
|
__$SubmittedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Submitted _self;
|
||||||
|
final $Res Function(_Submitted) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? otpCode = null,Object? pin = null,Object? confirmPin = null,}) {
|
||||||
|
return _then(_Submitted(
|
||||||
|
otpCode: null == otpCode ? _self.otpCode : otpCode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,confirmPin: null == confirmPin ? _self.confirmPin : confirmPin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$PinSetupFormState {
|
||||||
|
|
||||||
|
PinOtpPurpose get purpose; PinOtp? get otp; bool get isRequestingOtp; Option<WalletFailure> get otpFailureOption;/// Diisi saat server menjawab `429`; tombol kirim ulang menunggu sampai
|
||||||
|
/// waktu ini.
|
||||||
|
DateTime? get resendAvailableAt; bool get isSubmitting; Option<Either<WalletFailure, Unit>> get failureOrSuccessOption;
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PinSetupFormStateCopyWith<PinSetupFormState> get copyWith => _$PinSetupFormStateCopyWithImpl<PinSetupFormState>(this as PinSetupFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as PinSetupFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is PinSetupFormState&&(identical(other.purpose, _this.purpose) || other.purpose == _this.purpose)&&(identical(other.otp, _this.otp) || other.otp == _this.otp)&&(identical(other.isRequestingOtp, _this.isRequestingOtp) || other.isRequestingOtp == _this.isRequestingOtp)&&(identical(other.otpFailureOption, _this.otpFailureOption) || other.otpFailureOption == _this.otpFailureOption)&&(identical(other.resendAvailableAt, _this.resendAvailableAt) || other.resendAvailableAt == _this.resendAvailableAt)&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting)&&(identical(other.failureOrSuccessOption, _this.failureOrSuccessOption) || other.failureOrSuccessOption == _this.failureOrSuccessOption));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as PinSetupFormState;
|
||||||
|
return Object.hash(runtimeType,_this.purpose,_this.otp,_this.isRequestingOtp,_this.otpFailureOption,_this.resendAvailableAt,_this.isSubmitting,_this.failureOrSuccessOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as PinSetupFormState;
|
||||||
|
return 'PinSetupFormState(purpose: ${_this.purpose}, otp: ${_this.otp}, isRequestingOtp: ${_this.isRequestingOtp}, otpFailureOption: ${_this.otpFailureOption}, resendAvailableAt: ${_this.resendAvailableAt}, isSubmitting: ${_this.isSubmitting}, failureOrSuccessOption: ${_this.failureOrSuccessOption})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $PinSetupFormStateCopyWith<$Res> {
|
||||||
|
factory $PinSetupFormStateCopyWith(PinSetupFormState value, $Res Function(PinSetupFormState) _then) = _$PinSetupFormStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
PinOtpPurpose purpose, PinOtp? otp, bool isRequestingOtp, Option<WalletFailure> otpFailureOption, DateTime? resendAvailableAt, bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$PinOtpCopyWith<$Res>? get otp;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$PinSetupFormStateCopyWithImpl<$Res>
|
||||||
|
implements $PinSetupFormStateCopyWith<$Res> {
|
||||||
|
_$PinSetupFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final PinSetupFormState _self;
|
||||||
|
final $Res Function(PinSetupFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? purpose = null,Object? otp = freezed,Object? isRequestingOtp = null,Object? otpFailureOption = null,Object? resendAvailableAt = freezed,Object? isSubmitting = null,Object? failureOrSuccessOption = null,}) {
|
||||||
|
return _then(PinSetupFormState(
|
||||||
|
purpose: null == purpose ? _self.purpose : purpose // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PinOtpPurpose,otp: freezed == otp ? _self.otp : otp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PinOtp?,isRequestingOtp: null == isRequestingOtp ? _self.isRequestingOtp : isRequestingOtp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,otpFailureOption: null == otpFailureOption ? _self.otpFailureOption : otpFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,resendAvailableAt: freezed == resendAvailableAt ? _self.resendAvailableAt : resendAvailableAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,failureOrSuccessOption: null == failureOrSuccessOption ? _self.failureOrSuccessOption : failureOrSuccessOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<Either<WalletFailure, Unit>>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PinOtpCopyWith<$Res>? get otp {
|
||||||
|
if (_self.otp == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $PinOtpCopyWith<$Res>(_self.otp!, (value) {
|
||||||
|
return _then(_self.copyWith(otp: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [PinSetupFormState].
|
||||||
|
extension PinSetupFormStatePatterns on PinSetupFormState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _PinSetupFormState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _PinSetupFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _PinSetupFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( PinOtpPurpose purpose, PinOtp? otp, bool isRequestingOtp, Option<WalletFailure> otpFailureOption, DateTime? resendAvailableAt, bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState() when $default != null:
|
||||||
|
return $default(_that.purpose,_that.otp,_that.isRequestingOtp,_that.otpFailureOption,_that.resendAvailableAt,_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( PinOtpPurpose purpose, PinOtp? otp, bool isRequestingOtp, Option<WalletFailure> otpFailureOption, DateTime? resendAvailableAt, bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState():
|
||||||
|
return $default(_that.purpose,_that.otp,_that.isRequestingOtp,_that.otpFailureOption,_that.resendAvailableAt,_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( PinOtpPurpose purpose, PinOtp? otp, bool isRequestingOtp, Option<WalletFailure> otpFailureOption, DateTime? resendAvailableAt, bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _PinSetupFormState() when $default != null:
|
||||||
|
return $default(_that.purpose,_that.otp,_that.isRequestingOtp,_that.otpFailureOption,_that.resendAvailableAt,_that.isSubmitting,_that.failureOrSuccessOption);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _PinSetupFormState implements PinSetupFormState {
|
||||||
|
const _PinSetupFormState({required this.purpose, this.otp, this.isRequestingOtp = false, required this.otpFailureOption, this.resendAvailableAt, this.isSubmitting = false, required this.failureOrSuccessOption});
|
||||||
|
|
||||||
|
|
||||||
|
@override final PinOtpPurpose purpose;
|
||||||
|
@override final PinOtp? otp;
|
||||||
|
@override@JsonKey() final bool isRequestingOtp;
|
||||||
|
@override final Option<WalletFailure> otpFailureOption;
|
||||||
|
/// Diisi saat server menjawab `429`; tombol kirim ulang menunggu sampai
|
||||||
|
/// waktu ini.
|
||||||
|
@override final DateTime? resendAvailableAt;
|
||||||
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
@override final Option<Either<WalletFailure, Unit>> failureOrSuccessOption;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$PinSetupFormStateCopyWith<_PinSetupFormState> get copyWith => __$PinSetupFormStateCopyWithImpl<_PinSetupFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PinSetupFormState&&(identical(other.purpose, purpose) || other.purpose == purpose)&&(identical(other.otp, otp) || other.otp == otp)&&(identical(other.isRequestingOtp, isRequestingOtp) || other.isRequestingOtp == isRequestingOtp)&&(identical(other.otpFailureOption, otpFailureOption) || other.otpFailureOption == otpFailureOption)&&(identical(other.resendAvailableAt, resendAvailableAt) || other.resendAvailableAt == resendAvailableAt)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.failureOrSuccessOption, failureOrSuccessOption) || other.failureOrSuccessOption == failureOrSuccessOption));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,purpose,otp,isRequestingOtp,otpFailureOption,resendAvailableAt,isSubmitting,failureOrSuccessOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'PinSetupFormState(purpose: $purpose, otp: $otp, isRequestingOtp: $isRequestingOtp, otpFailureOption: $otpFailureOption, resendAvailableAt: $resendAvailableAt, isSubmitting: $isSubmitting, failureOrSuccessOption: $failureOrSuccessOption)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$PinSetupFormStateCopyWith<$Res> implements $PinSetupFormStateCopyWith<$Res> {
|
||||||
|
factory _$PinSetupFormStateCopyWith(_PinSetupFormState value, $Res Function(_PinSetupFormState) _then) = __$PinSetupFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
PinOtpPurpose purpose, PinOtp? otp, bool isRequestingOtp, Option<WalletFailure> otpFailureOption, DateTime? resendAvailableAt, bool isSubmitting, Option<Either<WalletFailure, Unit>> failureOrSuccessOption
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $PinOtpCopyWith<$Res>? get otp;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$PinSetupFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$PinSetupFormStateCopyWith<$Res> {
|
||||||
|
__$PinSetupFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _PinSetupFormState _self;
|
||||||
|
final $Res Function(_PinSetupFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? purpose = null,Object? otp = freezed,Object? isRequestingOtp = null,Object? otpFailureOption = null,Object? resendAvailableAt = freezed,Object? isSubmitting = null,Object? failureOrSuccessOption = null,}) {
|
||||||
|
return _then(_PinSetupFormState(
|
||||||
|
purpose: null == purpose ? _self.purpose : purpose // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PinOtpPurpose,otp: freezed == otp ? _self.otp : otp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as PinOtp?,isRequestingOtp: null == isRequestingOtp ? _self.isRequestingOtp : isRequestingOtp // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,otpFailureOption: null == otpFailureOption ? _self.otpFailureOption : otpFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,resendAvailableAt: freezed == resendAvailableAt ? _self.resendAvailableAt : resendAvailableAt // ignore: cast_nullable_to_non_nullable
|
||||||
|
as DateTime?,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,failureOrSuccessOption: null == failureOrSuccessOption ? _self.failureOrSuccessOption : failureOrSuccessOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<Either<WalletFailure, Unit>>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of PinSetupFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$PinOtpCopyWith<$Res>? get otp {
|
||||||
|
if (_self.otp == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $PinOtpCopyWith<$Res>(_self.otp!, (value) {
|
||||||
|
return _then(_self.copyWith(otp: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
part of 'pin_setup_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class PinSetupFormEvent with _$PinSetupFormEvent {
|
||||||
|
const factory PinSetupFormEvent.otpRequested(PinOtpPurpose purpose) =
|
||||||
|
_OtpRequested;
|
||||||
|
|
||||||
|
/// PIN hanya diteruskan ke API, tidak disimpan di state.
|
||||||
|
const factory PinSetupFormEvent.submitted({
|
||||||
|
required String otpCode,
|
||||||
|
required String pin,
|
||||||
|
required String confirmPin,
|
||||||
|
}) = _Submitted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
part of 'pin_setup_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class PinSetupFormState with _$PinSetupFormState {
|
||||||
|
const factory PinSetupFormState({
|
||||||
|
required PinOtpPurpose purpose,
|
||||||
|
PinOtp? otp,
|
||||||
|
@Default(false) bool isRequestingOtp,
|
||||||
|
required Option<WalletFailure> otpFailureOption,
|
||||||
|
|
||||||
|
/// Diisi saat server menjawab `429`; tombol kirim ulang menunggu sampai
|
||||||
|
/// waktu ini.
|
||||||
|
DateTime? resendAvailableAt,
|
||||||
|
@Default(false) bool isSubmitting,
|
||||||
|
required Option<Either<WalletFailure, Unit>> failureOrSuccessOption,
|
||||||
|
}) = _PinSetupFormState;
|
||||||
|
|
||||||
|
factory PinSetupFormState.initial() => PinSetupFormState(
|
||||||
|
purpose: PinOtpPurpose.setup,
|
||||||
|
otpFailureOption: none(),
|
||||||
|
failureOrSuccessOption: none(),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'voucher_loader_event.dart';
|
||||||
|
part 'voucher_loader_state.dart';
|
||||||
|
part 'voucher_loader_bloc.freezed.dart';
|
||||||
|
|
||||||
|
/// Katalog voucher yang bisa ditukar (§9.1).
|
||||||
|
@injectable
|
||||||
|
class VoucherLoaderBloc extends Bloc<VoucherLoaderEvent, VoucherLoaderState> {
|
||||||
|
final IVoucherRepository _repository;
|
||||||
|
|
||||||
|
VoucherLoaderBloc(this._repository) : super(VoucherLoaderState.initial()) {
|
||||||
|
on<VoucherLoaderEvent>(_onVoucherLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onVoucherLoaderEvent(
|
||||||
|
VoucherLoaderEvent event,
|
||||||
|
Emitter<VoucherLoaderState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
fetched: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getVouchers();
|
||||||
|
|
||||||
|
final data = result.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(vouchers) => state.copyWith(vouchers: vouchers, hasLoaded: true),
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(data.copyWith(isFetching: false));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,486 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'voucher_loader_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherLoaderEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherLoaderEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $VoucherLoaderEventCopyWith<$Res> {
|
||||||
|
$VoucherLoaderEventCopyWith(VoucherLoaderEvent _, $Res Function(VoucherLoaderEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherLoaderEvent].
|
||||||
|
extension VoucherLoaderEventPatterns on VoucherLoaderEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Fetched value)? fetched,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Fetched value) fetched,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Fetched value)? fetched,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? fetched,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched();case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() fetched,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched():
|
||||||
|
return fetched();case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? fetched,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Fetched() when fetched != null:
|
||||||
|
return fetched();case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Fetched implements VoucherLoaderEvent {
|
||||||
|
const _Fetched();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Fetched);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherLoaderEvent.fetched()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherLoaderState {
|
||||||
|
|
||||||
|
List<Voucher> get vouchers; Option<WalletFailure> get failureOption; bool get isFetching; bool get hasLoaded;
|
||||||
|
/// Create a copy of VoucherLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherLoaderStateCopyWith<VoucherLoaderState> get copyWith => _$VoucherLoaderStateCopyWithImpl<VoucherLoaderState>(this as VoucherLoaderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as VoucherLoaderState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherLoaderState&&const DeepCollectionEquality().equals(other.vouchers, _this.vouchers)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isFetching, _this.isFetching) || other.isFetching == _this.isFetching)&&(identical(other.hasLoaded, _this.hasLoaded) || other.hasLoaded == _this.hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as VoucherLoaderState;
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_this.vouchers),_this.failureOption,_this.isFetching,_this.hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as VoucherLoaderState;
|
||||||
|
return 'VoucherLoaderState(vouchers: ${_this.vouchers}, failureOption: ${_this.failureOption}, isFetching: ${_this.isFetching}, hasLoaded: ${_this.hasLoaded})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $VoucherLoaderStateCopyWith<$Res> {
|
||||||
|
factory $VoucherLoaderStateCopyWith(VoucherLoaderState value, $Res Function(VoucherLoaderState) _then) = _$VoucherLoaderStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
List<Voucher> vouchers, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$VoucherLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements $VoucherLoaderStateCopyWith<$Res> {
|
||||||
|
_$VoucherLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final VoucherLoaderState _self;
|
||||||
|
final $Res Function(VoucherLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? vouchers = null,Object? failureOption = null,Object? isFetching = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(VoucherLoaderState(
|
||||||
|
vouchers: null == vouchers ? _self.vouchers : vouchers // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Voucher>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherLoaderState].
|
||||||
|
extension VoucherLoaderStatePatterns on VoucherLoaderState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _VoucherLoaderState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _VoucherLoaderState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _VoucherLoaderState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<Voucher> vouchers, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState() when $default != null:
|
||||||
|
return $default(_that.vouchers,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<Voucher> vouchers, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState():
|
||||||
|
return $default(_that.vouchers,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<Voucher> vouchers, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherLoaderState() when $default != null:
|
||||||
|
return $default(_that.vouchers,_that.failureOption,_that.isFetching,_that.hasLoaded);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _VoucherLoaderState implements VoucherLoaderState {
|
||||||
|
const _VoucherLoaderState({required List<Voucher> vouchers, required this.failureOption, this.isFetching = false, this.hasLoaded = false}): _vouchers = vouchers;
|
||||||
|
|
||||||
|
|
||||||
|
final List<Voucher> _vouchers;
|
||||||
|
@override List<Voucher> get vouchers {
|
||||||
|
if (_vouchers is EqualUnmodifiableListView) return _vouchers;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_vouchers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isFetching;
|
||||||
|
@override@JsonKey() final bool hasLoaded;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$VoucherLoaderStateCopyWith<_VoucherLoaderState> get copyWith => __$VoucherLoaderStateCopyWithImpl<_VoucherLoaderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VoucherLoaderState&&const DeepCollectionEquality().equals(other.vouchers, _vouchers)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isFetching, isFetching) || other.isFetching == isFetching)&&(identical(other.hasLoaded, hasLoaded) || other.hasLoaded == hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_vouchers),failureOption,isFetching,hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherLoaderState(vouchers: $vouchers, failureOption: $failureOption, isFetching: $isFetching, hasLoaded: $hasLoaded)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$VoucherLoaderStateCopyWith<$Res> implements $VoucherLoaderStateCopyWith<$Res> {
|
||||||
|
factory _$VoucherLoaderStateCopyWith(_VoucherLoaderState value, $Res Function(_VoucherLoaderState) _then) = __$VoucherLoaderStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
List<Voucher> vouchers, Option<WalletFailure> failureOption, bool isFetching, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$VoucherLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements _$VoucherLoaderStateCopyWith<$Res> {
|
||||||
|
__$VoucherLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _VoucherLoaderState _self;
|
||||||
|
final $Res Function(_VoucherLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? vouchers = null,Object? failureOption = null,Object? isFetching = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(_VoucherLoaderState(
|
||||||
|
vouchers: null == vouchers ? _self._vouchers : vouchers // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<Voucher>,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
part of 'voucher_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherLoaderEvent with _$VoucherLoaderEvent {
|
||||||
|
const factory VoucherLoaderEvent.fetched() = _Fetched;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
part of 'voucher_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherLoaderState with _$VoucherLoaderState {
|
||||||
|
const factory VoucherLoaderState({
|
||||||
|
required List<Voucher> vouchers,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
@Default(false) bool hasLoaded,
|
||||||
|
}) = _VoucherLoaderState;
|
||||||
|
|
||||||
|
factory VoucherLoaderState.initial() =>
|
||||||
|
VoucherLoaderState(vouchers: const [], failureOption: none());
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../common/function/app_function.dart';
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'voucher_redeem_form_event.dart';
|
||||||
|
part 'voucher_redeem_form_state.dart';
|
||||||
|
part 'voucher_redeem_form_bloc.freezed.dart';
|
||||||
|
|
||||||
|
/// Tukar EnakPoint ke satu voucher (§9.2). Satu bloc per voucher, supaya
|
||||||
|
/// `Idempotency-Key` tidak terbawa ke voucher lain.
|
||||||
|
@injectable
|
||||||
|
class VoucherRedeemFormBloc
|
||||||
|
extends Bloc<VoucherRedeemFormEvent, VoucherRedeemFormState> {
|
||||||
|
final IVoucherRepository _repository;
|
||||||
|
|
||||||
|
VoucherRedeemFormBloc(this._repository)
|
||||||
|
: super(VoucherRedeemFormState.initial()) {
|
||||||
|
on<VoucherRedeemFormEvent>(_onVoucherRedeemFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onVoucherRedeemFormEvent(
|
||||||
|
VoucherRedeemFormEvent event,
|
||||||
|
Emitter<VoucherRedeemFormState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
submitted: (e) async {
|
||||||
|
// Key baru untuk setiap konfirmasi, kecuali mengulang request yang
|
||||||
|
// sebelumnya gagal karena jaringan.
|
||||||
|
final key = state.idempotencyKey ?? generateUuidV4();
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: true,
|
||||||
|
idempotencyKey: key,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.redeem(
|
||||||
|
voucherId: e.voucherId,
|
||||||
|
pin: e.pin,
|
||||||
|
idempotencyKey: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(
|
||||||
|
failureOption: optionOf(f),
|
||||||
|
idempotencyKey: f.isNetworkError ? key : null,
|
||||||
|
),
|
||||||
|
(redeemResult) =>
|
||||||
|
state.copyWith(result: redeemResult, idempotencyKey: null),
|
||||||
|
)
|
||||||
|
.copyWith(isSubmitting: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,579 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'voucher_redeem_form_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherRedeemFormEvent {
|
||||||
|
|
||||||
|
String get voucherId; String get pin;
|
||||||
|
/// Create a copy of VoucherRedeemFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherRedeemFormEventCopyWith<VoucherRedeemFormEvent> get copyWith => _$VoucherRedeemFormEventCopyWithImpl<VoucherRedeemFormEvent>(this as VoucherRedeemFormEvent, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as VoucherRedeemFormEvent;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherRedeemFormEvent&&(identical(other.voucherId, _this.voucherId) || other.voucherId == _this.voucherId)&&(identical(other.pin, _this.pin) || other.pin == _this.pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as VoucherRedeemFormEvent;
|
||||||
|
return Object.hash(runtimeType,_this.voucherId,_this.pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as VoucherRedeemFormEvent;
|
||||||
|
return 'VoucherRedeemFormEvent(voucherId: ${_this.voucherId}, pin: ${_this.pin})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $VoucherRedeemFormEventCopyWith<$Res> {
|
||||||
|
factory $VoucherRedeemFormEventCopyWith(VoucherRedeemFormEvent value, $Res Function(VoucherRedeemFormEvent) _then) = _$VoucherRedeemFormEventCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String voucherId, String pin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$VoucherRedeemFormEventCopyWithImpl<$Res>
|
||||||
|
implements $VoucherRedeemFormEventCopyWith<$Res> {
|
||||||
|
_$VoucherRedeemFormEventCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final VoucherRedeemFormEvent _self;
|
||||||
|
final $Res Function(VoucherRedeemFormEvent) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? voucherId = null,Object? pin = null,}) {
|
||||||
|
return _then(VoucherRedeemFormEvent.submitted(
|
||||||
|
voucherId: null == voucherId ? _self.voucherId : voucherId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherRedeemFormEvent].
|
||||||
|
extension VoucherRedeemFormEventPatterns on VoucherRedeemFormEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( String voucherId, String pin)? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.voucherId,_that.pin);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( String voucherId, String pin) submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted():
|
||||||
|
return submitted(_that.voucherId,_that.pin);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( String voucherId, String pin)? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.voucherId,_that.pin);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Submitted implements VoucherRedeemFormEvent {
|
||||||
|
const _Submitted({required this.voucherId, required this.pin});
|
||||||
|
|
||||||
|
|
||||||
|
@override final String voucherId;
|
||||||
|
@override final String pin;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SubmittedCopyWith<_Submitted> get copyWith => __$SubmittedCopyWithImpl<_Submitted>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted&&(identical(other.voucherId, voucherId) || other.voucherId == voucherId)&&(identical(other.pin, pin) || other.pin == pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,voucherId,pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedeemFormEvent.submitted(voucherId: $voucherId, pin: $pin)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SubmittedCopyWith<$Res> implements $VoucherRedeemFormEventCopyWith<$Res> {
|
||||||
|
factory _$SubmittedCopyWith(_Submitted value, $Res Function(_Submitted) _then) = __$SubmittedCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String voucherId, String pin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SubmittedCopyWithImpl<$Res>
|
||||||
|
implements _$SubmittedCopyWith<$Res> {
|
||||||
|
__$SubmittedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Submitted _self;
|
||||||
|
final $Res Function(_Submitted) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? voucherId = null,Object? pin = null,}) {
|
||||||
|
return _then(_Submitted(
|
||||||
|
voucherId: null == voucherId ? _self.voucherId : voucherId // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,pin: null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherRedeemFormState {
|
||||||
|
|
||||||
|
VoucherRedeemResult? get result; Option<WalletFailure> get failureOption; bool get isSubmitting; String? get idempotencyKey;
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherRedeemFormStateCopyWith<VoucherRedeemFormState> get copyWith => _$VoucherRedeemFormStateCopyWithImpl<VoucherRedeemFormState>(this as VoucherRedeemFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as VoucherRedeemFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherRedeemFormState&&(identical(other.result, _this.result) || other.result == _this.result)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting)&&(identical(other.idempotencyKey, _this.idempotencyKey) || other.idempotencyKey == _this.idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as VoucherRedeemFormState;
|
||||||
|
return Object.hash(runtimeType,_this.result,_this.failureOption,_this.isSubmitting,_this.idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as VoucherRedeemFormState;
|
||||||
|
return 'VoucherRedeemFormState(result: ${_this.result}, failureOption: ${_this.failureOption}, isSubmitting: ${_this.isSubmitting}, idempotencyKey: ${_this.idempotencyKey})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $VoucherRedeemFormStateCopyWith<$Res> {
|
||||||
|
factory $VoucherRedeemFormStateCopyWith(VoucherRedeemFormState value, $Res Function(VoucherRedeemFormState) _then) = _$VoucherRedeemFormStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
VoucherRedeemResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$VoucherRedeemResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$VoucherRedeemFormStateCopyWithImpl<$Res>
|
||||||
|
implements $VoucherRedeemFormStateCopyWith<$Res> {
|
||||||
|
_$VoucherRedeemFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final VoucherRedeemFormState _self;
|
||||||
|
final $Res Function(VoucherRedeemFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(VoucherRedeemFormState(
|
||||||
|
result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as VoucherRedeemResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherRedeemResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $VoucherRedeemResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherRedeemFormState].
|
||||||
|
extension VoucherRedeemFormStatePatterns on VoucherRedeemFormState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _VoucherRedeemFormState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _VoucherRedeemFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _VoucherRedeemFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( VoucherRedeemResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState() when $default != null:
|
||||||
|
return $default(_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( VoucherRedeemResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState():
|
||||||
|
return $default(_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( VoucherRedeemResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedeemFormState() when $default != null:
|
||||||
|
return $default(_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _VoucherRedeemFormState implements VoucherRedeemFormState {
|
||||||
|
const _VoucherRedeemFormState({this.result, required this.failureOption, this.isSubmitting = false, this.idempotencyKey});
|
||||||
|
|
||||||
|
|
||||||
|
@override final VoucherRedeemResult? result;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
@override final String? idempotencyKey;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$VoucherRedeemFormStateCopyWith<_VoucherRedeemFormState> get copyWith => __$VoucherRedeemFormStateCopyWithImpl<_VoucherRedeemFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VoucherRedeemFormState&&(identical(other.result, result) || other.result == result)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.idempotencyKey, idempotencyKey) || other.idempotencyKey == idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,result,failureOption,isSubmitting,idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedeemFormState(result: $result, failureOption: $failureOption, isSubmitting: $isSubmitting, idempotencyKey: $idempotencyKey)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$VoucherRedeemFormStateCopyWith<$Res> implements $VoucherRedeemFormStateCopyWith<$Res> {
|
||||||
|
factory _$VoucherRedeemFormStateCopyWith(_VoucherRedeemFormState value, $Res Function(_VoucherRedeemFormState) _then) = __$VoucherRedeemFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
VoucherRedeemResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $VoucherRedeemResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$VoucherRedeemFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$VoucherRedeemFormStateCopyWith<$Res> {
|
||||||
|
__$VoucherRedeemFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _VoucherRedeemFormState _self;
|
||||||
|
final $Res Function(_VoucherRedeemFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(_VoucherRedeemFormState(
|
||||||
|
result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as VoucherRedeemResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedeemFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherRedeemResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $VoucherRedeemResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
part of 'voucher_redeem_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherRedeemFormEvent with _$VoucherRedeemFormEvent {
|
||||||
|
/// [pin] hanya diteruskan ke API, tidak disimpan di state.
|
||||||
|
const factory VoucherRedeemFormEvent.submitted({
|
||||||
|
required String voucherId,
|
||||||
|
required String pin,
|
||||||
|
}) = _Submitted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
part of 'voucher_redeem_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherRedeemFormState with _$VoucherRedeemFormState {
|
||||||
|
const factory VoucherRedeemFormState({
|
||||||
|
VoucherRedeemResult? result,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isSubmitting,
|
||||||
|
String? idempotencyKey,
|
||||||
|
}) = _VoucherRedeemFormState;
|
||||||
|
|
||||||
|
factory VoucherRedeemFormState.initial() =>
|
||||||
|
VoucherRedeemFormState(failureOption: none());
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'voucher_redemption_loader_event.dart';
|
||||||
|
part 'voucher_redemption_loader_state.dart';
|
||||||
|
part 'voucher_redemption_loader_bloc.freezed.dart';
|
||||||
|
|
||||||
|
/// "Voucher saya" (§9.3).
|
||||||
|
@injectable
|
||||||
|
class VoucherRedemptionLoaderBloc
|
||||||
|
extends Bloc<VoucherRedemptionLoaderEvent, VoucherRedemptionLoaderState> {
|
||||||
|
final IVoucherRepository _repository;
|
||||||
|
|
||||||
|
static const int _limit = 20;
|
||||||
|
|
||||||
|
VoucherRedemptionLoaderBloc(this._repository)
|
||||||
|
: super(VoucherRedemptionLoaderState.initial()) {
|
||||||
|
on<VoucherRedemptionLoaderEvent>(_onVoucherRedemptionLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onVoucherRedemptionLoaderEvent(
|
||||||
|
VoucherRedemptionLoaderEvent event,
|
||||||
|
Emitter<VoucherRedemptionLoaderState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
refreshed: (e) async {
|
||||||
|
emit(state.copyWith(isFetching: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getRedemptions(page: 1, limit: _limit);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(page) => state.copyWith(
|
||||||
|
items: page.items,
|
||||||
|
page: page.page,
|
||||||
|
totalPages: page.totalPages,
|
||||||
|
hasLoaded: true,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isFetching: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
loadedMore: (e) async {
|
||||||
|
if (state.isFetching || state.isLoadingMore || !state.hasMore) return;
|
||||||
|
emit(state.copyWith(isLoadingMore: true, failureOption: none()));
|
||||||
|
|
||||||
|
final result = await _repository.getRedemptions(
|
||||||
|
page: state.page + 1,
|
||||||
|
limit: _limit,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(failureOption: optionOf(f)),
|
||||||
|
(page) => state.copyWith(
|
||||||
|
items: [...state.items, ...page.items],
|
||||||
|
page: page.page,
|
||||||
|
totalPages: page.totalPages,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isLoadingMore: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,533 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'voucher_redemption_loader_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherRedemptionLoaderEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherRedemptionLoaderEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedemptionLoaderEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $VoucherRedemptionLoaderEventCopyWith<$Res> {
|
||||||
|
$VoucherRedemptionLoaderEventCopyWith(VoucherRedemptionLoaderEvent _, $Res Function(VoucherRedemptionLoaderEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherRedemptionLoaderEvent].
|
||||||
|
extension VoucherRedemptionLoaderEventPatterns on VoucherRedemptionLoaderEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _Refreshed value)? refreshed,TResult Function( _LoadedMore value)? loadedMore,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed(_that);case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _Refreshed value) refreshed,required TResult Function( _LoadedMore value) loadedMore,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed():
|
||||||
|
return refreshed(_that);case _LoadedMore():
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _Refreshed value)? refreshed,TResult? Function( _LoadedMore value)? loadedMore,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed(_that);case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function()? refreshed,TResult Function()? loadedMore,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed();case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore();case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function() refreshed,required TResult Function() loadedMore,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed():
|
||||||
|
return refreshed();case _LoadedMore():
|
||||||
|
return loadedMore();case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function()? refreshed,TResult? Function()? loadedMore,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _Refreshed() when refreshed != null:
|
||||||
|
return refreshed();case _LoadedMore() when loadedMore != null:
|
||||||
|
return loadedMore();case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Refreshed implements VoucherRedemptionLoaderEvent {
|
||||||
|
const _Refreshed();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Refreshed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedemptionLoaderEvent.refreshed()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _LoadedMore implements VoucherRedemptionLoaderEvent {
|
||||||
|
const _LoadedMore();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoadedMore);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedemptionLoaderEvent.loadedMore()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$VoucherRedemptionLoaderState {
|
||||||
|
|
||||||
|
List<VoucherRedemption> get items; int get page; int get totalPages; Option<WalletFailure> get failureOption; bool get isFetching; bool get isLoadingMore; bool get hasLoaded;
|
||||||
|
/// Create a copy of VoucherRedemptionLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$VoucherRedemptionLoaderStateCopyWith<VoucherRedemptionLoaderState> get copyWith => _$VoucherRedemptionLoaderStateCopyWithImpl<VoucherRedemptionLoaderState>(this as VoucherRedemptionLoaderState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as VoucherRedemptionLoaderState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is VoucherRedemptionLoaderState&&const DeepCollectionEquality().equals(other.items, _this.items)&&(identical(other.page, _this.page) || other.page == _this.page)&&(identical(other.totalPages, _this.totalPages) || other.totalPages == _this.totalPages)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isFetching, _this.isFetching) || other.isFetching == _this.isFetching)&&(identical(other.isLoadingMore, _this.isLoadingMore) || other.isLoadingMore == _this.isLoadingMore)&&(identical(other.hasLoaded, _this.hasLoaded) || other.hasLoaded == _this.hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as VoucherRedemptionLoaderState;
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_this.items),_this.page,_this.totalPages,_this.failureOption,_this.isFetching,_this.isLoadingMore,_this.hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as VoucherRedemptionLoaderState;
|
||||||
|
return 'VoucherRedemptionLoaderState(items: ${_this.items}, page: ${_this.page}, totalPages: ${_this.totalPages}, failureOption: ${_this.failureOption}, isFetching: ${_this.isFetching}, isLoadingMore: ${_this.isLoadingMore}, hasLoaded: ${_this.hasLoaded})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $VoucherRedemptionLoaderStateCopyWith<$Res> {
|
||||||
|
factory $VoucherRedemptionLoaderStateCopyWith(VoucherRedemptionLoaderState value, $Res Function(VoucherRedemptionLoaderState) _then) = _$VoucherRedemptionLoaderStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
List<VoucherRedemption> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$VoucherRedemptionLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements $VoucherRedemptionLoaderStateCopyWith<$Res> {
|
||||||
|
_$VoucherRedemptionLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final VoucherRedemptionLoaderState _self;
|
||||||
|
final $Res Function(VoucherRedemptionLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedemptionLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? items = null,Object? page = null,Object? totalPages = null,Object? failureOption = null,Object? isFetching = null,Object? isLoadingMore = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(VoucherRedemptionLoaderState(
|
||||||
|
items: null == items ? _self.items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<VoucherRedemption>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,totalPages: null == totalPages ? _self.totalPages : totalPages // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isLoadingMore: null == isLoadingMore ? _self.isLoadingMore : isLoadingMore // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [VoucherRedemptionLoaderState].
|
||||||
|
extension VoucherRedemptionLoaderStatePatterns on VoucherRedemptionLoaderState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _VoucherRedemptionLoaderState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _VoucherRedemptionLoaderState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _VoucherRedemptionLoaderState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<VoucherRedemption> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState() when $default != null:
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<VoucherRedemption> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState():
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<VoucherRedemption> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _VoucherRedemptionLoaderState() when $default != null:
|
||||||
|
return $default(_that.items,_that.page,_that.totalPages,_that.failureOption,_that.isFetching,_that.isLoadingMore,_that.hasLoaded);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _VoucherRedemptionLoaderState extends VoucherRedemptionLoaderState {
|
||||||
|
const _VoucherRedemptionLoaderState({required List<VoucherRedemption> items, required this.page, required this.totalPages, required this.failureOption, this.isFetching = false, this.isLoadingMore = false, this.hasLoaded = false}): _items = items,super._();
|
||||||
|
|
||||||
|
|
||||||
|
final List<VoucherRedemption> _items;
|
||||||
|
@override List<VoucherRedemption> get items {
|
||||||
|
if (_items is EqualUnmodifiableListView) return _items;
|
||||||
|
// ignore: implicit_dynamic_type
|
||||||
|
return EqualUnmodifiableListView(_items);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override final int page;
|
||||||
|
@override final int totalPages;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isFetching;
|
||||||
|
@override@JsonKey() final bool isLoadingMore;
|
||||||
|
@override@JsonKey() final bool hasLoaded;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedemptionLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$VoucherRedemptionLoaderStateCopyWith<_VoucherRedemptionLoaderState> get copyWith => __$VoucherRedemptionLoaderStateCopyWithImpl<_VoucherRedemptionLoaderState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VoucherRedemptionLoaderState&&const DeepCollectionEquality().equals(other.items, _items)&&(identical(other.page, page) || other.page == page)&&(identical(other.totalPages, totalPages) || other.totalPages == totalPages)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isFetching, isFetching) || other.isFetching == isFetching)&&(identical(other.isLoadingMore, isLoadingMore) || other.isLoadingMore == isLoadingMore)&&(identical(other.hasLoaded, hasLoaded) || other.hasLoaded == hasLoaded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,const DeepCollectionEquality().hash(_items),page,totalPages,failureOption,isFetching,isLoadingMore,hasLoaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'VoucherRedemptionLoaderState(items: $items, page: $page, totalPages: $totalPages, failureOption: $failureOption, isFetching: $isFetching, isLoadingMore: $isLoadingMore, hasLoaded: $hasLoaded)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$VoucherRedemptionLoaderStateCopyWith<$Res> implements $VoucherRedemptionLoaderStateCopyWith<$Res> {
|
||||||
|
factory _$VoucherRedemptionLoaderStateCopyWith(_VoucherRedemptionLoaderState value, $Res Function(_VoucherRedemptionLoaderState) _then) = __$VoucherRedemptionLoaderStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
List<VoucherRedemption> items, int page, int totalPages, Option<WalletFailure> failureOption, bool isFetching, bool isLoadingMore, bool hasLoaded
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$VoucherRedemptionLoaderStateCopyWithImpl<$Res>
|
||||||
|
implements _$VoucherRedemptionLoaderStateCopyWith<$Res> {
|
||||||
|
__$VoucherRedemptionLoaderStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _VoucherRedemptionLoaderState _self;
|
||||||
|
final $Res Function(_VoucherRedemptionLoaderState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of VoucherRedemptionLoaderState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? items = null,Object? page = null,Object? totalPages = null,Object? failureOption = null,Object? isFetching = null,Object? isLoadingMore = null,Object? hasLoaded = null,}) {
|
||||||
|
return _then(_VoucherRedemptionLoaderState(
|
||||||
|
items: null == items ? _self._items : items // ignore: cast_nullable_to_non_nullable
|
||||||
|
as List<VoucherRedemption>,page: null == page ? _self.page : page // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,totalPages: null == totalPages ? _self.totalPages : totalPages // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isFetching: null == isFetching ? _self.isFetching : isFetching // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,isLoadingMore: null == isLoadingMore ? _self.isLoadingMore : isLoadingMore // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,hasLoaded: null == hasLoaded ? _self.hasLoaded : hasLoaded // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
part of 'voucher_redemption_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherRedemptionLoaderEvent
|
||||||
|
with _$VoucherRedemptionLoaderEvent {
|
||||||
|
/// Muat ulang dari halaman pertama.
|
||||||
|
const factory VoucherRedemptionLoaderEvent.refreshed() = _Refreshed;
|
||||||
|
|
||||||
|
const factory VoucherRedemptionLoaderEvent.loadedMore() = _LoadedMore;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
part of 'voucher_redemption_loader_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class VoucherRedemptionLoaderState
|
||||||
|
with _$VoucherRedemptionLoaderState {
|
||||||
|
const VoucherRedemptionLoaderState._();
|
||||||
|
|
||||||
|
const factory VoucherRedemptionLoaderState({
|
||||||
|
required List<VoucherRedemption> items,
|
||||||
|
required int page,
|
||||||
|
required int totalPages,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isFetching,
|
||||||
|
@Default(false) bool isLoadingMore,
|
||||||
|
@Default(false) bool hasLoaded,
|
||||||
|
}) = _VoucherRedemptionLoaderState;
|
||||||
|
|
||||||
|
factory VoucherRedemptionLoaderState.initial() =>
|
||||||
|
VoucherRedemptionLoaderState(
|
||||||
|
items: const [],
|
||||||
|
page: 0,
|
||||||
|
totalPages: 0,
|
||||||
|
failureOption: none(),
|
||||||
|
);
|
||||||
|
|
||||||
|
bool get hasMore => page < totalPages;
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../common/function/app_function.dart';
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'exchange_form_event.dart';
|
||||||
|
part 'exchange_form_state.dart';
|
||||||
|
part 'exchange_form_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class ExchangeFormBloc extends Bloc<ExchangeFormEvent, ExchangeFormState> {
|
||||||
|
final IWalletRepository _repository;
|
||||||
|
|
||||||
|
ExchangeFormBloc(this._repository) : super(ExchangeFormState.initial()) {
|
||||||
|
on<ExchangeFormEvent>(_onExchangeFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onExchangeFormEvent(
|
||||||
|
ExchangeFormEvent event,
|
||||||
|
Emitter<ExchangeFormState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
// UI men-debounce ketikan sebelum mengirim event ini.
|
||||||
|
coinsChanged: (e) async {
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
coins: e.coins,
|
||||||
|
preview: null,
|
||||||
|
previewFailureOption: none(),
|
||||||
|
idempotencyKey: null,
|
||||||
|
isPreviewing: e.coins > 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (e.coins <= 0) return;
|
||||||
|
|
||||||
|
final result = await _repository.previewExchange(coins: e.coins);
|
||||||
|
// Customer sudah mengetik angka lain.
|
||||||
|
if (state.coins != e.coins) return;
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(previewFailureOption: optionOf(f)),
|
||||||
|
(preview) => state.copyWith(preview: preview),
|
||||||
|
)
|
||||||
|
.copyWith(isPreviewing: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
submitted: (e) async {
|
||||||
|
// Key baru untuk setiap konfirmasi, kecuali mengulang request yang
|
||||||
|
// sebelumnya gagal karena jaringan.
|
||||||
|
final key = state.idempotencyKey ?? generateUuidV4();
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: true,
|
||||||
|
idempotencyKey: key,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.exchange(
|
||||||
|
coins: state.coins,
|
||||||
|
pin: e.pin,
|
||||||
|
idempotencyKey: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(
|
||||||
|
failureOption: optionOf(f),
|
||||||
|
idempotencyKey: f.isNetworkError ? key : null,
|
||||||
|
),
|
||||||
|
(exchangeResult) => state.copyWith(
|
||||||
|
result: exchangeResult,
|
||||||
|
idempotencyKey: null,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isSubmitting: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,650 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'exchange_form_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$ExchangeFormEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is ExchangeFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ExchangeFormEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $ExchangeFormEventCopyWith<$Res> {
|
||||||
|
$ExchangeFormEventCopyWith(ExchangeFormEvent _, $Res Function(ExchangeFormEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [ExchangeFormEvent].
|
||||||
|
extension ExchangeFormEventPatterns on ExchangeFormEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _CoinsChanged value)? coinsChanged,TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged() when coinsChanged != null:
|
||||||
|
return coinsChanged(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _CoinsChanged value) coinsChanged,required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged():
|
||||||
|
return coinsChanged(_that);case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _CoinsChanged value)? coinsChanged,TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged() when coinsChanged != null:
|
||||||
|
return coinsChanged(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( int coins)? coinsChanged,TResult Function( String pin)? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged() when coinsChanged != null:
|
||||||
|
return coinsChanged(_that.coins);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( int coins) coinsChanged,required TResult Function( String pin) submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged():
|
||||||
|
return coinsChanged(_that.coins);case _Submitted():
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( int coins)? coinsChanged,TResult? Function( String pin)? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CoinsChanged() when coinsChanged != null:
|
||||||
|
return coinsChanged(_that.coins);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _CoinsChanged implements ExchangeFormEvent {
|
||||||
|
const _CoinsChanged(this.coins);
|
||||||
|
|
||||||
|
|
||||||
|
final int coins;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$CoinsChangedCopyWith<_CoinsChanged> get copyWith => __$CoinsChangedCopyWithImpl<_CoinsChanged>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CoinsChanged&&(identical(other.coins, coins) || other.coins == coins));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,coins);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ExchangeFormEvent.coinsChanged(coins: $coins)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$CoinsChangedCopyWith<$Res> implements $ExchangeFormEventCopyWith<$Res> {
|
||||||
|
factory _$CoinsChangedCopyWith(_CoinsChanged value, $Res Function(_CoinsChanged) _then) = __$CoinsChangedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
int coins
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$CoinsChangedCopyWithImpl<$Res>
|
||||||
|
implements _$CoinsChangedCopyWith<$Res> {
|
||||||
|
__$CoinsChangedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _CoinsChanged _self;
|
||||||
|
final $Res Function(_CoinsChanged) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? coins = null,}) {
|
||||||
|
return _then(_CoinsChanged(
|
||||||
|
null == coins ? _self.coins : coins // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Submitted implements ExchangeFormEvent {
|
||||||
|
const _Submitted(this.pin);
|
||||||
|
|
||||||
|
|
||||||
|
final String pin;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SubmittedCopyWith<_Submitted> get copyWith => __$SubmittedCopyWithImpl<_Submitted>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted&&(identical(other.pin, pin) || other.pin == pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ExchangeFormEvent.submitted(pin: $pin)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SubmittedCopyWith<$Res> implements $ExchangeFormEventCopyWith<$Res> {
|
||||||
|
factory _$SubmittedCopyWith(_Submitted value, $Res Function(_Submitted) _then) = __$SubmittedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String pin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SubmittedCopyWithImpl<$Res>
|
||||||
|
implements _$SubmittedCopyWith<$Res> {
|
||||||
|
__$SubmittedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Submitted _self;
|
||||||
|
final $Res Function(_Submitted) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? pin = null,}) {
|
||||||
|
return _then(_Submitted(
|
||||||
|
null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$ExchangeFormState {
|
||||||
|
|
||||||
|
int get coins; ExchangePreview? get preview; Option<WalletFailure> get previewFailureOption; bool get isPreviewing; ExchangeResult? get result; Option<WalletFailure> get failureOption; bool get isSubmitting; String? get idempotencyKey;
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ExchangeFormStateCopyWith<ExchangeFormState> get copyWith => _$ExchangeFormStateCopyWithImpl<ExchangeFormState>(this as ExchangeFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as ExchangeFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is ExchangeFormState&&(identical(other.coins, _this.coins) || other.coins == _this.coins)&&(identical(other.preview, _this.preview) || other.preview == _this.preview)&&(identical(other.previewFailureOption, _this.previewFailureOption) || other.previewFailureOption == _this.previewFailureOption)&&(identical(other.isPreviewing, _this.isPreviewing) || other.isPreviewing == _this.isPreviewing)&&(identical(other.result, _this.result) || other.result == _this.result)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting)&&(identical(other.idempotencyKey, _this.idempotencyKey) || other.idempotencyKey == _this.idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as ExchangeFormState;
|
||||||
|
return Object.hash(runtimeType,_this.coins,_this.preview,_this.previewFailureOption,_this.isPreviewing,_this.result,_this.failureOption,_this.isSubmitting,_this.idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as ExchangeFormState;
|
||||||
|
return 'ExchangeFormState(coins: ${_this.coins}, preview: ${_this.preview}, previewFailureOption: ${_this.previewFailureOption}, isPreviewing: ${_this.isPreviewing}, result: ${_this.result}, failureOption: ${_this.failureOption}, isSubmitting: ${_this.isSubmitting}, idempotencyKey: ${_this.idempotencyKey})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $ExchangeFormStateCopyWith<$Res> {
|
||||||
|
factory $ExchangeFormStateCopyWith(ExchangeFormState value, $Res Function(ExchangeFormState) _then) = _$ExchangeFormStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
int coins, ExchangePreview? preview, Option<WalletFailure> previewFailureOption, bool isPreviewing, ExchangeResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$ExchangePreviewCopyWith<$Res>? get preview;$ExchangeResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$ExchangeFormStateCopyWithImpl<$Res>
|
||||||
|
implements $ExchangeFormStateCopyWith<$Res> {
|
||||||
|
_$ExchangeFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final ExchangeFormState _self;
|
||||||
|
final $Res Function(ExchangeFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? coins = null,Object? preview = freezed,Object? previewFailureOption = null,Object? isPreviewing = null,Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(ExchangeFormState(
|
||||||
|
coins: null == coins ? _self.coins : coins // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ExchangePreview?,previewFailureOption: null == previewFailureOption ? _self.previewFailureOption : previewFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isPreviewing: null == isPreviewing ? _self.isPreviewing : isPreviewing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ExchangeResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ExchangePreviewCopyWith<$Res>? get preview {
|
||||||
|
if (_self.preview == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ExchangePreviewCopyWith<$Res>(_self.preview!, (value) {
|
||||||
|
return _then(_self.copyWith(preview: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ExchangeResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ExchangeResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [ExchangeFormState].
|
||||||
|
extension ExchangeFormStatePatterns on ExchangeFormState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ExchangeFormState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ExchangeFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ExchangeFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( int coins, ExchangePreview? preview, Option<WalletFailure> previewFailureOption, bool isPreviewing, ExchangeResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState() when $default != null:
|
||||||
|
return $default(_that.coins,_that.preview,_that.previewFailureOption,_that.isPreviewing,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( int coins, ExchangePreview? preview, Option<WalletFailure> previewFailureOption, bool isPreviewing, ExchangeResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState():
|
||||||
|
return $default(_that.coins,_that.preview,_that.previewFailureOption,_that.isPreviewing,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( int coins, ExchangePreview? preview, Option<WalletFailure> previewFailureOption, bool isPreviewing, ExchangeResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ExchangeFormState() when $default != null:
|
||||||
|
return $default(_that.coins,_that.preview,_that.previewFailureOption,_that.isPreviewing,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _ExchangeFormState extends ExchangeFormState {
|
||||||
|
const _ExchangeFormState({required this.coins, this.preview, required this.previewFailureOption, this.isPreviewing = false, this.result, required this.failureOption, this.isSubmitting = false, this.idempotencyKey}): super._();
|
||||||
|
|
||||||
|
|
||||||
|
@override final int coins;
|
||||||
|
@override final ExchangePreview? preview;
|
||||||
|
@override final Option<WalletFailure> previewFailureOption;
|
||||||
|
@override@JsonKey() final bool isPreviewing;
|
||||||
|
@override final ExchangeResult? result;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
@override final String? idempotencyKey;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$ExchangeFormStateCopyWith<_ExchangeFormState> get copyWith => __$ExchangeFormStateCopyWithImpl<_ExchangeFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ExchangeFormState&&(identical(other.coins, coins) || other.coins == coins)&&(identical(other.preview, preview) || other.preview == preview)&&(identical(other.previewFailureOption, previewFailureOption) || other.previewFailureOption == previewFailureOption)&&(identical(other.isPreviewing, isPreviewing) || other.isPreviewing == isPreviewing)&&(identical(other.result, result) || other.result == result)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.idempotencyKey, idempotencyKey) || other.idempotencyKey == idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,coins,preview,previewFailureOption,isPreviewing,result,failureOption,isSubmitting,idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ExchangeFormState(coins: $coins, preview: $preview, previewFailureOption: $previewFailureOption, isPreviewing: $isPreviewing, result: $result, failureOption: $failureOption, isSubmitting: $isSubmitting, idempotencyKey: $idempotencyKey)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$ExchangeFormStateCopyWith<$Res> implements $ExchangeFormStateCopyWith<$Res> {
|
||||||
|
factory _$ExchangeFormStateCopyWith(_ExchangeFormState value, $Res Function(_ExchangeFormState) _then) = __$ExchangeFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
int coins, ExchangePreview? preview, Option<WalletFailure> previewFailureOption, bool isPreviewing, ExchangeResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $ExchangePreviewCopyWith<$Res>? get preview;@override $ExchangeResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$ExchangeFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$ExchangeFormStateCopyWith<$Res> {
|
||||||
|
__$ExchangeFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _ExchangeFormState _self;
|
||||||
|
final $Res Function(_ExchangeFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? coins = null,Object? preview = freezed,Object? previewFailureOption = null,Object? isPreviewing = null,Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(_ExchangeFormState(
|
||||||
|
coins: null == coins ? _self.coins : coins // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,preview: freezed == preview ? _self.preview : preview // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ExchangePreview?,previewFailureOption: null == previewFailureOption ? _self.previewFailureOption : previewFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isPreviewing: null == isPreviewing ? _self.isPreviewing : isPreviewing // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as ExchangeResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ExchangePreviewCopyWith<$Res>? get preview {
|
||||||
|
if (_self.preview == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ExchangePreviewCopyWith<$Res>(_self.preview!, (value) {
|
||||||
|
return _then(_self.copyWith(preview: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of ExchangeFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ExchangeResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ExchangeResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
part of 'exchange_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class ExchangeFormEvent with _$ExchangeFormEvent {
|
||||||
|
const factory ExchangeFormEvent.coinsChanged(int coins) = _CoinsChanged;
|
||||||
|
|
||||||
|
/// [pin] hanya diteruskan ke API, tidak disimpan di state.
|
||||||
|
const factory ExchangeFormEvent.submitted(String pin) = _Submitted;
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
part of 'exchange_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class ExchangeFormState with _$ExchangeFormState {
|
||||||
|
const ExchangeFormState._();
|
||||||
|
|
||||||
|
const factory ExchangeFormState({
|
||||||
|
required int coins,
|
||||||
|
ExchangePreview? preview,
|
||||||
|
required Option<WalletFailure> previewFailureOption,
|
||||||
|
@Default(false) bool isPreviewing,
|
||||||
|
ExchangeResult? result,
|
||||||
|
required Option<WalletFailure> failureOption,
|
||||||
|
@Default(false) bool isSubmitting,
|
||||||
|
String? idempotencyKey,
|
||||||
|
}) = _ExchangeFormState;
|
||||||
|
|
||||||
|
factory ExchangeFormState.initial() => ExchangeFormState(
|
||||||
|
coins: 0,
|
||||||
|
previewFailureOption: none(),
|
||||||
|
failureOption: none(),
|
||||||
|
);
|
||||||
|
|
||||||
|
bool get canSubmit =>
|
||||||
|
!isPreviewing &&
|
||||||
|
!isSubmitting &&
|
||||||
|
preview != null &&
|
||||||
|
preview!.valid &&
|
||||||
|
preview!.coins == coins;
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:dartz/dartz.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:injectable/injectable.dart';
|
||||||
|
|
||||||
|
import '../../../common/function/app_function.dart';
|
||||||
|
import '../../../domain/wallet/wallet.dart';
|
||||||
|
|
||||||
|
part 'transfer_form_event.dart';
|
||||||
|
part 'transfer_form_state.dart';
|
||||||
|
part 'transfer_form_bloc.freezed.dart';
|
||||||
|
|
||||||
|
@injectable
|
||||||
|
class TransferFormBloc extends Bloc<TransferFormEvent, TransferFormState> {
|
||||||
|
final IWalletRepository _repository;
|
||||||
|
|
||||||
|
TransferFormBloc(this._repository) : super(TransferFormState.initial()) {
|
||||||
|
on<TransferFormEvent>(_onTransferFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _onTransferFormEvent(
|
||||||
|
TransferFormEvent event,
|
||||||
|
Emitter<TransferFormState> emit,
|
||||||
|
) {
|
||||||
|
return event.map(
|
||||||
|
currencyChanged: (e) async => emit(
|
||||||
|
state.copyWith(
|
||||||
|
currency: e.currency,
|
||||||
|
idempotencyKey: null,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
phoneChanged: (e) async => emit(
|
||||||
|
state.copyWith(
|
||||||
|
phone: e.phone,
|
||||||
|
recipient: null,
|
||||||
|
recipientFailureOption: none(),
|
||||||
|
idempotencyKey: null,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
amountChanged: (e) async => emit(
|
||||||
|
state.copyWith(
|
||||||
|
amount: e.amount,
|
||||||
|
idempotencyKey: null,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
recipientChecked: (e) async {
|
||||||
|
final phone = state.phone;
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isCheckingRecipient: true,
|
||||||
|
recipient: null,
|
||||||
|
recipientFailureOption: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.checkRecipient(phone: phone);
|
||||||
|
if (state.phone != phone) return;
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(recipientFailureOption: optionOf(f)),
|
||||||
|
(recipient) => state.copyWith(recipient: recipient),
|
||||||
|
)
|
||||||
|
.copyWith(isCheckingRecipient: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
submitted: (e) async {
|
||||||
|
// Key baru untuk setiap konfirmasi, kecuali mengulang request yang
|
||||||
|
// sebelumnya gagal karena jaringan.
|
||||||
|
final key = state.idempotencyKey ?? generateUuidV4();
|
||||||
|
emit(
|
||||||
|
state.copyWith(
|
||||||
|
isSubmitting: true,
|
||||||
|
idempotencyKey: key,
|
||||||
|
failureOption: none(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final result = await _repository.transfer(
|
||||||
|
currency: state.currency,
|
||||||
|
amount: state.amount,
|
||||||
|
recipientPhone: state.phone,
|
||||||
|
pin: e.pin,
|
||||||
|
idempotencyKey: key,
|
||||||
|
);
|
||||||
|
|
||||||
|
emit(
|
||||||
|
result
|
||||||
|
.fold(
|
||||||
|
(f) => state.copyWith(
|
||||||
|
failureOption: optionOf(f),
|
||||||
|
idempotencyKey: f.isNetworkError ? key : null,
|
||||||
|
),
|
||||||
|
(transferResult) => state.copyWith(
|
||||||
|
result: transferResult,
|
||||||
|
idempotencyKey: null,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.copyWith(isSubmitting: false),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,842 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint, type=warning, deprecated_member_use, deprecated_member_use_from_same_package
|
||||||
|
// 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, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'transfer_form_bloc.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TransferFormEvent {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is TransferFormEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class $TransferFormEventCopyWith<$Res> {
|
||||||
|
$TransferFormEventCopyWith(TransferFormEvent _, $Res Function(TransferFormEvent) __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [TransferFormEvent].
|
||||||
|
extension TransferFormEventPatterns on TransferFormEvent {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>({TResult Function( _CurrencyChanged value)? currencyChanged,TResult Function( _PhoneChanged value)? phoneChanged,TResult Function( _AmountChanged value)? amountChanged,TResult Function( _RecipientChecked value)? recipientChecked,TResult Function( _Submitted value)? submitted,required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged() when currencyChanged != null:
|
||||||
|
return currencyChanged(_that);case _PhoneChanged() when phoneChanged != null:
|
||||||
|
return phoneChanged(_that);case _AmountChanged() when amountChanged != null:
|
||||||
|
return amountChanged(_that);case _RecipientChecked() when recipientChecked != null:
|
||||||
|
return recipientChecked(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>({required TResult Function( _CurrencyChanged value) currencyChanged,required TResult Function( _PhoneChanged value) phoneChanged,required TResult Function( _AmountChanged value) amountChanged,required TResult Function( _RecipientChecked value) recipientChecked,required TResult Function( _Submitted value) submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged():
|
||||||
|
return currencyChanged(_that);case _PhoneChanged():
|
||||||
|
return phoneChanged(_that);case _AmountChanged():
|
||||||
|
return amountChanged(_that);case _RecipientChecked():
|
||||||
|
return recipientChecked(_that);case _Submitted():
|
||||||
|
return submitted(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>({TResult? Function( _CurrencyChanged value)? currencyChanged,TResult? Function( _PhoneChanged value)? phoneChanged,TResult? Function( _AmountChanged value)? amountChanged,TResult? Function( _RecipientChecked value)? recipientChecked,TResult? Function( _Submitted value)? submitted,}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged() when currencyChanged != null:
|
||||||
|
return currencyChanged(_that);case _PhoneChanged() when phoneChanged != null:
|
||||||
|
return phoneChanged(_that);case _AmountChanged() when amountChanged != null:
|
||||||
|
return amountChanged(_that);case _RecipientChecked() when recipientChecked != null:
|
||||||
|
return recipientChecked(_that);case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( WalletCurrency currency)? currencyChanged,TResult Function( String phone)? phoneChanged,TResult Function( int amount)? amountChanged,TResult Function()? recipientChecked,TResult Function( String pin)? submitted,required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged() when currencyChanged != null:
|
||||||
|
return currencyChanged(_that.currency);case _PhoneChanged() when phoneChanged != null:
|
||||||
|
return phoneChanged(_that.phone);case _AmountChanged() when amountChanged != null:
|
||||||
|
return amountChanged(_that.amount);case _RecipientChecked() when recipientChecked != null:
|
||||||
|
return recipientChecked();case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( WalletCurrency currency) currencyChanged,required TResult Function( String phone) phoneChanged,required TResult Function( int amount) amountChanged,required TResult Function() recipientChecked,required TResult Function( String pin) submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged():
|
||||||
|
return currencyChanged(_that.currency);case _PhoneChanged():
|
||||||
|
return phoneChanged(_that.phone);case _AmountChanged():
|
||||||
|
return amountChanged(_that.amount);case _RecipientChecked():
|
||||||
|
return recipientChecked();case _Submitted():
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( WalletCurrency currency)? currencyChanged,TResult? Function( String phone)? phoneChanged,TResult? Function( int amount)? amountChanged,TResult? Function()? recipientChecked,TResult? Function( String pin)? submitted,}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _CurrencyChanged() when currencyChanged != null:
|
||||||
|
return currencyChanged(_that.currency);case _PhoneChanged() when phoneChanged != null:
|
||||||
|
return phoneChanged(_that.phone);case _AmountChanged() when amountChanged != null:
|
||||||
|
return amountChanged(_that.amount);case _RecipientChecked() when recipientChecked != null:
|
||||||
|
return recipientChecked();case _Submitted() when submitted != null:
|
||||||
|
return submitted(_that.pin);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _CurrencyChanged implements TransferFormEvent {
|
||||||
|
const _CurrencyChanged(this.currency);
|
||||||
|
|
||||||
|
|
||||||
|
final WalletCurrency currency;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$CurrencyChangedCopyWith<_CurrencyChanged> get copyWith => __$CurrencyChangedCopyWithImpl<_CurrencyChanged>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CurrencyChanged&&(identical(other.currency, currency) || other.currency == currency));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,currency);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent.currencyChanged(currency: $currency)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$CurrencyChangedCopyWith<$Res> implements $TransferFormEventCopyWith<$Res> {
|
||||||
|
factory _$CurrencyChangedCopyWith(_CurrencyChanged value, $Res Function(_CurrencyChanged) _then) = __$CurrencyChangedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
WalletCurrency currency
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$CurrencyChangedCopyWithImpl<$Res>
|
||||||
|
implements _$CurrencyChangedCopyWith<$Res> {
|
||||||
|
__$CurrencyChangedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _CurrencyChanged _self;
|
||||||
|
final $Res Function(_CurrencyChanged) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? currency = null,}) {
|
||||||
|
return _then(_CurrencyChanged(
|
||||||
|
null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||||
|
as WalletCurrency,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _PhoneChanged implements TransferFormEvent {
|
||||||
|
const _PhoneChanged(this.phone);
|
||||||
|
|
||||||
|
|
||||||
|
final String phone;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$PhoneChangedCopyWith<_PhoneChanged> get copyWith => __$PhoneChangedCopyWithImpl<_PhoneChanged>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PhoneChanged&&(identical(other.phone, phone) || other.phone == phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent.phoneChanged(phone: $phone)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$PhoneChangedCopyWith<$Res> implements $TransferFormEventCopyWith<$Res> {
|
||||||
|
factory _$PhoneChangedCopyWith(_PhoneChanged value, $Res Function(_PhoneChanged) _then) = __$PhoneChangedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String phone
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$PhoneChangedCopyWithImpl<$Res>
|
||||||
|
implements _$PhoneChangedCopyWith<$Res> {
|
||||||
|
__$PhoneChangedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _PhoneChanged _self;
|
||||||
|
final $Res Function(_PhoneChanged) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? phone = null,}) {
|
||||||
|
return _then(_PhoneChanged(
|
||||||
|
null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _AmountChanged implements TransferFormEvent {
|
||||||
|
const _AmountChanged(this.amount);
|
||||||
|
|
||||||
|
|
||||||
|
final int amount;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$AmountChangedCopyWith<_AmountChanged> get copyWith => __$AmountChangedCopyWithImpl<_AmountChanged>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AmountChanged&&(identical(other.amount, amount) || other.amount == amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent.amountChanged(amount: $amount)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$AmountChangedCopyWith<$Res> implements $TransferFormEventCopyWith<$Res> {
|
||||||
|
factory _$AmountChangedCopyWith(_AmountChanged value, $Res Function(_AmountChanged) _then) = __$AmountChangedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
int amount
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$AmountChangedCopyWithImpl<$Res>
|
||||||
|
implements _$AmountChangedCopyWith<$Res> {
|
||||||
|
__$AmountChangedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _AmountChanged _self;
|
||||||
|
final $Res Function(_AmountChanged) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? amount = null,}) {
|
||||||
|
return _then(_AmountChanged(
|
||||||
|
null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _RecipientChecked implements TransferFormEvent {
|
||||||
|
const _RecipientChecked();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _RecipientChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent.recipientChecked()';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _Submitted implements TransferFormEvent {
|
||||||
|
const _Submitted(this.pin);
|
||||||
|
|
||||||
|
|
||||||
|
final String pin;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$SubmittedCopyWith<_Submitted> get copyWith => __$SubmittedCopyWithImpl<_Submitted>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Submitted&&(identical(other.pin, pin) || other.pin == pin));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormEvent.submitted(pin: $pin)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$SubmittedCopyWith<$Res> implements $TransferFormEventCopyWith<$Res> {
|
||||||
|
factory _$SubmittedCopyWith(_Submitted value, $Res Function(_Submitted) _then) = __$SubmittedCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String pin
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$SubmittedCopyWithImpl<$Res>
|
||||||
|
implements _$SubmittedCopyWith<$Res> {
|
||||||
|
__$SubmittedCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _Submitted _self;
|
||||||
|
final $Res Function(_Submitted) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormEvent
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') $Res call({Object? pin = null,}) {
|
||||||
|
return _then(_Submitted(
|
||||||
|
null == pin ? _self.pin : pin // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TransferFormState {
|
||||||
|
|
||||||
|
WalletCurrency get currency; String get phone; int get amount; TransferRecipient? get recipient; Option<WalletFailure> get recipientFailureOption; bool get isCheckingRecipient; TransferResult? get result; Option<WalletFailure> get failureOption; bool get isSubmitting; String? get idempotencyKey;
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$TransferFormStateCopyWith<TransferFormState> get copyWith => _$TransferFormStateCopyWithImpl<TransferFormState>(this as TransferFormState, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
final _this = this as TransferFormState;
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is TransferFormState&&(identical(other.currency, _this.currency) || other.currency == _this.currency)&&(identical(other.phone, _this.phone) || other.phone == _this.phone)&&(identical(other.amount, _this.amount) || other.amount == _this.amount)&&(identical(other.recipient, _this.recipient) || other.recipient == _this.recipient)&&(identical(other.recipientFailureOption, _this.recipientFailureOption) || other.recipientFailureOption == _this.recipientFailureOption)&&(identical(other.isCheckingRecipient, _this.isCheckingRecipient) || other.isCheckingRecipient == _this.isCheckingRecipient)&&(identical(other.result, _this.result) || other.result == _this.result)&&(identical(other.failureOption, _this.failureOption) || other.failureOption == _this.failureOption)&&(identical(other.isSubmitting, _this.isSubmitting) || other.isSubmitting == _this.isSubmitting)&&(identical(other.idempotencyKey, _this.idempotencyKey) || other.idempotencyKey == _this.idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
final _this = this as TransferFormState;
|
||||||
|
return Object.hash(runtimeType,_this.currency,_this.phone,_this.amount,_this.recipient,_this.recipientFailureOption,_this.isCheckingRecipient,_this.result,_this.failureOption,_this.isSubmitting,_this.idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final _this = this as TransferFormState;
|
||||||
|
return 'TransferFormState(currency: ${_this.currency}, phone: ${_this.phone}, amount: ${_this.amount}, recipient: ${_this.recipient}, recipientFailureOption: ${_this.recipientFailureOption}, isCheckingRecipient: ${_this.isCheckingRecipient}, result: ${_this.result}, failureOption: ${_this.failureOption}, isSubmitting: ${_this.isSubmitting}, idempotencyKey: ${_this.idempotencyKey})';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $TransferFormStateCopyWith<$Res> {
|
||||||
|
factory $TransferFormStateCopyWith(TransferFormState value, $Res Function(TransferFormState) _then) = _$TransferFormStateCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
WalletCurrency currency, String phone, int amount, TransferRecipient? recipient, Option<WalletFailure> recipientFailureOption, bool isCheckingRecipient, TransferResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$TransferRecipientCopyWith<$Res>? get recipient;$TransferResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$TransferFormStateCopyWithImpl<$Res>
|
||||||
|
implements $TransferFormStateCopyWith<$Res> {
|
||||||
|
_$TransferFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final TransferFormState _self;
|
||||||
|
final $Res Function(TransferFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? currency = null,Object? phone = null,Object? amount = null,Object? recipient = freezed,Object? recipientFailureOption = null,Object? isCheckingRecipient = null,Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(TransferFormState(
|
||||||
|
currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||||
|
as WalletCurrency,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,recipient: freezed == recipient ? _self.recipient : recipient // ignore: cast_nullable_to_non_nullable
|
||||||
|
as TransferRecipient?,recipientFailureOption: null == recipientFailureOption ? _self.recipientFailureOption : recipientFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isCheckingRecipient: null == isCheckingRecipient ? _self.isCheckingRecipient : isCheckingRecipient // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as TransferResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$TransferRecipientCopyWith<$Res>? get recipient {
|
||||||
|
if (_self.recipient == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $TransferRecipientCopyWith<$Res>(_self.recipient!, (value) {
|
||||||
|
return _then(_self.copyWith(recipient: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$TransferResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $TransferResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [TransferFormState].
|
||||||
|
extension TransferFormStatePatterns on TransferFormState {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _TransferFormState value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _TransferFormState value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _TransferFormState value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( WalletCurrency currency, String phone, int amount, TransferRecipient? recipient, Option<WalletFailure> recipientFailureOption, bool isCheckingRecipient, TransferResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState() when $default != null:
|
||||||
|
return $default(_that.currency,_that.phone,_that.amount,_that.recipient,_that.recipientFailureOption,_that.isCheckingRecipient,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( WalletCurrency currency, String phone, int amount, TransferRecipient? recipient, Option<WalletFailure> recipientFailureOption, bool isCheckingRecipient, TransferResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState():
|
||||||
|
return $default(_that.currency,_that.phone,_that.amount,_that.recipient,_that.recipientFailureOption,_that.isCheckingRecipient,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( WalletCurrency currency, String phone, int amount, TransferRecipient? recipient, Option<WalletFailure> recipientFailureOption, bool isCheckingRecipient, TransferResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _TransferFormState() when $default != null:
|
||||||
|
return $default(_that.currency,_that.phone,_that.amount,_that.recipient,_that.recipientFailureOption,_that.isCheckingRecipient,_that.result,_that.failureOption,_that.isSubmitting,_that.idempotencyKey);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _TransferFormState extends TransferFormState {
|
||||||
|
const _TransferFormState({required this.currency, required this.phone, required this.amount, this.recipient, required this.recipientFailureOption, this.isCheckingRecipient = false, this.result, required this.failureOption, this.isSubmitting = false, this.idempotencyKey}): super._();
|
||||||
|
|
||||||
|
|
||||||
|
@override final WalletCurrency currency;
|
||||||
|
@override final String phone;
|
||||||
|
@override final int amount;
|
||||||
|
@override final TransferRecipient? recipient;
|
||||||
|
@override final Option<WalletFailure> recipientFailureOption;
|
||||||
|
@override@JsonKey() final bool isCheckingRecipient;
|
||||||
|
@override final TransferResult? result;
|
||||||
|
@override final Option<WalletFailure> failureOption;
|
||||||
|
@override@JsonKey() final bool isSubmitting;
|
||||||
|
@override final String? idempotencyKey;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$TransferFormStateCopyWith<_TransferFormState> get copyWith => __$TransferFormStateCopyWithImpl<_TransferFormState>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _TransferFormState&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.phone, phone) || other.phone == phone)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.recipient, recipient) || other.recipient == recipient)&&(identical(other.recipientFailureOption, recipientFailureOption) || other.recipientFailureOption == recipientFailureOption)&&(identical(other.isCheckingRecipient, isCheckingRecipient) || other.isCheckingRecipient == isCheckingRecipient)&&(identical(other.result, result) || other.result == result)&&(identical(other.failureOption, failureOption) || other.failureOption == failureOption)&&(identical(other.isSubmitting, isSubmitting) || other.isSubmitting == isSubmitting)&&(identical(other.idempotencyKey, idempotencyKey) || other.idempotencyKey == idempotencyKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(runtimeType,currency,phone,amount,recipient,recipientFailureOption,isCheckingRecipient,result,failureOption,isSubmitting,idempotencyKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TransferFormState(currency: $currency, phone: $phone, amount: $amount, recipient: $recipient, recipientFailureOption: $recipientFailureOption, isCheckingRecipient: $isCheckingRecipient, result: $result, failureOption: $failureOption, isSubmitting: $isSubmitting, idempotencyKey: $idempotencyKey)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$TransferFormStateCopyWith<$Res> implements $TransferFormStateCopyWith<$Res> {
|
||||||
|
factory _$TransferFormStateCopyWith(_TransferFormState value, $Res Function(_TransferFormState) _then) = __$TransferFormStateCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
WalletCurrency currency, String phone, int amount, TransferRecipient? recipient, Option<WalletFailure> recipientFailureOption, bool isCheckingRecipient, TransferResult? result, Option<WalletFailure> failureOption, bool isSubmitting, String? idempotencyKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@override $TransferRecipientCopyWith<$Res>? get recipient;@override $TransferResultCopyWith<$Res>? get result;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$TransferFormStateCopyWithImpl<$Res>
|
||||||
|
implements _$TransferFormStateCopyWith<$Res> {
|
||||||
|
__$TransferFormStateCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _TransferFormState _self;
|
||||||
|
final $Res Function(_TransferFormState) _then;
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? currency = null,Object? phone = null,Object? amount = null,Object? recipient = freezed,Object? recipientFailureOption = null,Object? isCheckingRecipient = null,Object? result = freezed,Object? failureOption = null,Object? isSubmitting = null,Object? idempotencyKey = freezed,}) {
|
||||||
|
return _then(_TransferFormState(
|
||||||
|
currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||||
|
as WalletCurrency,phone: null == phone ? _self.phone : phone // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int,recipient: freezed == recipient ? _self.recipient : recipient // ignore: cast_nullable_to_non_nullable
|
||||||
|
as TransferRecipient?,recipientFailureOption: null == recipientFailureOption ? _self.recipientFailureOption : recipientFailureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isCheckingRecipient: null == isCheckingRecipient ? _self.isCheckingRecipient : isCheckingRecipient // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,result: freezed == result ? _self.result : result // ignore: cast_nullable_to_non_nullable
|
||||||
|
as TransferResult?,failureOption: null == failureOption ? _self.failureOption : failureOption // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Option<WalletFailure>,isSubmitting: null == isSubmitting ? _self.isSubmitting : isSubmitting // ignore: cast_nullable_to_non_nullable
|
||||||
|
as bool,idempotencyKey: freezed == idempotencyKey ? _self.idempotencyKey : idempotencyKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$TransferRecipientCopyWith<$Res>? get recipient {
|
||||||
|
if (_self.recipient == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $TransferRecipientCopyWith<$Res>(_self.recipient!, (value) {
|
||||||
|
return _then(_self.copyWith(recipient: value));
|
||||||
|
});
|
||||||
|
}/// Create a copy of TransferFormState
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$TransferResultCopyWith<$Res>? get result {
|
||||||
|
if (_self.result == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $TransferResultCopyWith<$Res>(_self.result!, (value) {
|
||||||
|
return _then(_self.copyWith(result: value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
part of 'transfer_form_bloc.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class TransferFormEvent with _$TransferFormEvent {
|
||||||
|
const factory TransferFormEvent.currencyChanged(WalletCurrency currency) =
|
||||||
|
_CurrencyChanged;
|
||||||
|
|
||||||
|
const factory TransferFormEvent.phoneChanged(String phone) = _PhoneChanged;
|
||||||
|
|
||||||
|
const factory TransferFormEvent.amountChanged(int amount) = _AmountChanged;
|
||||||
|
|
||||||
|
const factory TransferFormEvent.recipientChecked() = _RecipientChecked;
|
||||||
|
|
||||||
|
/// [pin] hanya diteruskan ke API, tidak disimpan di state.
|
||||||
|
const factory TransferFormEvent.submitted(String pin) = _Submitted;
|
||||||
|
}
|
||||||