Skip to content

Commit

Permalink
Merge pull request #17 from TBD54566975/dyanmic_pfis
Browse files Browse the repository at this point in the history
load PFIs from known source and cache as shared preference
  • Loading branch information
wesbillman authored Jan 26, 2024
2 parents 25f7435 + 8afcd37 commit bfc3911
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The aim is that this app can work with any tbdex liquidity node, discoverying th

* Install Hermit https://cashapp.github.io/hermit/ (on macos you can run `brew install hermit` and then `hermit shell-hooks`)
* Ensure you have a mobile app simulator handy (XCode on macOS and runing the Simulator app will do for example)
* Run `flutter run` from this project to build and start the app in the simulator
* Run `flutter run` from this project to build and start the app in the simulator. Use `flutter run --dart-define=DEV_PFI=your_did_string` to run against a local tbdex liquidity node at dev time.



Expand Down
7 changes: 7 additions & 0 deletions frontend/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- web5_flutter (0.0.1):
- Flutter
- webview_flutter_wkwebview (0.0.1):
Expand All @@ -14,6 +17,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- web5_flutter (from `.symlinks/plugins/web5_flutter/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)

Expand All @@ -24,6 +28,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_secure_storage/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
web5_flutter:
:path: ".symlinks/plugins/web5_flutter/ios"
webview_flutter_wkwebview:
Expand All @@ -33,6 +39,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
web5_flutter: 9d0f3466d7bef47a35cf92aca8dbb30465c63d2e
webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a

Expand Down
104 changes: 85 additions & 19 deletions frontend/lib/features/pfis/pfi_providers.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,88 @@
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter_starter/features/pfis/pfi.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';

final pfisProvider = Provider<List<Pfi>>(
(ref) => [
Pfi(
id: 'prototype',
name: 'Prototype',
didUri: 'did:dht:74hg1efatndi8enx3e4z6c4u8ieh1xfkyay4ntg4dg1w6risu35y',
),
Pfi(
id: 'africa',
name: 'Africa',
didUri: 'coming soon...',
),
Pfi(
id: 'mexico',
name: 'Mexico',
didUri: 'coming soon...',
),
],
);
final pfisProvider = FutureProvider<List<Pfi>>((ref) async {
const url = 'https://raw.githubusercontent.com/TBD54566975/pfi-providers-data/main/pfis.json';
const cacheKey = 'pfi_cache';


// fall back to a dev PFI if passed on command line like: flutter run --dart-define=DEV_PFI=your_did_string
const devPfi = String.fromEnvironment('DEV_PFI');
if (devPfi != '' && devPfi != null) {
return [
Pfi(
id: 'dev',
name: 'Dev PFI',
didUri: devPfi,
),
];
}

// First, try loading from cache
List<Pfi> pfis = await _loadFromCache(cacheKey);
if (pfis.isNotEmpty) {
// If cache has data, return it first
// Then, asynchronously refresh the cache
_refreshCache(url, cacheKey);
return pfis;
} else {
// If cache is empty, fetch from the URL
return await _fetchFromURL(url, cacheKey);
}
});

Future<List<Pfi>> _loadFromCache(String cacheKey) async {
final prefs = await SharedPreferences.getInstance();
String? cachedData = prefs.getString(cacheKey);

if (cachedData != null) {
return (json.decode(cachedData) as List).map((data) {
return Pfi(
id: data['id'] as String,
name: data['name'] as String,
didUri: data['didUri'] as String,
);
}).toList();
} else {
return [];
}
}

Future<List<Pfi>> _fetchFromURL(String url, String cacheKey) async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(cacheKey, response.body);

return (json.decode(response.body) as List).map((data) {
return Pfi(
id: data['id'] as String,
name: data['name'] as String,
didUri: data['didUri'] as String,
);
}).toList();
}
} catch (e) {
// Handle the error or return an empty list
debugPrint(e.toString());
}
return [];
}

Future<void> _refreshCache(String url, String cacheKey) async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(cacheKey, response.body);
}
} catch (e) {
// Handle the error silently as this is a background refresh
debugPrint(e.toString());
}
}
42 changes: 24 additions & 18 deletions frontend/lib/features/pfis/pfis_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,32 @@ class PfisPage extends HookConsumerWidget {

@override
Widget build(BuildContext context, WidgetRef ref) {
final pfis = ref.watch(pfisProvider);
// Watch the provider and get the AsyncValue object

return Scaffold(
appBar: AppBar(title: Text(Loc.of(context).selectYourRegion)),
body: ListView(
children: [
...pfis.map(
(pfi) => ListTile(
title: Text(pfi.name),
subtitle: Text(pfi.didUri),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => PfiVerificationPage(pfi: pfi),
),
);
},
),
)
],
body: ref.watch(pfisProvider).when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (error, stack) => Center(child: Text('Error: $error')),
data: (pfis) {
// Build the list when data is available
return ListView(
children: pfis.map(
(pfi) => ListTile(
title: Text(pfi.name),
subtitle: Text(pfi.didUri),
trailing: const Icon(Icons.chevron_right),
onTap: () async {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => PfiVerificationPage(pfi: pfi),
),
);
},
),
).toList(),
);
},
),
);
}
Expand Down
66 changes: 65 additions & 1 deletion frontend/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.0"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
flutter:
dependency: "direct main"
description: flutter
Expand Down Expand Up @@ -349,6 +357,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.4.9"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06"
url: "https://pub.dev"
source: hosted
version: "2.2.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
url: "https://pub.dev"
source: hosted
version: "2.3.5"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21"
url: "https://pub.dev"
source: hosted
version: "2.2.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
sky_engine:
dependency: transitive
description: flutter
Expand Down Expand Up @@ -502,4 +566,4 @@ packages:
version: "1.0.4"
sdks:
dart: ">=3.2.3 <4.0.0"
flutter: ">=3.10.0"
flutter: ">=3.16.0"
1 change: 1 addition & 0 deletions frontend/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ dependencies:
http: ^1.1.2
intl: ^0.18.1
webview_flutter: ^4.4.2
shared_preferences: ^2.2.2

dev_dependencies:
flutter_test:
Expand Down

0 comments on commit bfc3911

Please sign in to comment.