:drunk: Werid miniapp runtime
This commit is contained in:
215
lib/modular/README.md
Normal file
215
lib/modular/README.md
Normal file
@@ -0,0 +1,215 @@
|
||||
# Plugin Registry and Loader System
|
||||
|
||||
## Overview
|
||||
|
||||
This module provides a plugin system for the Island app with two types of plugins:
|
||||
- **Raw Plugins**: Extend app abilities (services, hooks, utilities)
|
||||
- **Mini-Apps**: Full-screen applications loaded from network with caching
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
lib/
|
||||
modular/
|
||||
interface.dart # Plugin interfaces and metadata models
|
||||
registry.dart # PluginRegistry class for managing plugins
|
||||
pods/
|
||||
plugin_registry.dart # Riverpod providers for plugin management
|
||||
```
|
||||
|
||||
## Core Components
|
||||
|
||||
### 1. Plugin Interface (`lib/modular/interface.dart`)
|
||||
|
||||
Defines the base types for plugins:
|
||||
|
||||
- `Plugin`: Base interface for all plugins
|
||||
- `RawPlugin`: For plugins that extend app functionality
|
||||
- `MiniApp`: For full-screen apps with entry widgets
|
||||
- `PluginMetadata`: Common metadata structure
|
||||
- `MiniAppMetadata`: Metadata for mini-apps including download URL, cache path
|
||||
- `MiniAppServerInfo`: Server response format for mini-app listings
|
||||
- `PluginLoadResult`: Enum for load operation results
|
||||
|
||||
### 2. Plugin Registry (`lib/modular/registry.dart`)
|
||||
|
||||
`PluginRegistry` class manages plugin lifecycle:
|
||||
|
||||
**Raw Plugins:**
|
||||
- `registerRawPlugin(RawPlugin plugin)`
|
||||
- `unregisterRawPlugin(String id)`
|
||||
- `getRawPlugin(String id)`
|
||||
|
||||
**Mini-Apps:**
|
||||
- `loadMiniApp(MiniAppMetadata metadata, {ProgressCallback? onProgress})`: Loads .evc bytecode
|
||||
- `unloadMiniApp(String id)`: Unloads and cleans up
|
||||
- `getMiniApp(String id)`: Get loaded mini-app
|
||||
- `getMiniAppCacheDirectory()`: Get cache directory path
|
||||
- `clearMiniAppCache()`: Clear all cached mini-apps
|
||||
- `dispose()`: Cleanup all resources
|
||||
|
||||
### 3. Riverpod Providers (`lib/pods/plugin_registry.dart`)
|
||||
|
||||
**Providers:**
|
||||
- `pluginRegistryProvider`: Main registry provider with `keepAlive: true`
|
||||
- `miniAppsProvider`: List of loaded mini-apps
|
||||
- `rawPluginsProvider`: Map of raw plugins
|
||||
|
||||
**Methods (via `ref.read(pluginRegistryProvider.notifier)`:**
|
||||
- `syncMiniAppsFromServer(apiEndpoint)`: Sync with server, returns `MiniAppSyncResult`
|
||||
- `downloadMiniApp(id, downloadUrl, {ProgressCallback? onProgress})`: Download and cache
|
||||
- `updateMiniApp(id, {ProgressCallback? onProgress})`: Update to latest version
|
||||
- `enableMiniApp(id, enabled)`: Enable/disable mini-app
|
||||
- `deleteMiniApp(id, {deleteCache})`: Remove mini-app
|
||||
- `clearMiniAppCache()`: Clear cache
|
||||
- `getMiniApp(id)`: Get specific mini-app
|
||||
- `getLastSyncTime()`: Get last sync timestamp
|
||||
|
||||
## Storage
|
||||
|
||||
### SharedPreferences Keys:
|
||||
- `kMiniAppsRegistryKey`: JSON array of MiniAppMetadata
|
||||
- `kMiniAppsLastSyncKey`: ISO8601 timestamp of last sync
|
||||
|
||||
### Cache Structure:
|
||||
```
|
||||
{applicationDocuments}/mini_apps/
|
||||
├── {app_id}.evc # Compiled bytecode
|
||||
└── {app_id}_metadata.json # Metadata backup (optional)
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Registering a Raw Plugin
|
||||
|
||||
```dart
|
||||
class MyRawPlugin extends RawPlugin {
|
||||
@override
|
||||
PluginMetadata get metadata => PluginMetadata(
|
||||
id: 'my_plugin',
|
||||
name: 'My Plugin',
|
||||
version: '1.0.0',
|
||||
description: 'Extends app with new features',
|
||||
);
|
||||
}
|
||||
|
||||
final container = ProviderContainer();
|
||||
container.read(pluginRegistryProvider.notifier).registerRawPlugin(MyRawPlugin());
|
||||
```
|
||||
|
||||
### Syncing Mini-Apps from Server
|
||||
|
||||
```dart
|
||||
final syncResult = await ref.read(pluginRegistryProvider.notifier).syncMiniAppsFromServer(
|
||||
'https://api.example.com/mini-apps',
|
||||
);
|
||||
|
||||
if (syncResult.success) {
|
||||
print('Added: ${syncResult.added}');
|
||||
print('Updated: ${syncResult.updated}');
|
||||
}
|
||||
```
|
||||
|
||||
### Downloading and Loading a Mini-App
|
||||
|
||||
```dart
|
||||
await ref.read(pluginRegistryProvider.notifier).downloadMiniApp(
|
||||
'com.example.miniapp',
|
||||
'https://cdn.example.com/mini-apps/v1/app.evc',
|
||||
onProgress: (progress, message) {
|
||||
print('$progress: $message');
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
### Using a Loaded Mini-App Entry
|
||||
|
||||
```dart
|
||||
class MiniAppScreen extends ConsumerWidget {
|
||||
final String appId;
|
||||
|
||||
const MiniAppScreen({required this.appId, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final miniApp = await ref.read(pluginRegistryProvider.notifier).getMiniApp(appId);
|
||||
|
||||
if (miniApp == null) {
|
||||
return const Center(child: Text('Mini-app not loaded'));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
body: miniApp.buildEntry(),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Server API Response Format
|
||||
|
||||
```json
|
||||
{
|
||||
"mini_apps": [
|
||||
{
|
||||
"id": "com.example.miniapp",
|
||||
"name": "Example Mini-App",
|
||||
"version": "1.2.0",
|
||||
"description": "An example mini-application",
|
||||
"author": "Example Corp",
|
||||
"iconUrl": "https://cdn.example.com/icons/miniapp.png",
|
||||
"downloadUrl": "https://cdn.example.com/mini-apps/v1/app.evc",
|
||||
"updatedAt": "2026-01-18T00:00:00Z",
|
||||
"sizeBytes": 524288
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Mini-App Development
|
||||
|
||||
A mini-app should export a `buildEntry()` function:
|
||||
|
||||
```dart
|
||||
// mini_app/main.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
Widget buildEntry() {
|
||||
return MaterialApp(
|
||||
title: 'My Mini-App',
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('My Mini-App')),
|
||||
body: const Center(
|
||||
child: Text('Hello from Mini-App!'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Compile to .evc using flutter_eval toolchain before uploading to server.
|
||||
|
||||
## FlutterEval Integration
|
||||
|
||||
Currently, a stub `Runtime` class is provided in `lib/modular/registry.dart` for compilation. To enable full flutter_eval functionality:
|
||||
|
||||
1. Resolve dependency conflicts with analyzer package
|
||||
2. Replace stub `Runtime` class with actual flutter_eval import
|
||||
3. Test with actual .evc bytecode files
|
||||
|
||||
## Notes
|
||||
|
||||
- Registry uses `keepAlive: true` to persist across app lifecycle
|
||||
- All operations are async and return appropriate results
|
||||
- Progress callbacks provide real-time feedback for download/load operations
|
||||
- Error handling includes talker logging for debugging
|
||||
- SharedPreferences persistence survives app restarts
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- [ ] Full flutter_eval integration
|
||||
- [ ] Mini-app permissions and security model
|
||||
- [ ] Version comparison and auto-update
|
||||
- [ ] Dependency resolution for mini-apps
|
||||
- [ ] Mini-app marketplace UI
|
||||
- [ ] Hot-swapping without app restart
|
||||
336
lib/modular/api/README.md
Normal file
336
lib/modular/api/README.md
Normal file
@@ -0,0 +1,336 @@
|
||||
# Payment API for Mini-Apps
|
||||
|
||||
## Overview
|
||||
|
||||
Payment API (`lib/modular/api/payment.dart`) provides a simple interface for mini-apps to process payments without needing access to Riverpod or Flutter widget trees.
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Setup
|
||||
|
||||
```dart
|
||||
import 'package:island/modular/api/payment.dart';
|
||||
|
||||
// Get singleton instance
|
||||
final paymentAPI = PaymentAPI.instance;
|
||||
```
|
||||
|
||||
### Creating a Payment Order
|
||||
|
||||
```dart
|
||||
final order = await paymentAPI.createOrder(
|
||||
CreateOrderRequest(
|
||||
amount: 1000, // $10.00 in cents
|
||||
currency: 'USD',
|
||||
remarks: 'Premium subscription',
|
||||
payeeWalletId: 'wallet_123',
|
||||
appIdentifier: 'my.miniapp',
|
||||
),
|
||||
);
|
||||
|
||||
// Use the order ID for payment
|
||||
final orderId = order.id;
|
||||
```
|
||||
|
||||
### Processing Payment with Overlay
|
||||
|
||||
```dart
|
||||
final result = await paymentAPI.processPaymentWithOverlay(
|
||||
context: context,
|
||||
createOrderRequest: CreateOrderRequest(
|
||||
amount: 1000,
|
||||
currency: 'USD',
|
||||
remarks: 'Premium subscription',
|
||||
),
|
||||
enableBiometric: true,
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
print('Payment successful: ${result.order}');
|
||||
} else {
|
||||
print('Payment failed: ${result.error}');
|
||||
}
|
||||
```
|
||||
|
||||
### Processing Existing Payment
|
||||
|
||||
```dart
|
||||
final result = await paymentAPI.processPaymentWithOverlay(
|
||||
context: context,
|
||||
request: PaymentRequest(
|
||||
orderId: 'order_123',
|
||||
amount: 1000,
|
||||
currency: 'USD',
|
||||
pinCode: '123456',
|
||||
enableBiometric: true,
|
||||
showOverlay: true,
|
||||
),
|
||||
);
|
||||
```
|
||||
|
||||
### Processing Payment Without Overlay (Direct)
|
||||
|
||||
```dart
|
||||
final result = await paymentAPI.processDirectPayment(
|
||||
PaymentRequest(
|
||||
orderId: 'order_123',
|
||||
amount: 1000,
|
||||
currency: 'USD',
|
||||
pinCode: '123456',
|
||||
enableBiometric: false, // No biometric for direct
|
||||
),
|
||||
);
|
||||
|
||||
if (result.success) {
|
||||
// Handle success
|
||||
} else {
|
||||
// Handle error
|
||||
}
|
||||
```
|
||||
|
||||
## API Methods
|
||||
|
||||
### `createOrder(CreateOrderRequest)`
|
||||
|
||||
Creates a new payment order on the server.
|
||||
|
||||
**Parameters:**
|
||||
- `amount` (required): Amount in smallest currency unit (cents for USD, etc.)
|
||||
- `currency` (required): Currency code (e.g., 'USD', 'EUR')
|
||||
- `remarks` (optional): Payment description
|
||||
- `payeeWalletId` (optional): Target wallet ID
|
||||
- `appIdentifier` (optional): Mini-app identifier
|
||||
- `meta` (optional): Additional metadata
|
||||
|
||||
**Returns:** `SnWalletOrder?` or throws exception
|
||||
|
||||
### `processPayment({String orderId, String pinCode, bool enableBiometric})`
|
||||
|
||||
Processes a payment for an existing order. Must be called from within mini-app context.
|
||||
|
||||
**Parameters:**
|
||||
- `orderId` (required): Order ID to process
|
||||
- `pinCode` (required): 6-digit PIN code
|
||||
- `enableBiometric` (optional, default: true): Allow biometric authentication
|
||||
|
||||
**Returns:** `SnWalletOrder?` or throws exception
|
||||
|
||||
### `processPaymentWithOverlay({BuildContext, PaymentRequest?, CreateOrderRequest?, bool enableBiometric})`
|
||||
|
||||
Shows payment overlay UI and processes payment. Use this for user-facing payments.
|
||||
|
||||
**Parameters:**
|
||||
- `context` (required): BuildContext for showing overlay
|
||||
- `request` (optional): Existing payment request with orderId
|
||||
- `createOrderRequest` (optional): New order request (must provide one)
|
||||
- `enableBiometric` (optional, default: true): Enable biometric authentication
|
||||
|
||||
**Returns:** `PaymentResult`
|
||||
|
||||
### `processDirectPayment(PaymentRequest)`
|
||||
|
||||
Processes payment without showing UI overlay. Use for automatic/background payments.
|
||||
|
||||
**Parameters:**
|
||||
- `request` (required): PaymentRequest with all details including pinCode
|
||||
|
||||
**Returns:** `PaymentResult`
|
||||
|
||||
## Data Types
|
||||
|
||||
### `PaymentRequest`
|
||||
|
||||
```dart
|
||||
const factory PaymentRequest({
|
||||
required String orderId,
|
||||
required int amount,
|
||||
required String currency,
|
||||
String? remarks,
|
||||
String? payeeWalletId,
|
||||
String? pinCode,
|
||||
@Default(true) bool showOverlay,
|
||||
@Default(true) bool enableBiometric,
|
||||
});
|
||||
```
|
||||
|
||||
### `CreateOrderRequest`
|
||||
|
||||
```dart
|
||||
const factory CreateOrderRequest({
|
||||
required int amount,
|
||||
required String currency,
|
||||
String? remarks,
|
||||
String? payeeWalletId,
|
||||
String? appIdentifier,
|
||||
@Default({}) Map<String, dynamic> meta,
|
||||
});
|
||||
```
|
||||
|
||||
### `PaymentResult`
|
||||
|
||||
```dart
|
||||
const factory PaymentResult({
|
||||
required bool success,
|
||||
SnWalletOrder? order,
|
||||
String? error,
|
||||
String? errorCode,
|
||||
});
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
The API handles common error scenarios:
|
||||
|
||||
- **401/403**: Invalid PIN code
|
||||
- **400**: Payment error with message
|
||||
- **404**: Order not found
|
||||
- **503**: Service unavailable/maintenance
|
||||
- **Network errors**: Connection issues
|
||||
|
||||
## Internals
|
||||
|
||||
The API:
|
||||
- Uses a singleton pattern (`PaymentAPI.instance`)
|
||||
- Manages its own Dio instance with proper interceptors
|
||||
- Reads server URL and token from SharedPreferences
|
||||
- Handles authentication automatically
|
||||
- Reuses existing `PaymentOverlay` widget for UI
|
||||
|
||||
## Complete Example
|
||||
|
||||
```dart
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:island/modular/api/payment.dart';
|
||||
|
||||
class MiniAppPayment extends StatelessWidget {
|
||||
const MiniAppPayment({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Payment Example')),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () => _processWithOverlay(context),
|
||||
child: const Text('Pay $10.00 (with overlay)'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () => _processDirect(context),
|
||||
child: const Text('Pay $10.00 (direct)'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _processWithOverlay(BuildContext context) async {
|
||||
final api = PaymentAPI.instance;
|
||||
|
||||
final result = await api.processPaymentWithOverlay(
|
||||
context: context,
|
||||
createOrderRequest: CreateOrderRequest(
|
||||
amount: 1000, // $10.00
|
||||
currency: 'USD',
|
||||
remarks: 'Test payment from mini-app',
|
||||
appIdentifier: 'com.example.miniapp',
|
||||
),
|
||||
enableBiometric: true,
|
||||
);
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (result.success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Payment successful!')),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Payment failed: ${result.error}'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _processDirect(BuildContext context) async {
|
||||
final api = PaymentAPI.instance;
|
||||
|
||||
final result = await api.processDirectPayment(
|
||||
PaymentRequest(
|
||||
orderId: 'order_${DateTime.now().millisecondsSinceEpoch}',
|
||||
amount: 1000,
|
||||
currency: 'USD',
|
||||
pinCode: '123456', // Should come from user input
|
||||
enableBiometric: false,
|
||||
),
|
||||
);
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
if (result.success) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Payment successful!')),
|
||||
);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Payment failed: ${result.error}'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- All methods are async and return Futures
|
||||
- Errors are thrown as exceptions, catch and handle in your mini-app
|
||||
- PIN codes must be 6 digits
|
||||
- Amount is in smallest currency unit (cents for USD)
|
||||
- Token is managed internally, no need to provide it
|
||||
- Server URL is loaded from app preferences
|
||||
|
||||
## Integration with flutter_eval
|
||||
|
||||
To expose this API to mini-apps loaded via flutter_eval:
|
||||
|
||||
1. Add to plugin registry:
|
||||
```dart
|
||||
// In lib/modular/registry.dart
|
||||
import 'package:island/modular/api/payment.dart';
|
||||
|
||||
Future<PluginLoadResult> loadMiniApp(...) async {
|
||||
// ... existing code ...
|
||||
|
||||
final runtime = Runtime(ByteData.sublistView(bytecode));
|
||||
runtime.addPlugin(flutterEvalPlugin);
|
||||
|
||||
// Register Payment API
|
||||
final paymentAPI = PaymentAPI.instance;
|
||||
// You'll need to create a bridge to expose this to eval
|
||||
|
||||
// ... rest of loading code
|
||||
}
|
||||
```
|
||||
|
||||
2. Mini-app can access API:
|
||||
```dart
|
||||
// mini_app/main.dart
|
||||
final paymentAPI = PaymentAPI.instance; // Will be exposed via bridge
|
||||
```
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- **Never hardcode PIN codes**: Always get from user input
|
||||
- **Use secure storage**: App manages PIN storage securely
|
||||
- **Validate amounts**: Ensure amounts are reasonable
|
||||
- **Handle errors gracefully**: Show user-friendly messages
|
||||
- **Biometric is optional**: Some devices may not support it
|
||||
284
lib/modular/api/payment.dart
Normal file
284
lib/modular/api/payment.dart
Normal file
@@ -0,0 +1,284 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:island/models/auth.dart';
|
||||
import 'package:island/models/wallet.dart';
|
||||
import 'package:island/widgets/payment/payment_overlay.dart';
|
||||
import 'package:island/pods/config.dart';
|
||||
import 'package:island/pods/network.dart';
|
||||
|
||||
part 'payment.freezed.dart';
|
||||
part 'payment.g.dart';
|
||||
|
||||
@freezed
|
||||
sealed class PaymentRequest with _$PaymentRequest {
|
||||
const factory PaymentRequest({
|
||||
required String orderId,
|
||||
required int amount,
|
||||
required String currency,
|
||||
String? remarks,
|
||||
String? payeeWalletId,
|
||||
String? pinCode,
|
||||
@Default(true) bool showOverlay,
|
||||
@Default(true) bool enableBiometric,
|
||||
}) = _PaymentRequest;
|
||||
|
||||
factory PaymentRequest.fromJson(Map<String, dynamic> json) =>
|
||||
_$PaymentRequestFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class PaymentResult with _$PaymentResult {
|
||||
const factory PaymentResult({
|
||||
required bool success,
|
||||
SnWalletOrder? order,
|
||||
String? error,
|
||||
String? errorCode,
|
||||
}) = _PaymentResult;
|
||||
|
||||
factory PaymentResult.fromJson(Map<String, dynamic> json) =>
|
||||
_$PaymentResultFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class CreateOrderRequest with _$CreateOrderRequest {
|
||||
const factory CreateOrderRequest({
|
||||
required int amount,
|
||||
required String currency,
|
||||
String? remarks,
|
||||
String? payeeWalletId,
|
||||
String? appIdentifier,
|
||||
@Default({}) Map<String, dynamic> meta,
|
||||
}) = _CreateOrderRequest;
|
||||
|
||||
factory CreateOrderRequest.fromJson(Map<String, dynamic> json) =>
|
||||
_$CreateOrderRequestFromJson(json);
|
||||
}
|
||||
|
||||
class PaymentAPI {
|
||||
static PaymentAPI? _instance;
|
||||
late Dio _dio;
|
||||
late String _serverUrl;
|
||||
String? _token;
|
||||
|
||||
PaymentAPI._internal();
|
||||
|
||||
static PaymentAPI get instance {
|
||||
_instance ??= PaymentAPI._internal();
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
Future<void> _initialize() async {
|
||||
if (_dio == null) {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_serverUrl =
|
||||
prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
||||
|
||||
final tokenString = prefs.getString(kTokenPairStoreKey);
|
||||
if (tokenString != null) {
|
||||
final appToken = AppToken.fromJson(jsonDecode(tokenString!));
|
||||
_token = await getToken(appToken);
|
||||
}
|
||||
|
||||
_dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: _serverUrl,
|
||||
connectTimeout: const Duration(seconds: 10),
|
||||
receiveTimeout: const Duration(seconds: 10),
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
_dio.interceptors.add(
|
||||
InterceptorsWrapper(
|
||||
onRequest: (options, handler) async {
|
||||
if (_token != null) {
|
||||
options.headers['Authorization'] = 'AtField $_token';
|
||||
}
|
||||
return handler.next(options);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<SnWalletOrder?> createOrder(CreateOrderRequest request) async {
|
||||
await _initialize();
|
||||
|
||||
try {
|
||||
final response = await _dio.post('/pass/orders', data: request.toJson());
|
||||
|
||||
return SnWalletOrder.fromJson(response.data);
|
||||
} catch (e) {
|
||||
throw _parsePaymentError(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<SnWalletOrder?> processPayment({
|
||||
required String orderId,
|
||||
required String pinCode,
|
||||
bool enableBiometric = true,
|
||||
}) async {
|
||||
await _initialize();
|
||||
|
||||
try {
|
||||
final response = await _dio.post(
|
||||
'/pass/orders/$orderId/pay',
|
||||
data: {'pin_code': pinCode},
|
||||
);
|
||||
|
||||
return SnWalletOrder.fromJson(response.data);
|
||||
} catch (e) {
|
||||
throw _parsePaymentError(e);
|
||||
}
|
||||
}
|
||||
|
||||
Future<PaymentResult> processPaymentWithOverlay({
|
||||
required BuildContext context,
|
||||
PaymentRequest? request,
|
||||
CreateOrderRequest? createOrderRequest,
|
||||
bool enableBiometric = true,
|
||||
}) async {
|
||||
try {
|
||||
await _initialize();
|
||||
|
||||
SnWalletOrder order;
|
||||
|
||||
if (request == null && createOrderRequest == null) {
|
||||
return PaymentResult(
|
||||
success: false,
|
||||
error: 'Either request or createOrderRequest must be provided',
|
||||
);
|
||||
}
|
||||
|
||||
if (request != null) {
|
||||
order = (await createOrder(createOrderRequest!))!;
|
||||
} else {
|
||||
order = SnWalletOrder(
|
||||
id: request!.orderId,
|
||||
status: 0,
|
||||
currency: request!.currency,
|
||||
remarks: request!.remarks,
|
||||
appIdentifier: 'mini-app',
|
||||
meta: {},
|
||||
amount: request!.amount,
|
||||
expiredAt: DateTime.now().add(const Duration(hours: 1)),
|
||||
payeeWalletId: request!.payeeWalletId,
|
||||
transactionId: null,
|
||||
issuerAppId: null,
|
||||
createdAt: DateTime.now(),
|
||||
updatedAt: DateTime.now(),
|
||||
deletedAt: null,
|
||||
);
|
||||
}
|
||||
|
||||
final result = await PaymentOverlay.show(
|
||||
context: context,
|
||||
order: order,
|
||||
enableBiometric: enableBiometric,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
return PaymentResult(success: true, order: result);
|
||||
} else {
|
||||
return PaymentResult(
|
||||
success: false,
|
||||
error: 'Payment was cancelled by user',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
final errorMessage = _parsePaymentError(e);
|
||||
return PaymentResult(
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
errorCode: e is DioException
|
||||
? (e as DioException).response?.statusCode.toString()
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<PaymentResult> processDirectPayment(PaymentRequest request) async {
|
||||
await _initialize();
|
||||
|
||||
try {
|
||||
if (request.pinCode == null) {
|
||||
return PaymentResult(
|
||||
success: false,
|
||||
error: 'PIN code is required for direct payment processing',
|
||||
);
|
||||
}
|
||||
|
||||
final result = await processPayment(
|
||||
orderId: request.orderId,
|
||||
pinCode: request.pinCode!,
|
||||
enableBiometric: request.enableBiometric,
|
||||
);
|
||||
|
||||
if (result != null) {
|
||||
return PaymentResult(success: true, order: result);
|
||||
} else {
|
||||
return PaymentResult(success: false, error: 'Payment failed');
|
||||
}
|
||||
} catch (e) {
|
||||
final errorMessage = _parsePaymentError(e);
|
||||
return PaymentResult(
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
errorCode: e is DioException
|
||||
? (e as DioException).response?.statusCode.toString()
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _parsePaymentError(dynamic error) {
|
||||
if (error is DioException) {
|
||||
final dioError = error as DioException;
|
||||
|
||||
if (dioError.response?.statusCode == 403 ||
|
||||
dioError.response?.statusCode == 401) {
|
||||
return 'invalidPin'.tr();
|
||||
} else if (dioError.response?.statusCode == 400) {
|
||||
return dioError.response?.data?['error'] ?? 'paymentFailed'.tr();
|
||||
} else if (dioError.response?.statusCode == 503) {
|
||||
return 'serviceUnavailable'.tr();
|
||||
} else if (dioError.response?.statusCode == 404) {
|
||||
return 'orderNotFound'.tr();
|
||||
}
|
||||
|
||||
return 'networkError'.tr();
|
||||
}
|
||||
|
||||
return error.toString();
|
||||
}
|
||||
|
||||
Future<void> updateServerUrl() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
_serverUrl =
|
||||
prefs.getString(kNetworkServerStoreKey) ?? kNetworkServerDefault;
|
||||
_dio.options.baseUrl = _serverUrl;
|
||||
}
|
||||
|
||||
Future<void> updateToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final tokenString = prefs.getString(kTokenPairStoreKey);
|
||||
if (tokenString != null) {
|
||||
final appToken = AppToken.fromJson(jsonDecode(tokenString!));
|
||||
_token = await getToken(appToken);
|
||||
} else {
|
||||
_token = null;
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
_dio.close();
|
||||
}
|
||||
}
|
||||
860
lib/modular/api/payment.freezed.dart
Normal file
860
lib/modular/api/payment.freezed.dart
Normal file
@@ -0,0 +1,860 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// 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 'payment.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PaymentRequest {
|
||||
|
||||
String get orderId; int get amount; String get currency; String? get remarks; String? get payeeWalletId; String? get pinCode; bool get showOverlay; bool get enableBiometric;
|
||||
/// Create a copy of PaymentRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PaymentRequestCopyWith<PaymentRequest> get copyWith => _$PaymentRequestCopyWithImpl<PaymentRequest>(this as PaymentRequest, _$identity);
|
||||
|
||||
/// Serializes this PaymentRequest to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PaymentRequest&&(identical(other.orderId, orderId) || other.orderId == orderId)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.pinCode, pinCode) || other.pinCode == pinCode)&&(identical(other.showOverlay, showOverlay) || other.showOverlay == showOverlay)&&(identical(other.enableBiometric, enableBiometric) || other.enableBiometric == enableBiometric));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,orderId,amount,currency,remarks,payeeWalletId,pinCode,showOverlay,enableBiometric);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentRequest(orderId: $orderId, amount: $amount, currency: $currency, remarks: $remarks, payeeWalletId: $payeeWalletId, pinCode: $pinCode, showOverlay: $showOverlay, enableBiometric: $enableBiometric)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PaymentRequestCopyWith<$Res> {
|
||||
factory $PaymentRequestCopyWith(PaymentRequest value, $Res Function(PaymentRequest) _then) = _$PaymentRequestCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String orderId, int amount, String currency, String? remarks, String? payeeWalletId, String? pinCode, bool showOverlay, bool enableBiometric
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PaymentRequestCopyWithImpl<$Res>
|
||||
implements $PaymentRequestCopyWith<$Res> {
|
||||
_$PaymentRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PaymentRequest _self;
|
||||
final $Res Function(PaymentRequest) _then;
|
||||
|
||||
/// Create a copy of PaymentRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? orderId = null,Object? amount = null,Object? currency = null,Object? remarks = freezed,Object? payeeWalletId = freezed,Object? pinCode = freezed,Object? showOverlay = null,Object? enableBiometric = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
|
||||
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||
as String?,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,pinCode: freezed == pinCode ? _self.pinCode : pinCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,showOverlay: null == showOverlay ? _self.showOverlay : showOverlay // ignore: cast_nullable_to_non_nullable
|
||||
as bool,enableBiometric: null == enableBiometric ? _self.enableBiometric : enableBiometric // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [PaymentRequest].
|
||||
extension PaymentRequestPatterns on PaymentRequest {
|
||||
/// 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( _PaymentRequest value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest() 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( _PaymentRequest value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _PaymentRequest value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest() 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( String orderId, int amount, String currency, String? remarks, String? payeeWalletId, String? pinCode, bool showOverlay, bool enableBiometric)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest() when $default != null:
|
||||
return $default(_that.orderId,_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.pinCode,_that.showOverlay,_that.enableBiometric);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( String orderId, int amount, String currency, String? remarks, String? payeeWalletId, String? pinCode, bool showOverlay, bool enableBiometric) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest():
|
||||
return $default(_that.orderId,_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.pinCode,_that.showOverlay,_that.enableBiometric);}
|
||||
}
|
||||
/// 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, int amount, String currency, String? remarks, String? payeeWalletId, String? pinCode, bool showOverlay, bool enableBiometric)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentRequest() when $default != null:
|
||||
return $default(_that.orderId,_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.pinCode,_that.showOverlay,_that.enableBiometric);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _PaymentRequest implements PaymentRequest {
|
||||
const _PaymentRequest({required this.orderId, required this.amount, required this.currency, this.remarks, this.payeeWalletId, this.pinCode, this.showOverlay = true, this.enableBiometric = true});
|
||||
factory _PaymentRequest.fromJson(Map<String, dynamic> json) => _$PaymentRequestFromJson(json);
|
||||
|
||||
@override final String orderId;
|
||||
@override final int amount;
|
||||
@override final String currency;
|
||||
@override final String? remarks;
|
||||
@override final String? payeeWalletId;
|
||||
@override final String? pinCode;
|
||||
@override@JsonKey() final bool showOverlay;
|
||||
@override@JsonKey() final bool enableBiometric;
|
||||
|
||||
/// Create a copy of PaymentRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$PaymentRequestCopyWith<_PaymentRequest> get copyWith => __$PaymentRequestCopyWithImpl<_PaymentRequest>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$PaymentRequestToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PaymentRequest&&(identical(other.orderId, orderId) || other.orderId == orderId)&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.pinCode, pinCode) || other.pinCode == pinCode)&&(identical(other.showOverlay, showOverlay) || other.showOverlay == showOverlay)&&(identical(other.enableBiometric, enableBiometric) || other.enableBiometric == enableBiometric));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,orderId,amount,currency,remarks,payeeWalletId,pinCode,showOverlay,enableBiometric);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentRequest(orderId: $orderId, amount: $amount, currency: $currency, remarks: $remarks, payeeWalletId: $payeeWalletId, pinCode: $pinCode, showOverlay: $showOverlay, enableBiometric: $enableBiometric)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$PaymentRequestCopyWith<$Res> implements $PaymentRequestCopyWith<$Res> {
|
||||
factory _$PaymentRequestCopyWith(_PaymentRequest value, $Res Function(_PaymentRequest) _then) = __$PaymentRequestCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String orderId, int amount, String currency, String? remarks, String? payeeWalletId, String? pinCode, bool showOverlay, bool enableBiometric
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$PaymentRequestCopyWithImpl<$Res>
|
||||
implements _$PaymentRequestCopyWith<$Res> {
|
||||
__$PaymentRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _PaymentRequest _self;
|
||||
final $Res Function(_PaymentRequest) _then;
|
||||
|
||||
/// Create a copy of PaymentRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? orderId = null,Object? amount = null,Object? currency = null,Object? remarks = freezed,Object? payeeWalletId = freezed,Object? pinCode = freezed,Object? showOverlay = null,Object? enableBiometric = null,}) {
|
||||
return _then(_PaymentRequest(
|
||||
orderId: null == orderId ? _self.orderId : orderId // ignore: cast_nullable_to_non_nullable
|
||||
as String,amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||
as String?,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,pinCode: freezed == pinCode ? _self.pinCode : pinCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,showOverlay: null == showOverlay ? _self.showOverlay : showOverlay // ignore: cast_nullable_to_non_nullable
|
||||
as bool,enableBiometric: null == enableBiometric ? _self.enableBiometric : enableBiometric // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PaymentResult {
|
||||
|
||||
bool get success; SnWalletOrder? get order; String? get error; String? get errorCode;
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PaymentResultCopyWith<PaymentResult> get copyWith => _$PaymentResultCopyWithImpl<PaymentResult>(this as PaymentResult, _$identity);
|
||||
|
||||
/// Serializes this PaymentResult to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PaymentResult&&(identical(other.success, success) || other.success == success)&&(identical(other.order, order) || other.order == order)&&(identical(other.error, error) || other.error == error)&&(identical(other.errorCode, errorCode) || other.errorCode == errorCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,success,order,error,errorCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentResult(success: $success, order: $order, error: $error, errorCode: $errorCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PaymentResultCopyWith<$Res> {
|
||||
factory $PaymentResultCopyWith(PaymentResult value, $Res Function(PaymentResult) _then) = _$PaymentResultCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool success, SnWalletOrder? order, String? error, String? errorCode
|
||||
});
|
||||
|
||||
|
||||
$SnWalletOrderCopyWith<$Res>? get order;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PaymentResultCopyWithImpl<$Res>
|
||||
implements $PaymentResultCopyWith<$Res> {
|
||||
_$PaymentResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PaymentResult _self;
|
||||
final $Res Function(PaymentResult) _then;
|
||||
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? success = null,Object? order = freezed,Object? error = freezed,Object? errorCode = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as bool,order: freezed == order ? _self.order : order // ignore: cast_nullable_to_non_nullable
|
||||
as SnWalletOrder?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,errorCode: freezed == errorCode ? _self.errorCode : errorCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SnWalletOrderCopyWith<$Res>? get order {
|
||||
if (_self.order == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $SnWalletOrderCopyWith<$Res>(_self.order!, (value) {
|
||||
return _then(_self.copyWith(order: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [PaymentResult].
|
||||
extension PaymentResultPatterns on PaymentResult {
|
||||
/// 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( _PaymentResult value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult() 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( _PaymentResult value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _PaymentResult value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult() 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 success, SnWalletOrder? order, String? error, String? errorCode)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult() when $default != null:
|
||||
return $default(_that.success,_that.order,_that.error,_that.errorCode);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 success, SnWalletOrder? order, String? error, String? errorCode) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult():
|
||||
return $default(_that.success,_that.order,_that.error,_that.errorCode);}
|
||||
}
|
||||
/// 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 success, SnWalletOrder? order, String? error, String? errorCode)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PaymentResult() when $default != null:
|
||||
return $default(_that.success,_that.order,_that.error,_that.errorCode);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _PaymentResult implements PaymentResult {
|
||||
const _PaymentResult({required this.success, this.order, this.error, this.errorCode});
|
||||
factory _PaymentResult.fromJson(Map<String, dynamic> json) => _$PaymentResultFromJson(json);
|
||||
|
||||
@override final bool success;
|
||||
@override final SnWalletOrder? order;
|
||||
@override final String? error;
|
||||
@override final String? errorCode;
|
||||
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$PaymentResultCopyWith<_PaymentResult> get copyWith => __$PaymentResultCopyWithImpl<_PaymentResult>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$PaymentResultToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PaymentResult&&(identical(other.success, success) || other.success == success)&&(identical(other.order, order) || other.order == order)&&(identical(other.error, error) || other.error == error)&&(identical(other.errorCode, errorCode) || other.errorCode == errorCode));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,success,order,error,errorCode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PaymentResult(success: $success, order: $order, error: $error, errorCode: $errorCode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$PaymentResultCopyWith<$Res> implements $PaymentResultCopyWith<$Res> {
|
||||
factory _$PaymentResultCopyWith(_PaymentResult value, $Res Function(_PaymentResult) _then) = __$PaymentResultCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool success, SnWalletOrder? order, String? error, String? errorCode
|
||||
});
|
||||
|
||||
|
||||
@override $SnWalletOrderCopyWith<$Res>? get order;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$PaymentResultCopyWithImpl<$Res>
|
||||
implements _$PaymentResultCopyWith<$Res> {
|
||||
__$PaymentResultCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _PaymentResult _self;
|
||||
final $Res Function(_PaymentResult) _then;
|
||||
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? success = null,Object? order = freezed,Object? error = freezed,Object? errorCode = freezed,}) {
|
||||
return _then(_PaymentResult(
|
||||
success: null == success ? _self.success : success // ignore: cast_nullable_to_non_nullable
|
||||
as bool,order: freezed == order ? _self.order : order // ignore: cast_nullable_to_non_nullable
|
||||
as SnWalletOrder?,error: freezed == error ? _self.error : error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,errorCode: freezed == errorCode ? _self.errorCode : errorCode // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of PaymentResult
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$SnWalletOrderCopyWith<$Res>? get order {
|
||||
if (_self.order == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $SnWalletOrderCopyWith<$Res>(_self.order!, (value) {
|
||||
return _then(_self.copyWith(order: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$CreateOrderRequest {
|
||||
|
||||
int get amount; String get currency; String? get remarks; String? get payeeWalletId; String? get appIdentifier; Map<String, dynamic> get meta;
|
||||
/// Create a copy of CreateOrderRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$CreateOrderRequestCopyWith<CreateOrderRequest> get copyWith => _$CreateOrderRequestCopyWithImpl<CreateOrderRequest>(this as CreateOrderRequest, _$identity);
|
||||
|
||||
/// Serializes this CreateOrderRequest to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is CreateOrderRequest&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other.meta, meta));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,amount,currency,remarks,payeeWalletId,appIdentifier,const DeepCollectionEquality().hash(meta));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CreateOrderRequest(amount: $amount, currency: $currency, remarks: $remarks, payeeWalletId: $payeeWalletId, appIdentifier: $appIdentifier, meta: $meta)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $CreateOrderRequestCopyWith<$Res> {
|
||||
factory $CreateOrderRequestCopyWith(CreateOrderRequest value, $Res Function(CreateOrderRequest) _then) = _$CreateOrderRequestCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
int amount, String currency, String? remarks, String? payeeWalletId, String? appIdentifier, Map<String, dynamic> meta
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$CreateOrderRequestCopyWithImpl<$Res>
|
||||
implements $CreateOrderRequestCopyWith<$Res> {
|
||||
_$CreateOrderRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final CreateOrderRequest _self;
|
||||
final $Res Function(CreateOrderRequest) _then;
|
||||
|
||||
/// Create a copy of CreateOrderRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? amount = null,Object? currency = null,Object? remarks = freezed,Object? payeeWalletId = freezed,Object? appIdentifier = freezed,Object? meta = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||
as String?,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,appIdentifier: freezed == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
||||
as String?,meta: null == meta ? _self.meta : meta // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [CreateOrderRequest].
|
||||
extension CreateOrderRequestPatterns on CreateOrderRequest {
|
||||
/// 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( _CreateOrderRequest value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest() 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( _CreateOrderRequest value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _CreateOrderRequest value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest() 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 amount, String currency, String? remarks, String? payeeWalletId, String? appIdentifier, Map<String, dynamic> meta)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest() when $default != null:
|
||||
return $default(_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.appIdentifier,_that.meta);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 amount, String currency, String? remarks, String? payeeWalletId, String? appIdentifier, Map<String, dynamic> meta) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest():
|
||||
return $default(_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.appIdentifier,_that.meta);}
|
||||
}
|
||||
/// 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 amount, String currency, String? remarks, String? payeeWalletId, String? appIdentifier, Map<String, dynamic> meta)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _CreateOrderRequest() when $default != null:
|
||||
return $default(_that.amount,_that.currency,_that.remarks,_that.payeeWalletId,_that.appIdentifier,_that.meta);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _CreateOrderRequest implements CreateOrderRequest {
|
||||
const _CreateOrderRequest({required this.amount, required this.currency, this.remarks, this.payeeWalletId, this.appIdentifier, final Map<String, dynamic> meta = const {}}): _meta = meta;
|
||||
factory _CreateOrderRequest.fromJson(Map<String, dynamic> json) => _$CreateOrderRequestFromJson(json);
|
||||
|
||||
@override final int amount;
|
||||
@override final String currency;
|
||||
@override final String? remarks;
|
||||
@override final String? payeeWalletId;
|
||||
@override final String? appIdentifier;
|
||||
final Map<String, dynamic> _meta;
|
||||
@override@JsonKey() Map<String, dynamic> get meta {
|
||||
if (_meta is EqualUnmodifiableMapView) return _meta;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(_meta);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of CreateOrderRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$CreateOrderRequestCopyWith<_CreateOrderRequest> get copyWith => __$CreateOrderRequestCopyWithImpl<_CreateOrderRequest>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$CreateOrderRequestToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _CreateOrderRequest&&(identical(other.amount, amount) || other.amount == amount)&&(identical(other.currency, currency) || other.currency == currency)&&(identical(other.remarks, remarks) || other.remarks == remarks)&&(identical(other.payeeWalletId, payeeWalletId) || other.payeeWalletId == payeeWalletId)&&(identical(other.appIdentifier, appIdentifier) || other.appIdentifier == appIdentifier)&&const DeepCollectionEquality().equals(other._meta, _meta));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,amount,currency,remarks,payeeWalletId,appIdentifier,const DeepCollectionEquality().hash(_meta));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CreateOrderRequest(amount: $amount, currency: $currency, remarks: $remarks, payeeWalletId: $payeeWalletId, appIdentifier: $appIdentifier, meta: $meta)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$CreateOrderRequestCopyWith<$Res> implements $CreateOrderRequestCopyWith<$Res> {
|
||||
factory _$CreateOrderRequestCopyWith(_CreateOrderRequest value, $Res Function(_CreateOrderRequest) _then) = __$CreateOrderRequestCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
int amount, String currency, String? remarks, String? payeeWalletId, String? appIdentifier, Map<String, dynamic> meta
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$CreateOrderRequestCopyWithImpl<$Res>
|
||||
implements _$CreateOrderRequestCopyWith<$Res> {
|
||||
__$CreateOrderRequestCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _CreateOrderRequest _self;
|
||||
final $Res Function(_CreateOrderRequest) _then;
|
||||
|
||||
/// Create a copy of CreateOrderRequest
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? amount = null,Object? currency = null,Object? remarks = freezed,Object? payeeWalletId = freezed,Object? appIdentifier = freezed,Object? meta = null,}) {
|
||||
return _then(_CreateOrderRequest(
|
||||
amount: null == amount ? _self.amount : amount // ignore: cast_nullable_to_non_nullable
|
||||
as int,currency: null == currency ? _self.currency : currency // ignore: cast_nullable_to_non_nullable
|
||||
as String,remarks: freezed == remarks ? _self.remarks : remarks // ignore: cast_nullable_to_non_nullable
|
||||
as String?,payeeWalletId: freezed == payeeWalletId ? _self.payeeWalletId : payeeWalletId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,appIdentifier: freezed == appIdentifier ? _self.appIdentifier : appIdentifier // ignore: cast_nullable_to_non_nullable
|
||||
as String?,meta: null == meta ? _self._meta : meta // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, dynamic>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
69
lib/modular/api/payment.g.dart
Normal file
69
lib/modular/api/payment.g.dart
Normal file
@@ -0,0 +1,69 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'payment.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_PaymentRequest _$PaymentRequestFromJson(Map<String, dynamic> json) =>
|
||||
_PaymentRequest(
|
||||
orderId: json['order_id'] as String,
|
||||
amount: (json['amount'] as num).toInt(),
|
||||
currency: json['currency'] as String,
|
||||
remarks: json['remarks'] as String?,
|
||||
payeeWalletId: json['payee_wallet_id'] as String?,
|
||||
pinCode: json['pin_code'] as String?,
|
||||
showOverlay: json['show_overlay'] as bool? ?? true,
|
||||
enableBiometric: json['enable_biometric'] as bool? ?? true,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PaymentRequestToJson(_PaymentRequest instance) =>
|
||||
<String, dynamic>{
|
||||
'order_id': instance.orderId,
|
||||
'amount': instance.amount,
|
||||
'currency': instance.currency,
|
||||
'remarks': instance.remarks,
|
||||
'payee_wallet_id': instance.payeeWalletId,
|
||||
'pin_code': instance.pinCode,
|
||||
'show_overlay': instance.showOverlay,
|
||||
'enable_biometric': instance.enableBiometric,
|
||||
};
|
||||
|
||||
_PaymentResult _$PaymentResultFromJson(Map<String, dynamic> json) =>
|
||||
_PaymentResult(
|
||||
success: json['success'] as bool,
|
||||
order: json['order'] == null
|
||||
? null
|
||||
: SnWalletOrder.fromJson(json['order'] as Map<String, dynamic>),
|
||||
error: json['error'] as String?,
|
||||
errorCode: json['error_code'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PaymentResultToJson(_PaymentResult instance) =>
|
||||
<String, dynamic>{
|
||||
'success': instance.success,
|
||||
'order': instance.order?.toJson(),
|
||||
'error': instance.error,
|
||||
'error_code': instance.errorCode,
|
||||
};
|
||||
|
||||
_CreateOrderRequest _$CreateOrderRequestFromJson(Map<String, dynamic> json) =>
|
||||
_CreateOrderRequest(
|
||||
amount: (json['amount'] as num).toInt(),
|
||||
currency: json['currency'] as String,
|
||||
remarks: json['remarks'] as String?,
|
||||
payeeWalletId: json['payee_wallet_id'] as String?,
|
||||
appIdentifier: json['app_identifier'] as String?,
|
||||
meta: json['meta'] as Map<String, dynamic>? ?? const {},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CreateOrderRequestToJson(_CreateOrderRequest instance) =>
|
||||
<String, dynamic>{
|
||||
'amount': instance.amount,
|
||||
'currency': instance.currency,
|
||||
'remarks': instance.remarks,
|
||||
'payee_wallet_id': instance.payeeWalletId,
|
||||
'app_identifier': instance.appIdentifier,
|
||||
'meta': instance.meta,
|
||||
};
|
||||
72
lib/modular/interface.dart
Normal file
72
lib/modular/interface.dart
Normal file
@@ -0,0 +1,72 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'interface.freezed.dart';
|
||||
part 'interface.g.dart';
|
||||
|
||||
@freezed
|
||||
sealed class PluginMetadata with _$PluginMetadata {
|
||||
const factory PluginMetadata({
|
||||
required String id,
|
||||
required String name,
|
||||
required String version,
|
||||
required String description,
|
||||
String? author,
|
||||
DateTime? updatedAt,
|
||||
}) = _PluginMetadata;
|
||||
|
||||
factory PluginMetadata.fromJson(Map<String, dynamic> json) =>
|
||||
_$PluginMetadataFromJson(json);
|
||||
}
|
||||
|
||||
abstract class Plugin {
|
||||
PluginMetadata get metadata;
|
||||
}
|
||||
|
||||
abstract class RawPlugin extends Plugin {}
|
||||
|
||||
abstract class MiniApp extends Plugin {
|
||||
Widget buildEntry();
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class MiniAppMetadata with _$MiniAppMetadata {
|
||||
const factory MiniAppMetadata({
|
||||
required String id,
|
||||
required String name,
|
||||
required String version,
|
||||
required String description,
|
||||
String? author,
|
||||
String? iconUrl,
|
||||
required String downloadUrl,
|
||||
String? localCachePath,
|
||||
DateTime? lastUpdated,
|
||||
DateTime? lastChecked,
|
||||
@Default(false) bool isEnabled,
|
||||
@Default(0) int localVersion,
|
||||
int? sizeBytes,
|
||||
}) = _MiniAppMetadata;
|
||||
|
||||
factory MiniAppMetadata.fromJson(Map<String, dynamic> json) =>
|
||||
_$MiniAppMetadataFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
sealed class MiniAppServerInfo with _$MiniAppServerInfo {
|
||||
const factory MiniAppServerInfo({
|
||||
required String id,
|
||||
required String name,
|
||||
required String version,
|
||||
required String description,
|
||||
String? author,
|
||||
String? iconUrl,
|
||||
required String downloadUrl,
|
||||
required DateTime updatedAt,
|
||||
required int sizeBytes,
|
||||
}) = _MiniAppServerInfo;
|
||||
|
||||
factory MiniAppServerInfo.fromJson(Map<String, dynamic> json) =>
|
||||
_$MiniAppServerInfoFromJson(json);
|
||||
}
|
||||
|
||||
enum PluginLoadResult { success, failed, alreadyLoaded }
|
||||
860
lib/modular/interface.freezed.dart
Normal file
860
lib/modular/interface.freezed.dart
Normal file
@@ -0,0 +1,860 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// coverage:ignore-file
|
||||
// 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 'interface.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
/// @nodoc
|
||||
mixin _$PluginMetadata {
|
||||
|
||||
String get id; String get name; String get version; String get description; String? get author; DateTime? get updatedAt;
|
||||
/// Create a copy of PluginMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$PluginMetadataCopyWith<PluginMetadata> get copyWith => _$PluginMetadataCopyWithImpl<PluginMetadata>(this as PluginMetadata, _$identity);
|
||||
|
||||
/// Serializes this PluginMetadata to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is PluginMetadata&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PluginMetadata(id: $id, name: $name, version: $version, description: $description, author: $author, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $PluginMetadataCopyWith<$Res> {
|
||||
factory $PluginMetadataCopyWith(PluginMetadata value, $Res Function(PluginMetadata) _then) = _$PluginMetadataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, DateTime? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$PluginMetadataCopyWithImpl<$Res>
|
||||
implements $PluginMetadataCopyWith<$Res> {
|
||||
_$PluginMetadataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final PluginMetadata _self;
|
||||
final $Res Function(PluginMetadata) _then;
|
||||
|
||||
/// Create a copy of PluginMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [PluginMetadata].
|
||||
extension PluginMetadataPatterns on PluginMetadata {
|
||||
/// 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( _PluginMetadata value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata() 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( _PluginMetadata value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _PluginMetadata value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata() 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( String id, String name, String version, String description, String? author, DateTime? updatedAt)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.updatedAt);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( String id, String name, String version, String description, String? author, DateTime? updatedAt) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata():
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.updatedAt);}
|
||||
}
|
||||
/// 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 id, String name, String version, String description, String? author, DateTime? updatedAt)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _PluginMetadata() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.updatedAt);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _PluginMetadata implements PluginMetadata {
|
||||
const _PluginMetadata({required this.id, required this.name, required this.version, required this.description, this.author, this.updatedAt});
|
||||
factory _PluginMetadata.fromJson(Map<String, dynamic> json) => _$PluginMetadataFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String name;
|
||||
@override final String version;
|
||||
@override final String description;
|
||||
@override final String? author;
|
||||
@override final DateTime? updatedAt;
|
||||
|
||||
/// Create a copy of PluginMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$PluginMetadataCopyWith<_PluginMetadata> get copyWith => __$PluginMetadataCopyWithImpl<_PluginMetadata>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$PluginMetadataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _PluginMetadata&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,updatedAt);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'PluginMetadata(id: $id, name: $name, version: $version, description: $description, author: $author, updatedAt: $updatedAt)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$PluginMetadataCopyWith<$Res> implements $PluginMetadataCopyWith<$Res> {
|
||||
factory _$PluginMetadataCopyWith(_PluginMetadata value, $Res Function(_PluginMetadata) _then) = __$PluginMetadataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, DateTime? updatedAt
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$PluginMetadataCopyWithImpl<$Res>
|
||||
implements _$PluginMetadataCopyWith<$Res> {
|
||||
__$PluginMetadataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _PluginMetadata _self;
|
||||
final $Res Function(_PluginMetadata) _then;
|
||||
|
||||
/// Create a copy of PluginMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? updatedAt = freezed,}) {
|
||||
return _then(_PluginMetadata(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,updatedAt: freezed == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MiniAppMetadata {
|
||||
|
||||
String get id; String get name; String get version; String get description; String? get author; String? get iconUrl; String get downloadUrl; String? get localCachePath; DateTime? get lastUpdated; DateTime? get lastChecked; bool get isEnabled; int get localVersion; int? get sizeBytes;
|
||||
/// Create a copy of MiniAppMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$MiniAppMetadataCopyWith<MiniAppMetadata> get copyWith => _$MiniAppMetadataCopyWithImpl<MiniAppMetadata>(this as MiniAppMetadata, _$identity);
|
||||
|
||||
/// Serializes this MiniAppMetadata to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MiniAppMetadata&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.iconUrl, iconUrl) || other.iconUrl == iconUrl)&&(identical(other.downloadUrl, downloadUrl) || other.downloadUrl == downloadUrl)&&(identical(other.localCachePath, localCachePath) || other.localCachePath == localCachePath)&&(identical(other.lastUpdated, lastUpdated) || other.lastUpdated == lastUpdated)&&(identical(other.lastChecked, lastChecked) || other.lastChecked == lastChecked)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled)&&(identical(other.localVersion, localVersion) || other.localVersion == localVersion)&&(identical(other.sizeBytes, sizeBytes) || other.sizeBytes == sizeBytes));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,iconUrl,downloadUrl,localCachePath,lastUpdated,lastChecked,isEnabled,localVersion,sizeBytes);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MiniAppMetadata(id: $id, name: $name, version: $version, description: $description, author: $author, iconUrl: $iconUrl, downloadUrl: $downloadUrl, localCachePath: $localCachePath, lastUpdated: $lastUpdated, lastChecked: $lastChecked, isEnabled: $isEnabled, localVersion: $localVersion, sizeBytes: $sizeBytes)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $MiniAppMetadataCopyWith<$Res> {
|
||||
factory $MiniAppMetadataCopyWith(MiniAppMetadata value, $Res Function(MiniAppMetadata) _then) = _$MiniAppMetadataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, String? localCachePath, DateTime? lastUpdated, DateTime? lastChecked, bool isEnabled, int localVersion, int? sizeBytes
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$MiniAppMetadataCopyWithImpl<$Res>
|
||||
implements $MiniAppMetadataCopyWith<$Res> {
|
||||
_$MiniAppMetadataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final MiniAppMetadata _self;
|
||||
final $Res Function(MiniAppMetadata) _then;
|
||||
|
||||
/// Create a copy of MiniAppMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? iconUrl = freezed,Object? downloadUrl = null,Object? localCachePath = freezed,Object? lastUpdated = freezed,Object? lastChecked = freezed,Object? isEnabled = null,Object? localVersion = null,Object? sizeBytes = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,iconUrl: freezed == iconUrl ? _self.iconUrl : iconUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,downloadUrl: null == downloadUrl ? _self.downloadUrl : downloadUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,localCachePath: freezed == localCachePath ? _self.localCachePath : localCachePath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,lastUpdated: freezed == lastUpdated ? _self.lastUpdated : lastUpdated // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,lastChecked: freezed == lastChecked ? _self.lastChecked : lastChecked // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,localVersion: null == localVersion ? _self.localVersion : localVersion // ignore: cast_nullable_to_non_nullable
|
||||
as int,sizeBytes: freezed == sizeBytes ? _self.sizeBytes : sizeBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [MiniAppMetadata].
|
||||
extension MiniAppMetadataPatterns on MiniAppMetadata {
|
||||
/// 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( _MiniAppMetadata value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata() 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( _MiniAppMetadata value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _MiniAppMetadata value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata() 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( String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, String? localCachePath, DateTime? lastUpdated, DateTime? lastChecked, bool isEnabled, int localVersion, int? sizeBytes)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.localCachePath,_that.lastUpdated,_that.lastChecked,_that.isEnabled,_that.localVersion,_that.sizeBytes);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( String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, String? localCachePath, DateTime? lastUpdated, DateTime? lastChecked, bool isEnabled, int localVersion, int? sizeBytes) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata():
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.localCachePath,_that.lastUpdated,_that.lastChecked,_that.isEnabled,_that.localVersion,_that.sizeBytes);}
|
||||
}
|
||||
/// 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 id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, String? localCachePath, DateTime? lastUpdated, DateTime? lastChecked, bool isEnabled, int localVersion, int? sizeBytes)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppMetadata() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.localCachePath,_that.lastUpdated,_that.lastChecked,_that.isEnabled,_that.localVersion,_that.sizeBytes);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _MiniAppMetadata implements MiniAppMetadata {
|
||||
const _MiniAppMetadata({required this.id, required this.name, required this.version, required this.description, this.author, this.iconUrl, required this.downloadUrl, this.localCachePath, this.lastUpdated, this.lastChecked, this.isEnabled = false, this.localVersion = 0, this.sizeBytes});
|
||||
factory _MiniAppMetadata.fromJson(Map<String, dynamic> json) => _$MiniAppMetadataFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String name;
|
||||
@override final String version;
|
||||
@override final String description;
|
||||
@override final String? author;
|
||||
@override final String? iconUrl;
|
||||
@override final String downloadUrl;
|
||||
@override final String? localCachePath;
|
||||
@override final DateTime? lastUpdated;
|
||||
@override final DateTime? lastChecked;
|
||||
@override@JsonKey() final bool isEnabled;
|
||||
@override@JsonKey() final int localVersion;
|
||||
@override final int? sizeBytes;
|
||||
|
||||
/// Create a copy of MiniAppMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$MiniAppMetadataCopyWith<_MiniAppMetadata> get copyWith => __$MiniAppMetadataCopyWithImpl<_MiniAppMetadata>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$MiniAppMetadataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MiniAppMetadata&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.iconUrl, iconUrl) || other.iconUrl == iconUrl)&&(identical(other.downloadUrl, downloadUrl) || other.downloadUrl == downloadUrl)&&(identical(other.localCachePath, localCachePath) || other.localCachePath == localCachePath)&&(identical(other.lastUpdated, lastUpdated) || other.lastUpdated == lastUpdated)&&(identical(other.lastChecked, lastChecked) || other.lastChecked == lastChecked)&&(identical(other.isEnabled, isEnabled) || other.isEnabled == isEnabled)&&(identical(other.localVersion, localVersion) || other.localVersion == localVersion)&&(identical(other.sizeBytes, sizeBytes) || other.sizeBytes == sizeBytes));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,iconUrl,downloadUrl,localCachePath,lastUpdated,lastChecked,isEnabled,localVersion,sizeBytes);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MiniAppMetadata(id: $id, name: $name, version: $version, description: $description, author: $author, iconUrl: $iconUrl, downloadUrl: $downloadUrl, localCachePath: $localCachePath, lastUpdated: $lastUpdated, lastChecked: $lastChecked, isEnabled: $isEnabled, localVersion: $localVersion, sizeBytes: $sizeBytes)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$MiniAppMetadataCopyWith<$Res> implements $MiniAppMetadataCopyWith<$Res> {
|
||||
factory _$MiniAppMetadataCopyWith(_MiniAppMetadata value, $Res Function(_MiniAppMetadata) _then) = __$MiniAppMetadataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, String? localCachePath, DateTime? lastUpdated, DateTime? lastChecked, bool isEnabled, int localVersion, int? sizeBytes
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$MiniAppMetadataCopyWithImpl<$Res>
|
||||
implements _$MiniAppMetadataCopyWith<$Res> {
|
||||
__$MiniAppMetadataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _MiniAppMetadata _self;
|
||||
final $Res Function(_MiniAppMetadata) _then;
|
||||
|
||||
/// Create a copy of MiniAppMetadata
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? iconUrl = freezed,Object? downloadUrl = null,Object? localCachePath = freezed,Object? lastUpdated = freezed,Object? lastChecked = freezed,Object? isEnabled = null,Object? localVersion = null,Object? sizeBytes = freezed,}) {
|
||||
return _then(_MiniAppMetadata(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,iconUrl: freezed == iconUrl ? _self.iconUrl : iconUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,downloadUrl: null == downloadUrl ? _self.downloadUrl : downloadUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,localCachePath: freezed == localCachePath ? _self.localCachePath : localCachePath // ignore: cast_nullable_to_non_nullable
|
||||
as String?,lastUpdated: freezed == lastUpdated ? _self.lastUpdated : lastUpdated // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,lastChecked: freezed == lastChecked ? _self.lastChecked : lastChecked // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime?,isEnabled: null == isEnabled ? _self.isEnabled : isEnabled // ignore: cast_nullable_to_non_nullable
|
||||
as bool,localVersion: null == localVersion ? _self.localVersion : localVersion // ignore: cast_nullable_to_non_nullable
|
||||
as int,sizeBytes: freezed == sizeBytes ? _self.sizeBytes : sizeBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MiniAppServerInfo {
|
||||
|
||||
String get id; String get name; String get version; String get description; String? get author; String? get iconUrl; String get downloadUrl; DateTime get updatedAt; int get sizeBytes;
|
||||
/// Create a copy of MiniAppServerInfo
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$MiniAppServerInfoCopyWith<MiniAppServerInfo> get copyWith => _$MiniAppServerInfoCopyWithImpl<MiniAppServerInfo>(this as MiniAppServerInfo, _$identity);
|
||||
|
||||
/// Serializes this MiniAppServerInfo to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is MiniAppServerInfo&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.iconUrl, iconUrl) || other.iconUrl == iconUrl)&&(identical(other.downloadUrl, downloadUrl) || other.downloadUrl == downloadUrl)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.sizeBytes, sizeBytes) || other.sizeBytes == sizeBytes));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,iconUrl,downloadUrl,updatedAt,sizeBytes);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MiniAppServerInfo(id: $id, name: $name, version: $version, description: $description, author: $author, iconUrl: $iconUrl, downloadUrl: $downloadUrl, updatedAt: $updatedAt, sizeBytes: $sizeBytes)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $MiniAppServerInfoCopyWith<$Res> {
|
||||
factory $MiniAppServerInfoCopyWith(MiniAppServerInfo value, $Res Function(MiniAppServerInfo) _then) = _$MiniAppServerInfoCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, DateTime updatedAt, int sizeBytes
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$MiniAppServerInfoCopyWithImpl<$Res>
|
||||
implements $MiniAppServerInfoCopyWith<$Res> {
|
||||
_$MiniAppServerInfoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final MiniAppServerInfo _self;
|
||||
final $Res Function(MiniAppServerInfo) _then;
|
||||
|
||||
/// Create a copy of MiniAppServerInfo
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? iconUrl = freezed,Object? downloadUrl = null,Object? updatedAt = null,Object? sizeBytes = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,iconUrl: freezed == iconUrl ? _self.iconUrl : iconUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,downloadUrl: null == downloadUrl ? _self.downloadUrl : downloadUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,sizeBytes: null == sizeBytes ? _self.sizeBytes : sizeBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [MiniAppServerInfo].
|
||||
extension MiniAppServerInfoPatterns on MiniAppServerInfo {
|
||||
/// 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( _MiniAppServerInfo value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo() 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( _MiniAppServerInfo value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// 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( _MiniAppServerInfo value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo() 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( String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, DateTime updatedAt, int sizeBytes)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.updatedAt,_that.sizeBytes);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( String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, DateTime updatedAt, int sizeBytes) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo():
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.updatedAt,_that.sizeBytes);}
|
||||
}
|
||||
/// 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 id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, DateTime updatedAt, int sizeBytes)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _MiniAppServerInfo() when $default != null:
|
||||
return $default(_that.id,_that.name,_that.version,_that.description,_that.author,_that.iconUrl,_that.downloadUrl,_that.updatedAt,_that.sizeBytes);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _MiniAppServerInfo implements MiniAppServerInfo {
|
||||
const _MiniAppServerInfo({required this.id, required this.name, required this.version, required this.description, this.author, this.iconUrl, required this.downloadUrl, required this.updatedAt, required this.sizeBytes});
|
||||
factory _MiniAppServerInfo.fromJson(Map<String, dynamic> json) => _$MiniAppServerInfoFromJson(json);
|
||||
|
||||
@override final String id;
|
||||
@override final String name;
|
||||
@override final String version;
|
||||
@override final String description;
|
||||
@override final String? author;
|
||||
@override final String? iconUrl;
|
||||
@override final String downloadUrl;
|
||||
@override final DateTime updatedAt;
|
||||
@override final int sizeBytes;
|
||||
|
||||
/// Create a copy of MiniAppServerInfo
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$MiniAppServerInfoCopyWith<_MiniAppServerInfo> get copyWith => __$MiniAppServerInfoCopyWithImpl<_MiniAppServerInfo>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$MiniAppServerInfoToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _MiniAppServerInfo&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.version, version) || other.version == version)&&(identical(other.description, description) || other.description == description)&&(identical(other.author, author) || other.author == author)&&(identical(other.iconUrl, iconUrl) || other.iconUrl == iconUrl)&&(identical(other.downloadUrl, downloadUrl) || other.downloadUrl == downloadUrl)&&(identical(other.updatedAt, updatedAt) || other.updatedAt == updatedAt)&&(identical(other.sizeBytes, sizeBytes) || other.sizeBytes == sizeBytes));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,id,name,version,description,author,iconUrl,downloadUrl,updatedAt,sizeBytes);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MiniAppServerInfo(id: $id, name: $name, version: $version, description: $description, author: $author, iconUrl: $iconUrl, downloadUrl: $downloadUrl, updatedAt: $updatedAt, sizeBytes: $sizeBytes)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$MiniAppServerInfoCopyWith<$Res> implements $MiniAppServerInfoCopyWith<$Res> {
|
||||
factory _$MiniAppServerInfoCopyWith(_MiniAppServerInfo value, $Res Function(_MiniAppServerInfo) _then) = __$MiniAppServerInfoCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String id, String name, String version, String description, String? author, String? iconUrl, String downloadUrl, DateTime updatedAt, int sizeBytes
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$MiniAppServerInfoCopyWithImpl<$Res>
|
||||
implements _$MiniAppServerInfoCopyWith<$Res> {
|
||||
__$MiniAppServerInfoCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _MiniAppServerInfo _self;
|
||||
final $Res Function(_MiniAppServerInfo) _then;
|
||||
|
||||
/// Create a copy of MiniAppServerInfo
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? version = null,Object? description = null,Object? author = freezed,Object? iconUrl = freezed,Object? downloadUrl = null,Object? updatedAt = null,Object? sizeBytes = null,}) {
|
||||
return _then(_MiniAppServerInfo(
|
||||
id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as String,description: null == description ? _self.description : description // ignore: cast_nullable_to_non_nullable
|
||||
as String,author: freezed == author ? _self.author : author // ignore: cast_nullable_to_non_nullable
|
||||
as String?,iconUrl: freezed == iconUrl ? _self.iconUrl : iconUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,downloadUrl: null == downloadUrl ? _self.downloadUrl : downloadUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String,updatedAt: null == updatedAt ? _self.updatedAt : updatedAt // ignore: cast_nullable_to_non_nullable
|
||||
as DateTime,sizeBytes: null == sizeBytes ? _self.sizeBytes : sizeBytes // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
93
lib/modular/interface.g.dart
Normal file
93
lib/modular/interface.g.dart
Normal file
@@ -0,0 +1,93 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'interface.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_PluginMetadata _$PluginMetadataFromJson(Map<String, dynamic> json) =>
|
||||
_PluginMetadata(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
version: json['version'] as String,
|
||||
description: json['description'] as String,
|
||||
author: json['author'] as String?,
|
||||
updatedAt: json['updated_at'] == null
|
||||
? null
|
||||
: DateTime.parse(json['updated_at'] as String),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$PluginMetadataToJson(_PluginMetadata instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'version': instance.version,
|
||||
'description': instance.description,
|
||||
'author': instance.author,
|
||||
'updated_at': instance.updatedAt?.toIso8601String(),
|
||||
};
|
||||
|
||||
_MiniAppMetadata _$MiniAppMetadataFromJson(Map<String, dynamic> json) =>
|
||||
_MiniAppMetadata(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
version: json['version'] as String,
|
||||
description: json['description'] as String,
|
||||
author: json['author'] as String?,
|
||||
iconUrl: json['icon_url'] as String?,
|
||||
downloadUrl: json['download_url'] as String,
|
||||
localCachePath: json['local_cache_path'] as String?,
|
||||
lastUpdated: json['last_updated'] == null
|
||||
? null
|
||||
: DateTime.parse(json['last_updated'] as String),
|
||||
lastChecked: json['last_checked'] == null
|
||||
? null
|
||||
: DateTime.parse(json['last_checked'] as String),
|
||||
isEnabled: json['is_enabled'] as bool? ?? false,
|
||||
localVersion: (json['local_version'] as num?)?.toInt() ?? 0,
|
||||
sizeBytes: (json['size_bytes'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MiniAppMetadataToJson(_MiniAppMetadata instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'version': instance.version,
|
||||
'description': instance.description,
|
||||
'author': instance.author,
|
||||
'icon_url': instance.iconUrl,
|
||||
'download_url': instance.downloadUrl,
|
||||
'local_cache_path': instance.localCachePath,
|
||||
'last_updated': instance.lastUpdated?.toIso8601String(),
|
||||
'last_checked': instance.lastChecked?.toIso8601String(),
|
||||
'is_enabled': instance.isEnabled,
|
||||
'local_version': instance.localVersion,
|
||||
'size_bytes': instance.sizeBytes,
|
||||
};
|
||||
|
||||
_MiniAppServerInfo _$MiniAppServerInfoFromJson(Map<String, dynamic> json) =>
|
||||
_MiniAppServerInfo(
|
||||
id: json['id'] as String,
|
||||
name: json['name'] as String,
|
||||
version: json['version'] as String,
|
||||
description: json['description'] as String,
|
||||
author: json['author'] as String?,
|
||||
iconUrl: json['icon_url'] as String?,
|
||||
downloadUrl: json['download_url'] as String,
|
||||
updatedAt: DateTime.parse(json['updated_at'] as String),
|
||||
sizeBytes: (json['size_bytes'] as num).toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MiniAppServerInfoToJson(_MiniAppServerInfo instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'version': instance.version,
|
||||
'description': instance.description,
|
||||
'author': instance.author,
|
||||
'icon_url': instance.iconUrl,
|
||||
'download_url': instance.downloadUrl,
|
||||
'updated_at': instance.updatedAt.toIso8601String(),
|
||||
'size_bytes': instance.sizeBytes,
|
||||
};
|
||||
199
lib/modular/miniapp_loader.dart
Normal file
199
lib/modular/miniapp_loader.dart
Normal file
@@ -0,0 +1,199 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_eval/flutter_eval.dart';
|
||||
import 'package:island/modular/interface.dart';
|
||||
import 'package:island/pods/plugin_registry.dart';
|
||||
import 'package:island/talker.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/dart_miniapp_display.dart';
|
||||
import 'package:island/widgets/miniapp_modal.dart';
|
||||
|
||||
typedef ProgressCallback = void Function(double progress, String message);
|
||||
|
||||
final flutterEvalPlugin = FlutterEvalPlugin();
|
||||
|
||||
class MiniappLoader {
|
||||
static Future<void> loadMiniappFromSource(
|
||||
BuildContext context,
|
||||
WidgetRef ref, {
|
||||
ProgressCallback? onProgress,
|
||||
}) async {
|
||||
try {
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: ['dart', 'evc'],
|
||||
withData: true,
|
||||
);
|
||||
|
||||
if (result == null || result.files.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final file = result.files.first;
|
||||
final fileName = file.name;
|
||||
|
||||
if (fileName.endsWith('.dart')) {
|
||||
await _loadDartSource(context, file, fileName);
|
||||
} else if (fileName.endsWith('.evc')) {
|
||||
await _loadBytecodeFile(context, ref, file, fileName, onProgress);
|
||||
} else {
|
||||
showErrorAlert('Unsupported file type. Please use .dart or .evc files');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
talker.error('[MiniappLoader] Failed to load from source', e, stackTrace);
|
||||
showErrorAlert('Failed to load miniapp: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _loadDartSource(
|
||||
BuildContext context,
|
||||
PlatformFile file,
|
||||
String fileName,
|
||||
) async {
|
||||
try {
|
||||
final sourceCode = file.bytes;
|
||||
|
||||
if (sourceCode == null) {
|
||||
showErrorAlert('Unable to read file contents');
|
||||
return;
|
||||
}
|
||||
|
||||
final package = _generatePackageName(fileName);
|
||||
|
||||
await showModalBottomSheet<void>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
useSafeArea: true,
|
||||
builder: (modalContext) {
|
||||
return DartMiniappDisplay(
|
||||
package: package,
|
||||
sourceCode: String.fromCharCodes(sourceCode),
|
||||
);
|
||||
},
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
talker.error('[MiniappLoader] Failed to load dart source', e, stackTrace);
|
||||
showErrorAlert('Failed to load miniapp: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> _loadBytecodeFile(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
PlatformFile file,
|
||||
String fileName,
|
||||
ProgressCallback? onProgress,
|
||||
) async {
|
||||
try {
|
||||
final bytecode = file.bytes;
|
||||
|
||||
if (bytecode == null) {
|
||||
showErrorAlert('Unable to read file contents');
|
||||
return;
|
||||
}
|
||||
|
||||
if (onProgress != null) {
|
||||
onProgress(0.3, 'Saving bytecode...');
|
||||
}
|
||||
|
||||
final registryNotifier = ref.read(pluginRegistryProvider.notifier);
|
||||
final cacheDirPath = await registryNotifier.getMiniAppCacheDirectory();
|
||||
final appId = _generateAppId(fileName);
|
||||
final cachePath = '$cacheDirPath/$appId.evc';
|
||||
|
||||
final cacheFile = File(cachePath);
|
||||
await cacheFile.writeAsBytes(bytecode);
|
||||
|
||||
if (onProgress != null) {
|
||||
onProgress(0.5, 'Loading miniapp...');
|
||||
}
|
||||
|
||||
final metadata = MiniAppMetadata(
|
||||
id: appId,
|
||||
name: appId,
|
||||
version: '0.0.1-dev',
|
||||
description: 'Loaded from file: $fileName',
|
||||
downloadUrl: '',
|
||||
localCachePath: cachePath,
|
||||
lastUpdated: DateTime.now(),
|
||||
isEnabled: true,
|
||||
);
|
||||
|
||||
final success = await registryNotifier.loadMiniappFromCache(
|
||||
metadata,
|
||||
onProgress: onProgress,
|
||||
);
|
||||
|
||||
if (success && context.mounted) {
|
||||
if (onProgress != null) {
|
||||
onProgress(1.0, 'Loaded successfully');
|
||||
}
|
||||
showInfoAlert('Miniapp loaded successfully from file', 'Load Complete');
|
||||
await showMiniappModal(context, ref, appId);
|
||||
} else {
|
||||
showErrorAlert('Failed to load miniapp');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
talker.error(
|
||||
'[MiniappLoader] Failed to load bytecode file',
|
||||
e,
|
||||
stackTrace,
|
||||
);
|
||||
showErrorAlert('Failed to load miniapp: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> loadMiniappFromUrl(
|
||||
BuildContext context,
|
||||
WidgetRef ref,
|
||||
String url, {
|
||||
ProgressCallback? onProgress,
|
||||
}) async {
|
||||
try {
|
||||
if (onProgress != null) {
|
||||
onProgress(0.1, 'Downloading from URL...');
|
||||
}
|
||||
|
||||
final registryNotifier = ref.read(pluginRegistryProvider.notifier);
|
||||
final success = await registryNotifier.loadMiniappFromUrl(
|
||||
url,
|
||||
onProgress: onProgress,
|
||||
);
|
||||
|
||||
if (success) {
|
||||
if (onProgress != null) {
|
||||
onProgress(1.0, 'Loaded successfully');
|
||||
}
|
||||
showInfoAlert('Miniapp loaded successfully from URL', 'Load Complete');
|
||||
|
||||
if (context.mounted) {
|
||||
final appId = registryNotifier.generateAppIdFromUrl(url);
|
||||
await showMiniappModal(context, ref, appId);
|
||||
}
|
||||
} else {
|
||||
showErrorAlert('Failed to load miniapp');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
talker.error('[MiniappLoader] Failed to load from URL', e, stackTrace);
|
||||
showErrorAlert('Failed to load miniapp: $e');
|
||||
}
|
||||
}
|
||||
|
||||
static String _generateAppId(String fileName) {
|
||||
final baseName = fileName
|
||||
.replaceAll('.dart', '')
|
||||
.replaceAll('.evc', '')
|
||||
.replaceAll(RegExp(r'[^\w-]'), '_');
|
||||
return 'dev_${baseName}_${DateTime.now().millisecondsSinceEpoch}';
|
||||
}
|
||||
|
||||
static String _generatePackageName(String fileName) {
|
||||
final baseName = fileName
|
||||
.replaceAll('.dart', '')
|
||||
.replaceAll(RegExp(r'[^\w-]'), '_');
|
||||
return 'dev_${baseName}_${DateTime.now().millisecondsSinceEpoch}';
|
||||
}
|
||||
}
|
||||
209
lib/modular/registry.dart
Normal file
209
lib/modular/registry.dart
Normal file
@@ -0,0 +1,209 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:island/modular/interface.dart';
|
||||
import 'package:island/talker.dart';
|
||||
|
||||
typedef ProgressCallback = void Function(double progress, String message);
|
||||
|
||||
dynamic flutterEvalPlugin;
|
||||
|
||||
class Runtime {
|
||||
final ByteData bytecode;
|
||||
|
||||
Runtime(this.bytecode);
|
||||
|
||||
void addPlugin(dynamic plugin) {}
|
||||
|
||||
dynamic executeLib(String package, String function) {
|
||||
return null;
|
||||
}
|
||||
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
class PluginRegistry {
|
||||
final Map<String, RawPlugin> _rawPlugins = {};
|
||||
final Map<String, MiniApp> _miniApps = {};
|
||||
|
||||
Map<String, RawPlugin> get rawPlugins => Map.unmodifiable(_rawPlugins);
|
||||
Map<String, MiniApp> get miniApps => Map.unmodifiable(_miniApps);
|
||||
|
||||
void registerRawPlugin(RawPlugin plugin) {
|
||||
_rawPlugins[plugin.metadata.id] = plugin;
|
||||
talker.info(
|
||||
'[PluginRegistry] Registered raw plugin: ${plugin.metadata.id}',
|
||||
);
|
||||
}
|
||||
|
||||
void unregisterRawPlugin(String id) {
|
||||
_rawPlugins.remove(id);
|
||||
talker.info('[PluginRegistry] Unregistered raw plugin: $id');
|
||||
}
|
||||
|
||||
RawPlugin? getRawPlugin(String id) {
|
||||
return _rawPlugins[id];
|
||||
}
|
||||
|
||||
Future<PluginLoadResult> loadMiniApp(
|
||||
MiniAppMetadata metadata, {
|
||||
ProgressCallback? onProgress,
|
||||
}) async {
|
||||
if (_miniApps.containsKey(metadata.id)) {
|
||||
return PluginLoadResult.alreadyLoaded;
|
||||
}
|
||||
|
||||
try {
|
||||
talker.info('[PluginRegistry] Loading mini-app: ${metadata.id}');
|
||||
|
||||
if (metadata.localCachePath == null) {
|
||||
talker.warning(
|
||||
'[PluginRegistry] Mini-app has no cache path: ${metadata.id}',
|
||||
);
|
||||
return PluginLoadResult.failed;
|
||||
}
|
||||
|
||||
final file = File(metadata.localCachePath!);
|
||||
if (!await file.exists()) {
|
||||
talker.warning(
|
||||
'[PluginRegistry] Mini-app cache file not found: ${metadata.localCachePath}',
|
||||
);
|
||||
return PluginLoadResult.failed;
|
||||
}
|
||||
|
||||
final bytecode = await file.readAsBytes();
|
||||
|
||||
if (onProgress != null) {
|
||||
onProgress(0.5, 'Initializing runtime...');
|
||||
}
|
||||
|
||||
final runtime = Runtime(ByteData.sublistView(bytecode));
|
||||
runtime.addPlugin(flutterEvalPlugin);
|
||||
|
||||
if (onProgress != null) {
|
||||
onProgress(0.8, 'Building entry widget...');
|
||||
}
|
||||
|
||||
final entryFunction = runtime.executeLib(
|
||||
'package:mini_app/main.dart',
|
||||
'buildEntry',
|
||||
);
|
||||
|
||||
if (entryFunction == null) {
|
||||
talker.error(
|
||||
'[PluginRegistry] Failed to get entry function for mini-app: ${metadata.id}',
|
||||
);
|
||||
return PluginLoadResult.failed;
|
||||
}
|
||||
|
||||
final miniApp = EvaluatedMiniApp(
|
||||
appMetadata: metadata,
|
||||
entryFunction: entryFunction,
|
||||
runtime: runtime,
|
||||
);
|
||||
|
||||
_miniApps[metadata.id] = miniApp;
|
||||
|
||||
if (onProgress != null) {
|
||||
onProgress(1.0, 'Loaded successfully');
|
||||
}
|
||||
|
||||
talker.info(
|
||||
'[PluginRegistry] Successfully loaded mini-app: ${metadata.id}',
|
||||
);
|
||||
return PluginLoadResult.success;
|
||||
} catch (e, stackTrace) {
|
||||
talker.error(
|
||||
'[PluginRegistry] Failed to load mini-app: ${metadata.id}',
|
||||
e,
|
||||
stackTrace,
|
||||
);
|
||||
return PluginLoadResult.failed;
|
||||
}
|
||||
}
|
||||
|
||||
void unloadMiniApp(String id) {
|
||||
final miniApp = _miniApps[id];
|
||||
if (miniApp != null) {
|
||||
if (miniApp is EvaluatedMiniApp) {
|
||||
miniApp.runtime.dispose();
|
||||
}
|
||||
_miniApps.remove(id);
|
||||
talker.info('[PluginRegistry] Unloaded mini-app: $id');
|
||||
}
|
||||
}
|
||||
|
||||
MiniApp? getMiniApp(String id) {
|
||||
return _miniApps[id];
|
||||
}
|
||||
|
||||
Future<String> getMiniAppCacheDirectory() async {
|
||||
final appDocDir = await getApplicationDocumentsDirectory();
|
||||
final cacheDir = Directory('${appDocDir.path}/mini_apps');
|
||||
if (!await cacheDir.exists()) {
|
||||
await cacheDir.create(recursive: true);
|
||||
}
|
||||
return cacheDir.path;
|
||||
}
|
||||
|
||||
String getMiniAppCachePath(String id) {
|
||||
return '$id.evc';
|
||||
}
|
||||
|
||||
Future<void> clearMiniAppCache() async {
|
||||
final cacheDirPath = await getMiniAppCacheDirectory();
|
||||
final cacheDir = Directory(cacheDirPath);
|
||||
if (await cacheDir.exists()) {
|
||||
await cacheDir.delete(recursive: true);
|
||||
await cacheDir.create(recursive: true);
|
||||
talker.info('[PluginRegistry] Cleared mini-app cache');
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
for (final miniApp in _miniApps.values) {
|
||||
if (miniApp is EvaluatedMiniApp) {
|
||||
miniApp.runtime.dispose();
|
||||
}
|
||||
}
|
||||
_miniApps.clear();
|
||||
_rawPlugins.clear();
|
||||
talker.info('[PluginRegistry] Disposed');
|
||||
}
|
||||
}
|
||||
|
||||
class EvaluatedMiniApp extends MiniApp {
|
||||
final MiniAppMetadata appMetadata;
|
||||
final dynamic entryFunction;
|
||||
final Runtime runtime;
|
||||
|
||||
EvaluatedMiniApp({
|
||||
required this.appMetadata,
|
||||
required this.entryFunction,
|
||||
required this.runtime,
|
||||
});
|
||||
|
||||
@override
|
||||
PluginMetadata get metadata => appMetadata as PluginMetadata;
|
||||
|
||||
@override
|
||||
Widget buildEntry() {
|
||||
try {
|
||||
final result = entryFunction();
|
||||
if (result is Widget) {
|
||||
return result;
|
||||
}
|
||||
talker.warning(
|
||||
'[MiniApp] Entry function did not return a Widget: $result',
|
||||
);
|
||||
return const SizedBox.shrink();
|
||||
} catch (e, stackTrace) {
|
||||
talker.error('[MiniApp] Failed to build entry widget', e, stackTrace);
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user