Skip to content
Snippets Groups Projects
activity.dart 12.6 KiB
Newer Older
poka's avatar
poka committed
// ignore_for_file: must_be_immutable

Hugo Trentesaux's avatar
Hugo Trentesaux committed
import 'package:easy_localization/easy_localization.dart';
poka's avatar
poka committed
import 'package:flutter/services.dart';
import 'package:gecko/globals.dart';
import 'package:gecko/models/queries_indexer.dart';
import 'package:gecko/models/widgets_keys.dart';
import 'package:gecko/providers/cesium_plus.dart';
import 'package:gecko/providers/duniter_indexer.dart';
import 'package:gecko/providers/home.dart';
poka's avatar
poka committed
import 'package:gecko/providers/substrate_sdk.dart';
import 'package:gecko/providers/wallets_profiles.dart';
poka's avatar
poka committed
import 'package:flutter/material.dart';
import 'package:gecko/screens/wallet_view.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
import 'package:provider/provider.dart';

class ActivityScreen extends StatelessWidget with ChangeNotifier {
  ActivityScreen({required this.address, this.avatar, this.username, Key? key})
poka's avatar
poka committed
      : super(key: key);
  final ScrollController scrollController = ScrollController();
  final double avatarsSize = 80;
  final String? address;
poka's avatar
poka committed
  final String? username;
  final Image? avatar;
poka's avatar
poka committed

poka's avatar
poka committed
  FetchMore? fetchMore;
  FetchMoreOptions? opts;
poka's avatar
poka committed

  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
    WalletsProfilesProvider walletProfile =
        Provider.of<WalletsProfilesProvider>(context, listen: false);
    HomeProvider homeProvider =
        Provider.of<HomeProvider>(context, listen: false);
poka's avatar
poka committed

poka's avatar
poka committed
    return Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          elevation: 0,
          toolbarHeight: 60 * ratio,
Hugo Trentesaux's avatar
Hugo Trentesaux committed
          title: SizedBox(
poka's avatar
poka committed
            height: 22,
Hugo Trentesaux's avatar
Hugo Trentesaux committed
            child: Text('accountActivity'.tr()),
poka's avatar
poka committed
          ),
        ),
        bottomNavigationBar: homeProvider.bottomAppBar(context),
poka's avatar
poka committed
        body: Column(children: <Widget>[
          walletProfile.headerProfileView(context, address!, username),
          historyQuery(context),
poka's avatar
poka committed
        ]));
  }

  Widget historyQuery(context) {
    DuniterIndexer duniterIndexer =
        Provider.of<DuniterIndexer>(context, listen: false);
    if (indexerEndpoint == '') {
Hugo Trentesaux's avatar
Hugo Trentesaux committed
      Column(children: <Widget>[
        const SizedBox(height: 50),
Hugo Trentesaux's avatar
Hugo Trentesaux committed
          "noNetworkNoHistory".tr(),
          textAlign: TextAlign.center,
Hugo Trentesaux's avatar
Hugo Trentesaux committed
          style: const TextStyle(fontSize: 18),
    final httpLink = HttpLink(
      '$indexerEndpoint/v1beta1/relay',
    );

    final client = ValueNotifier(
      GraphQLClient(
        cache: GraphQLCache(),
        link: httpLink,
poka's avatar
poka committed

    return GraphQLProvider(
      client: client,
      child: Expanded(
          child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        mainAxisSize: MainAxisSize.max,
        children: <Widget>[
          Query(
            options: QueryOptions(
              document: gql(getHistoryByAddressQ3),
              variables: <String, dynamic>{
                'address': address,
                'number': 20,
                'cursor': null
              },
            ),
            builder: (QueryResult result, {fetchMore, refetch}) {
              if (result.isLoading && result.data == null) {
                return const Center(
                  child: CircularProgressIndicator(),
                );
              }

              if (result.hasException) {
                log.e('Error Indexer: ${result.exception}');
Hugo Trentesaux's avatar
Hugo Trentesaux committed
                return Column(children: <Widget>[
                  const SizedBox(height: 50),
Hugo Trentesaux's avatar
Hugo Trentesaux committed
                    "noNetworkNoHistory".tr(),
                    textAlign: TextAlign.center,
Hugo Trentesaux's avatar
Hugo Trentesaux committed
                    style: const TextStyle(fontSize: 18),
              } else if (result
                  .data?['transaction_connection']?['edges'].isEmpty) {
Hugo Trentesaux's avatar
Hugo Trentesaux committed
                return Column(children: <Widget>[
                  const SizedBox(height: 50),
Hugo Trentesaux's avatar
Hugo Trentesaux committed
                    "noDataToDisplay".tr(),
                    style: const TextStyle(fontSize: 18),
poka's avatar
poka committed

              if (result.isNotLoading) {
                // log.d(result.data);
                opts = duniterIndexer.checkQueryResult(result, opts, address!);
poka's avatar
poka committed

              // Build history list
              return NotificationListener(
                  child: Builder(
                    builder: (context) => Expanded(
                      child: ListView(
                        key: keyListTransactions,
                        controller: scrollController,
                        children: <Widget>[historyView(context, result)],
                      ),
poka's avatar
poka committed
                    ),
                  ),
                  onNotification: (dynamic t) {
                    if (t is ScrollEndNotification &&
                        scrollController.position.pixels >=
                            scrollController.position.maxScrollExtent * 0.7 &&
                        duniterIndexer.pageInfo!['hasNextPage'] &&
                        result.isNotLoading) {
                      fetchMore!(opts!);
                    }
                    return true;
                  });
            },
          ),
        ],
      )),
    );
poka's avatar
poka committed
  }

  Widget historyView(context, result) {
    DuniterIndexer duniterIndexer =
        Provider.of<DuniterIndexer>(context, listen: false);
poka's avatar
poka committed

    return duniterIndexer.transBC == null
Hugo Trentesaux's avatar
Hugo Trentesaux committed
        ? Column(children: <Widget>[
            const SizedBox(height: 50),
poka's avatar
poka committed
            Text(
Hugo Trentesaux's avatar
Hugo Trentesaux committed
              "noTransactionToDisplay".tr(),
              style: const TextStyle(fontSize: 18),
poka's avatar
poka committed
            )
          ])
poka's avatar
poka committed
        : Column(children: <Widget>[
            getTransactionTile(context, duniterIndexer),
            if (result.isLoading && duniterIndexer.pageInfo!['hasPreviousPage'])
poka's avatar
poka committed
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: const <Widget>[
                  CircularProgressIndicator(),
                ],
              ),
            if (!duniterIndexer.pageInfo!['hasNextPage'])
poka's avatar
poka committed
              Column(
                children: const <Widget>[
                  SizedBox(height: 15),
                  Text("Début de l'historique.",
                      textAlign: TextAlign.center,
                      style: TextStyle(fontSize: 20)),
                  SizedBox(height: 15)
                ],
              )
          ]);
  }

  Widget getTransactionTile(
      BuildContext context, DuniterIndexer duniterIndexer) {
    CesiumPlusProvider cesiumPlusProvider =
poka's avatar
poka committed
        Provider.of<CesiumPlusProvider>(context, listen: false);
poka's avatar
poka committed
    SubstrateSdk sub = Provider.of<SubstrateSdk>(context, listen: false);

poka's avatar
poka committed
    int keyID = 0;
poka's avatar
poka committed
    String? dateDelimiter;
    String? lastDateDelimiter;
    const double avatarSize = 200;
poka's avatar
poka committed

poka's avatar
poka committed
    bool isTody = false;
    bool isYesterday = false;
    bool isThisWeek = false;

Hugo Trentesaux's avatar
Hugo Trentesaux committed
    final Map<int, String> monthsInYear = {
      1: "month1".tr(),
      2: "month2".tr(),
      3: "month3".tr(),
      4: "month4".tr(),
      5: "month5".tr(),
      6: "month6".tr(),
      7: "month7".tr(),
      8: "month8".tr(),
      9: "month9".tr(),
      10: "month10".tr(),
      11: "month11".tr(),
      12: "month12".tr()
poka's avatar
poka committed
    };

    return Column(
        children: duniterIndexer.transBC!.map((repository) {
      // log.d('bbbbbbbbbbbbbbbbbbbbbb: ' + repository.toString());

poka's avatar
poka committed
      DateTime now = DateTime.now();
      DateTime date = repository[0];
poka's avatar
poka committed

      String dateForm;
      if ({4, 10, 11, 12}.contains(date.month)) {
poka's avatar
poka committed
        dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 3)}.";
poka's avatar
poka committed
      } else if ({1, 2, 7, 9}.contains(date.month)) {
poka's avatar
poka committed
        dateForm = "${date.day} ${monthsInYear[date.month]!.substring(0, 4)}.";
poka's avatar
poka committed
      } else {
        dateForm = "${date.day} ${monthsInYear[date.month]}";
      }

      int weekNumber(DateTime date) {
        int dayOfYear = int.parse(DateFormat("D").format(date));
        return ((dayOfYear - date.weekday + 10) / 7).floor();
      }

      final transactionDate = DateTime(date.year, date.month, date.day);
      final todayDate = DateTime(now.year, now.month, now.day);
      final yesterdayDate = DateTime(now.year, now.month, now.day - 1);

      if (transactionDate == todayDate && !isTody) {
Hugo Trentesaux's avatar
Hugo Trentesaux committed
        dateDelimiter = lastDateDelimiter = "today".tr();
poka's avatar
poka committed
        isTody = true;
      } else if (transactionDate == yesterdayDate && !isYesterday) {
Hugo Trentesaux's avatar
Hugo Trentesaux committed
        dateDelimiter = lastDateDelimiter = "yesterday".tr();
poka's avatar
poka committed
        isYesterday = true;
poka's avatar
poka committed
      } else if (weekNumber(date) == weekNumber(now) &&
          date.year == now.year &&
Hugo Trentesaux's avatar
Hugo Trentesaux committed
          lastDateDelimiter != "thisWeek".tr() &&
          transactionDate != yesterdayDate &&
          transactionDate != todayDate &&
poka's avatar
poka committed
          !isThisWeek) {
Hugo Trentesaux's avatar
Hugo Trentesaux committed
        dateDelimiter = lastDateDelimiter = "thisWeek".tr();
poka's avatar
poka committed
        isThisWeek = true;
poka's avatar
poka committed
      } else if (lastDateDelimiter != monthsInYear[date.month] &&
poka's avatar
poka committed
          lastDateDelimiter != "${monthsInYear[date.month]} ${date.year}" &&
          transactionDate != todayDate &&
          transactionDate != yesterdayDate &&
poka's avatar
poka committed
          !(weekNumber(date) == weekNumber(now) && date.year == now.year)) {
poka's avatar
poka committed
        if (date.year == now.year) {
          dateDelimiter = lastDateDelimiter = monthsInYear[date.month];
        } else {
          dateDelimiter =
              lastDateDelimiter = "${monthsInYear[date.month]} ${date.year}";
        }
      } else {
        dateDelimiter = null;
      }

poka's avatar
poka committed
      final bool isUdUnit = configBox.get('isUdUnit') ?? false;
      late double amount;
      late String finalAmount;
      amount = repository[4] == 'RECEIVED' ? repository[3] : repository[3] * -1;

      if (isUdUnit) {
        amount = round(amount / (sub.udValue / 100));
poka's avatar
poka committed
        finalAmount = 'ud'.tr(args: ['$amount ']);
poka's avatar
poka committed
      } else {
        finalAmount = '$amount $currencyName';
      }

poka's avatar
poka committed
      return Column(children: <Widget>[
        if (dateDelimiter != null)
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 30),
            child: Text(
poka's avatar
poka committed
              dateDelimiter!,
poka's avatar
poka committed
              style: TextStyle(
                  fontSize: 23, color: orangeC, fontWeight: FontWeight.w300),
            ),
          ),
        Padding(
          padding: const EdgeInsets.only(right: 0),
          child:
              // Row(children: [Column(children: [],)],)
              ListTile(
                  key: keyTransaction(keyID++),
poka's avatar
poka committed
                  contentPadding: const EdgeInsets.only(
                      left: 20, right: 30, top: 15, bottom: 15),
                    child: cesiumPlusProvider.defaultAvatar(avatarSize),
poka's avatar
poka committed
                  title: Padding(
                    padding: const EdgeInsets.only(bottom: 5),
                    child: Text(getShortPubkey(repository[1]),
poka's avatar
poka committed
                        style: const TextStyle(
                            fontSize: 18, fontFamily: 'Monospace')),
                  ),
                  subtitle: RichText(
                    text: TextSpan(
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.grey[700],
                      ),
                      children: <TextSpan>[
                        TextSpan(
                          text: dateForm,
                        ),
                        if (repository[2] != '')
poka's avatar
poka committed
                          TextSpan(
                            text: '  ·  ',
                            style: TextStyle(
                              fontSize: 20,
                              color: Colors.grey[550],
                            ),
                          ),
                        TextSpan(
poka's avatar
poka committed
                          style: TextStyle(
                            fontStyle: FontStyle.italic,
                            color: Colors.grey[600],
                          ),
                        ),
                      ],
                    ),
                  ),
poka's avatar
poka committed
                  trailing: Text(finalAmount,
poka's avatar
poka committed
                      style: const TextStyle(
                          fontSize: 18, fontWeight: FontWeight.w500),
                      textAlign: TextAlign.justify),
                  dense: false,
                  isThreeLine: false,
                  onTap: () {
                    duniterIndexer.nPage = 1;
                    // _cesiumPlusProvider.avatarCancelToken.cancel('cancelled');
                    Navigator.push(
                      context,
                      MaterialPageRoute(builder: (context) {
                        return WalletViewScreen(pubkey: repository[1]);
poka's avatar
poka committed
                    // Navigator.pop(context);
poka's avatar
poka committed
                  }),
        ),
      ]);
    }).toList());
  }
}