feat: global websocket connection for indexer and datapod

This commit is contained in:
poka 2024-01-08 03:10:56 +01:00
parent ebf7420615
commit 2bef9c1790
14 changed files with 81 additions and 142 deletions

View File

@ -1,6 +1,5 @@
[
"https://gdev-indexer.p2p.legal",
"https://hasura.gdev.coinduf.eu",
"https://gdev-hasura.cgeek.fr",
"https://hasura-gdev.pini.fr"
"gdev-indexer.p2p.legal",
"gdev-hasura.cgeek.fr",
"hasura-gdev.pini.fr"
]

View File

@ -29,7 +29,7 @@ const cesiumPod = "https://g1.data.le-sou.org";
// String cesiumPod = "https://g1.data.presles.fr";
// String cesiumPod = "https://g1.data.e-is.pro";
const datapodEndpoint = 'https://gdev-datapod.p2p.legal';
const datapodEndpoint = 'gdev-datapod.p2p.legal';
// const v2sDatapod = 'http://10.0.2.2:8080';
// Contexts

View File

@ -16,6 +16,7 @@ class DuniterIndexer with ChangeNotifier {
bool isLoadingIndexer = false;
bool hasNextPage = false;
Future<QueryResult<Object?>?> Function()? refetch;
late GraphQLClient indexerClient;
void reload() {
notifyListeners();
@ -27,10 +28,11 @@ class DuniterIndexer with ChangeNotifier {
final client = HttpClient();
client.connectionTimeout = const Duration(milliseconds: 4000);
try {
final request = await client.postUrl(Uri.parse('$endpoint/v1/graphql'));
final request =
await client.postUrl(Uri.parse('https://$endpoint/v1/graphql'));
final response = await request.close();
if (response.statusCode != 200) {
log.w('INDEXER IS OFFLINE');
log.w('Indexer $endpoint is offline');
indexerEndpoint = '';
isLoadingIndexer = false;
notifyListeners();
@ -46,7 +48,7 @@ class DuniterIndexer with ChangeNotifier {
return true;
}
} catch (e) {
log.w('INDEXER IS OFFLINE');
log.w('Indexer $endpoint is offline');
indexerEndpoint = '';
isLoadingIndexer = false;
notifyListeners();
@ -96,7 +98,7 @@ class DuniterIndexer with ChangeNotifier {
}
try {
final endpointPath = '${listIndexerEndpoints[i]}/v1/graphql';
final endpointPath = 'https://${listIndexerEndpoints[i]}/v1/graphql';
final request = await client.postUrl(Uri.parse(endpointPath));
final response = await request.close();
@ -217,42 +219,24 @@ class DuniterIndexer with ChangeNotifier {
Future<QueryResult> _execQuery(
String query, Map<String, dynamic> variables) async {
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
);
final options = QueryOptions(document: gql(query), variables: variables);
// 5GMyvKsTNk9wDBy9jwKaX6mhSzmFFtpdK9KNnmrLoSTSuJHv
return await client.query(options);
return await indexerClient.query(options);
}
Stream<QueryResult> subscribeHistoryIssued(String address) {
final wsLink = WebSocketLink(
'${indexerEndpoint.replaceFirst('https', 'wss')}/v1/graphql',
);
final variables = <String, dynamic>{
'address': address,
};
final client = GraphQLClient(
cache: GraphQLCache(),
link: wsLink,
);
final options = SubscriptionOptions(
document: gql(subscribeHistoryIssuedQ),
variables: variables,
);
return client.subscribe(options);
return indexerClient.subscribe(options);
}
Map computeHistoryView(repository, String address) {

View File

@ -11,19 +11,14 @@ import 'package:provider/provider.dart';
import 'package:uuid/uuid.dart';
class V2sDatapodProvider with ChangeNotifier {
late GraphQLClient datapodClient;
Future<QueryResult> _execQuery(
String query, Map<String, dynamic> variables) async {
final httpLink = HttpLink('$datapodEndpoint/v1/graphql');
final GraphQLClient client = GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
);
final QueryOptions options =
QueryOptions(document: gql(query), variables: variables);
return await client.query(options);
return await datapodClient.query(options);
}
Future<bool> updateProfile(
@ -174,34 +169,21 @@ class V2sDatapodProvider with ChangeNotifier {
}
Future<File> cacheAvatar(String address, String data) async {
final file = File('${avatarsCacheDirectory.path}/$address');
return await file.writeAsBytes(base64.decode(data));
final uuid = const Uuid().v4();
final tempFile = File('${avatarsCacheDirectory.path}/$uuid$address');
final targetFile = File('${avatarsCacheDirectory.path}/$address');
try {
// Write to a temporary file first to prevent data race
await tempFile.writeAsBytes(base64.decode(data));
log.d('Caching avatar of $address');
return await tempFile.rename(targetFile.path);
} catch (e) {
log.e("An error occurred while caching avatar: $e");
rethrow;
}
}
// Future<File> cacheAvatar(String address, String data) async {
// // Get the list of all files in the directory
// final dir = Directory(avatarsCacheDirectory.path);
// var filesList = dir.listSync().whereType<File>().toList();
// // Sorting files by modified date, oldest first
// filesList
// .sort((a, b) => a.lastModifiedSync().compareTo(b.lastModifiedSync()));
// // If there are more than 20 files, remove the oldest ones
// while (filesList.length > 20) {
// filesList.first.deleteSync();
// filesList.removeAt(0);
// }
// // Write the new avatar file
// final file = File('${avatarsCacheDirectory.path}/$address');
// await file.writeAsBytes(base64.decode(data));
// log.d('cache files: ${filesList.length}');
// return file;
// }
Image getAvatarLocal(String address) {
final avatarFile = File('${avatarsCacheDirectory.path}/$address');
return Image.file(

View File

@ -20,6 +20,7 @@ import 'package:gecko/screens/myWallets/restore_chest.dart';
import 'package:gecko/screens/onBoarding/1.dart';
import 'package:gecko/widgets/drawer.dart';
import 'package:gecko/widgets/buttons/home_buttons.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:provider/provider.dart';
@ -76,7 +77,25 @@ class _HomeScreenState extends State<HomeScreen> {
homeProvider.isWalletBoxInit = true;
myWalletProvider.reload();
duniterIndexer.getValidIndexerEndpoint();
duniterIndexer.getValidIndexerEndpoint().then((validIndexerEndpoint) {
final wsLinkIndexer = WebSocketLink(
'wss://$validIndexerEndpoint/v1/graphql',
);
final wsLinkDatapod = WebSocketLink(
'wss://$datapodEndpoint/v1/graphql',
);
duniterIndexer.indexerClient = GraphQLClient(
cache: GraphQLCache(),
link: wsLinkIndexer,
);
datapod.datapodClient = GraphQLClient(
cache: GraphQLCache(),
link: wsLinkDatapod,
);
});
await homeProvider.getValidEndpoints();
if (configBox.get('isCacheChecked') == null) {
@ -101,7 +120,6 @@ class _HomeScreenState extends State<HomeScreen> {
}
});
}
// _duniterIndexer.checkIndexerEndpointBackground();
});
super.initState();
}

View File

@ -86,7 +86,7 @@ class WalletOptions extends StatelessWidget {
? duniterIndexer
.walletNameIndexer[walletOptions.address.text]!
: wallet.name!,
style: scaledTextStyle(fontSize: 18),
style: scaledTextStyle(fontSize: 19),
);
}),
actions: [

View File

@ -4,8 +4,10 @@ import 'package:gecko/globals.dart';
import 'package:gecko/models/queries_indexer.dart';
import 'package:gecko/models/scale_functions.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/widgets/cert_tile.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
class CertsList extends StatelessWidget {
const CertsList(
@ -18,14 +20,11 @@ class CertsList extends StatelessWidget {
@override
Widget build(BuildContext context) {
final indexerProvider = Provider.of<DuniterIndexer>(context, listen: false);
final screenHeight = MediaQuery.of(context).size.height;
final appBarHeight = AppBar().preferredSize.height;
final windowHeight = screenHeight - appBarHeight - (isTall ? 170 : 140);
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
late String gertCertsReq;
late String certFrom;
@ -37,14 +36,8 @@ class CertsList extends StatelessWidget {
certFrom = 'receiver';
}
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
client: ValueNotifier(indexerProvider.indexerClient),
child: Query(
options: QueryOptions(
document: gql(gertCertsReq),
@ -53,7 +46,7 @@ class CertsList extends StatelessWidget {
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading && result.data == null) {
if (result.isLoading || result.data == null) {
return const Center(
child: CircularProgressIndicator(),
);

View File

@ -30,21 +30,10 @@ class DatapodAvatar extends StatelessWidget {
);
}
final httpLink = HttpLink(
'$datapodEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
),
);
return ScaledSizedBox(
width: size,
child: GraphQLProvider(
client: client,
client: ValueNotifier(datapod.datapodClient),
child: Query(
options: QueryOptions(
document: gql(getAvatarQ),
@ -53,7 +42,7 @@ class DatapodAvatar extends StatelessWidget {
},
),
builder: (QueryResult result, {fetchMore, refetch}) {
if (result.isLoading) {
if (result.isLoading || result.data == null) {
return Center(
child: ClipOval(child: datapod.defaultAvatar(size)),
);

View File

@ -36,19 +36,8 @@ class HistoryQuery extends StatelessWidget {
]);
}
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
client: ValueNotifier(duniterIndexer.indexerClient),
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,

View File

@ -54,7 +54,8 @@ class HistoryView extends StatelessWidget {
return Column(children: <Widget>[
if (isMigrationTime)
Padding(
padding: EdgeInsets.symmetric(vertical: scaleSize(23)),
padding: EdgeInsets.only(
top: scaleSize(25), bottom: scaleSize(15)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
@ -64,9 +65,9 @@ class HistoryView extends StatelessWidget {
Text(
'blockchainStart'.tr(),
style: scaledTextStyle(
fontSize: 19,
fontSize: 20,
color: Colors.blueAccent,
fontWeight: FontWeight.w500),
fontWeight: FontWeight.w400),
),
Image(
image: const AssetImage('assets/party.png'),
@ -83,7 +84,7 @@ class HistoryView extends StatelessWidget {
child: Text(
answer['dateDelimiter'],
style: scaledTextStyle(
fontSize: 19,
fontSize: 20,
color: orangeC,
fontWeight: FontWeight.w300),
),
@ -131,7 +132,7 @@ class HistoryView extends StatelessWidget {
Text(
'identityMigrated'.tr(),
style: scaledTextStyle(
fontSize: 19,
fontSize: 20,
color: Colors.green[700],
fontWeight: FontWeight.w500),
),
@ -155,10 +156,18 @@ class HistoryView extends StatelessWidget {
Column(
children: <Widget>[
ScaledSizedBox(height: 15),
Text("historyStart".tr(),
textAlign: TextAlign.center,
style: scaledTextStyle(fontSize: 20)),
ScaledSizedBox(height: 15)
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Icon(Icons.blur_on_outlined, size: scaleSize(31)),
Text("historyStart".tr(),
textAlign: TextAlign.center,
style: scaledTextStyle(
fontSize: 20, fontWeight: FontWeight.w300)),
Icon(Icons.blur_on_outlined, size: scaleSize(31)),
],
),
ScaledSizedBox(height: 30)
],
)
]);

View File

@ -6,6 +6,7 @@ import 'package:gecko/models/queries_indexer.dart';
import 'package:gecko/models/scale_functions.dart';
import 'package:gecko/models/wallet_data.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/widgets/commons/loading.dart';
import 'package:gecko/widgets/wallet_name.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';
@ -34,22 +35,8 @@ class NameByAddress extends StatelessWidget {
return WalletName(wallet: wallet, size: size, color: color);
}
// if (g1WalletsBox.get(wallet.address)?.username != null) {
// return Text(g1WalletsBox.get(wallet.address)!.username!);
// }
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(store: HiveStore()),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
client: ValueNotifier(duniterIndexer.indexerClient),
child: Query(
options: QueryOptions(
document: gql(getNameByAddressQ),
@ -66,7 +53,7 @@ class NameByAddress extends StatelessWidget {
}
if (result.isLoading) {
return const Text('Loading');
return const Loading();
}
duniterIndexer.walletNameIndexer[wallet.address] =

View File

@ -29,19 +29,8 @@ class SearchIdentityQuery extends StatelessWidget {
return Text('noResult'.tr());
}
final httpLink = HttpLink(
'$indexerEndpoint/v1/graphql',
);
final client = ValueNotifier(
GraphQLClient(
cache: GraphQLCache(
store: HiveStore()),
link: httpLink,
),
);
return GraphQLProvider(
client: client,
client: ValueNotifier(duniterIndexer.indexerClient),
child: Query(
options: QueryOptions(
document: gql(searchAddressByNameQ),

View File

@ -108,7 +108,7 @@ class _TransactionInProgressTuleState extends State<TransactionInProgressTule> {
Text(
'Transaction en cours',
style: scaledTextStyle(
fontSize: 19,
fontSize: 20,
color: Colors.blueAccent,
fontWeight: FontWeight.w400),
),

View File

@ -5,7 +5,7 @@ description: Pay with G1.
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
version: 0.1.3+64
version: 0.1.4+65
environment:
sdk: ">=2.12.0 <3.0.0"