diff --git a/Dockerfile b/Dockerfile index 3a7b8402cfc225aa4a8434065d36a6d20282b139..f24f76458a0505ec5e6d3eed229981a96d35710b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ rm -rf /var/lib/apt/lists/* && \ apt-get clean -ARG GINKGO_WEB_VERSION=0.0.9 +ARG GINKGO_WEB_VERSION=0.0.12 ARG GINKGO_WEB_VERSION_PATH=176d988bc6e5c3756973cef2038c7d6c RUN curl -L https://git.duniter.org/vjrj/ginkgo/uploads/${GINKGO_WEB_VERSION_PATH}/ginkgo-web-${GINKGO_WEB_VERSION}.tgz | tar xfz - -C /usr/share/nginx/html/ --strip-components=2 @@ -27,12 +27,11 @@ COPY assets/img/ /usr/share/nginx/html/assets/img/ # Copy the default nginx configuration and g1nkgo conf to restore in empty volumes RUN cp -a /etc/nginx/ /etc/nginx-default/ -# Copy startup.sh (copy previous assets if people mount empty volumes) -COPY startup.sh /usr/local/bin/startup.sh -RUN chmod +x /usr/local/bin/startup.sh - # Exponer los puertos de nginx EXPOSE 80 EXPOSE 443 -CMD ["nginx", "-g", "daemon off;"] +COPY entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod +x /usr/local/bin/entrypoint.sh + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/assets/.env.development b/assets/.env.development index fb557efb91ed4322d93fd4d1db92e533938b341b..63fcb481efbe4eb268c2fc5ed026a85ca73c184a 100644 --- a/assets/.env.development +++ b/assets/.env.development @@ -5,11 +5,11 @@ SENTRY_DSN=https://306345cb87ee4e1cbbe9023fb4afc5fc@sentry.comunes.org/6 CARD_COLOR_LEFT=0xFF598040 CARD_COLOR_RIGHT=0xFF225500 # Empty for default -CARD_COLOR_TEXT=Äž1 Wallet Dev +CARD_TEXT=Äž1 Wallet Dev # Nodes space-separated # The duniter nodes are only used at boot time, later it tries to calculate periodically the nodes # that are available with the less latency DUNITER_NODES=https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr https://g1.monnaielibreoccitanie.org https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr CESIUM_PLUS_NODES=https://g1.data.le-sou.org https://g1.data.e-is.pro https://g1.data.presler.fr https://g1.data.mithril.re -GVA_NODES=https://g1v1.p2p.legal:443/gva https://g1.asycn.io:443/gva https://duniter.pini.fr:443/gva https://duniter.cuates.net:443/gva +GVA_NODES=https://g1v1.p2p.legal:443/gva https://g1.asycn.io:443/gva https://duniter.pini.fr:443/gva diff --git a/assets/env.production.txt b/assets/env.production.txt index 6f10c86a9410bcb8e32ccb5a960434dc1991828a..eae3ce8eb048260131b1c36f0b86069a438c117d 100644 --- a/assets/env.production.txt +++ b/assets/env.production.txt @@ -1,14 +1,14 @@ SENTRY_DSN=https://306345cb87ee4e1cbbe9023fb4afc5fc@sentry.comunes.org/6 # Card customization -CARD_COLOR_LEFT=0xFF05112B -CARD_COLOR_RIGHT=0xFF085476 +CARD_COLOR_LEFT="0xFF05112B" +CARD_COLOR_RIGHT="0xFF085476" # Empty for default -CARD_COLOR_TEXT=Äž1 Wallet +CARD_TEXT=Äž1 Wallet # Nodes space-separated # The duniter nodes are only used at boot time, later it tries to calculate periodically the nodes # that are available with the less latency -DUNITER_NODES=https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr https://g1.monnaielibreoccitanie.org https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr +DUNITER_NODES=http://192.168.32.3:10901 https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr https://g1.monnaielibreoccitanie.org https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr CESIUM_PLUS_NODES=https://g1.data.le-sou.org https://g1.data.e-is.pro https://g1.data.presler.fr https://g1.data.mithril.re -GVA_NODES=https://g1v1.p2p.legal:443/gva https://g1.asycn.io:443/gva https://duniter.pini.fr:443/gva https://duniter.cuates.net:443/gva +GVA_NODES=https://g1v1.p2p.legal:443/gva https://g1.asycn.io:443/gva https://duniter.pini.fr:443/gva diff --git a/docker-compose.yml b/docker-compose.yml index 66926dd5550acf92250fee970d85ff6bcdac8f32..c05ddbde231e3b5245e9ddc35504c70d7345cc6a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,54 @@ version: '3' services: + duniter: + container_name: duniter + environment: + - DEBUG_ENTRYPOINT=${DUNITER_DEBUG_ENTRYPOINT:-${DEBUG_ENTRYPOINT:-${DEBUG:-}}} + - DUNITER_AUTO_SYNC=${DUNITER_AUTO_SYNC:-true} + - DUNITER_BMA_ENABLED=${DUNITER_BMA_ENABLED:-true} + - DUNITER_BMA_IP4=${DUNITER_BMA_IP4:-0.0.0.0} + - DUNITER_BMA_REMOTE_HOST=${DUNITER_BMA_REMOTE_HOST:-duniter.localhost} + - DUNITER_BMA_REMOTE_PORT=${DUNITER_BMA_REMOTE:-443} + - DUNITER_GVA_ENABLED=${DUNITER_GVA_ENABLED:-true} + - DUNITER_GVA_PATH=${DUNITER_GVA_PATH:-gva} + - DUNITER_GVA_PORT=${DUNITER_GVA_PORT:-30901} + - DUNITER_GVA_REMOTE_HOST=${DUNITER_GVA_REMOTE_HOST:-duniter.localhost} + - DUNITER_GVA_REMOTE_PATH=${DUNITER_GVA_REMOTE_PATH:-gva} + - DUNITER_GVA_REMOTE_PORT=${DUNITER_GVA_REMOTE_PORT:-443} + - DUNITER_GVA_REMOTE_TLS=${DUNITER_GVA_REMOTE_TLS:-false} + - DUNITER_GVA_WHITELIST=${DUNITER_GVA_WHITELIST:-127.0.0.1,::1} + - DUNITER_MANUAL_CONFIG=${DUNITER_MANUAL_CONFIG:-false} + - DUNITER_POW_PREFIX=${DUNITER_POW_PREFIX:-} + - DUNITER_POW_CPU=${DUNITER_POW_CPU:-0.8} + - DUNITER_POW_NBCORES=${DUNITER_POW_NBCORES:-1} + - DUNITER_START_OPTS=${DUNITER_START_OPTS:-direct_webstart} + - DUNITER_SYNC_HOST=${DUNITER_SYNC_HOST:-g1.duniter.org:443} + - DUNITER_SYNC_OPTS=${DUNITER_SYNC_OPTS:-} + - DUNITER_WS2P_HOST=${DUNITER_WS2P_HOST:-0.0.0.0} + - DUNITER_WS2P_PORT=${DUNITER_W2SP_PORT:-20901} + - DUNITER_WS2P_PUBLIC=${DUNITER_W2SP_PUBLIC:-true} + - DUNITER_WS2P_REMOTE_HOST=${DUNITER_WS2P_REMOTE_HOST:-duniter.localhost} + - DUNITER_WS2P_REMOTE_PATH=${DUNITER_WS2P_REMOTE_PATH:-ws2p} + - DUNITER_WS2P_REMOTE_PORT=${DUNITER_WS2P_REMOTE_PORT:-443} + image: duniter/duniter:dev + networks: + - private + ports: + - 0.0.0.0:10901:10901 + - 0.0.0.0:20901:20901 + - 0.0.0.0:30901:30901 + - 0.0.0.0:9220:9220 + restart: unless-stopped + volumes: + - data:/var/lib/duniter + - etc:/etc/duniter + # Don't auto-updated duniter + labels: + - "com.centurylinklabs.watchtower.enable=false" + # We start duniter but adding g1nkgo local IP to the allow list, so we can use GVA without rate limits (in theory) + entrypoint: /bin/sh -c "while ! getent hosts g1nkgo_host > /dev/null 2>&1; do echo 'Waiting for g1nkgo_host...'; sleep 1; done && G1NKGO_IP=`getent hosts g1nkgo_host | awk '{ print $$1 }'` && export DUNITER_GVA_WHITELIST=$$G1NKGO_IP,$${DUNITER_GVA_WHITELIST:-127.0.0.1,::1} && echo $$DUNITER_GVA_WHITELIST && exec /docker-entrypoint.sh" + g1nkgo: image: g1nkgo:latest container_name: g1nkgo @@ -12,12 +60,29 @@ services: volumes: - ~/.ginkgo/nginx-conf:/etc/nginx/:rw - ./assets:/usr/share/nginx/html/assets:rw + labels: + - "com.centurylinklabs.watchtower.enable=true" + networks: + private: + aliases: + - g1nkgo_host environment: # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones # Useful for having logs with local time - TZ: "Europe/Copenhagen" - command: /bin/bash -c "/usr/local/bin/startup.sh && nginx -g 'daemon off;'" + - TZ=${TZ:-Europe/Copenhagen} + # Sentry conf + # SENTRY_DSN=https://306345cb87ee4e1cbbe9023fb4afc5fc@sentry.comunes.org/6 + # Card customization + # Empty for default + - CARD_TEXT=${CARD_TEXT:-Äž1 Wallet} + # Nodes space-separated + # The duniter nodes are only used at boot time, later it tries to calculate periodically the nodes + # that are available with the less latency + # SENTRY_DSN no tiene valor predeterminado, por lo que no se incluye aquÃ. + - DUNITER_NODES=${DUNITER_NODES:-https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr https://g1.monnaielibreoccitanie.org https://g1.duniter.fr https://g1.le-sou.org https://g1.cgeek.fr} + - CESIUM_PLUS_NODES=${CESIUM_PLUS_NODES:-https://g1.data.le-sou.org https://g1.data.e-is.pro https://g1.data.presler.fr https://g1.data.mithril.re} + - GVA_NODES=${GVA_NODES:-https://g1v1.p2p.legal:443/gva https://g1.asycn.io:443/gva https://duniter.pini.fr:443/gva https://duniter.cuates.net:443/gva} watchtower: image: containrrr/watchtower @@ -27,3 +92,16 @@ services: - /var/run/docker.sock:/var/run/docker.sock # Additional watchtower args # commmand: + networks: + - private + +networks: + private: + name: ${DOCKER_NETWORK_PRIVATE:-duniter} +# Not in use +# public: +# name: ${DOCKER_NETWORK_PUBLIC:-host} + +volumes: + data: + etc: diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000000000000000000000000000000000000..639580d907d3d848760343dfe9a85286d1f89703 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ -z "$(ls -A /etc/nginx)" ]; then + cp -a /etc/nginx-default/* /etc/nginx/ +fi + +CONFIG_FILE="/usr/share/nginx/html/assets/env.production.txt" + +VARIABLES=( + "SENTRY_DSN" + "CARD_TEXT" + "DUNITER_NODES" + "CESIUM_PLUS_NODES" + "GVA_NODES" +) + +DUNITER_IP=$(getent hosts duniter | awk '{ print $1 }') + +export GVA_NODES="http://$DUNITER_IP:30901 ${GVA_NODES}" + +for VAR_NAME in "${VARIABLES[@]}"; do + VAR_VALUE=${!VAR_NAME} + if [ ! -z "$VAR_VALUE" ]; then + ESCAPED_VAR_VALUE=$(echo "$VAR_VALUE" | sed -e 's/[\/&]/\\&/g') + sed -i -e "s/^\($VAR_NAME=\).*\$/\1$ESCAPED_VAR_VALUE/" $CONFIG_FILE + fi +done + +exec nginx -g "daemon off;" diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index cb6950551df449258d980761203c7a5ff1b0daaa..d2e181eff906f18329c52a43da1d209db79589d1 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -47,6 +47,8 @@ <string>es</string> <string>fr</string> <string>ca</string> + <string>de</string> + <string>nl</string> </array> <key>LSApplicationQueriesSchemes</key> <array> diff --git a/lib/main.dart b/lib/main.dart index 8497aa7c08bdb7957e7975027c002fe6a446db8c..83b6dc890a3a47cd2f2c3c228a759d81de6032e4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,7 +7,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:ginkgo/ui/contacts_cache.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:introduction_screen/introduction_screen.dart'; @@ -31,6 +30,7 @@ import 'data/models/payment_cubit.dart'; import 'data/models/transaction_cubit.dart'; import 'g1/api.dart'; import 'shared_prefs.dart'; +import 'ui/contacts_cache.dart'; import 'ui/logger.dart'; import 'ui/screens/skeleton_screen.dart'; import 'ui/ui_helpers.dart'; @@ -45,17 +45,17 @@ void main() async { await FlutterDisplayMode.setHighRefreshRate(); } - final SharedPreferencesHelper shared = SharedPreferencesHelper(); - await shared.init(); - await shared.getWallet(); - assert(shared.getPubKey() != null); - // .env await dotenv.load( fileName: kReleaseMode ? 'assets/env.production.txt' : 'assets/.env.development'); + final SharedPreferencesHelper shared = SharedPreferencesHelper(); + await shared.init(); + await shared.getWallet(); + assert(shared.getPubKey() != null); + if (kIsWeb) { await Hive.initFlutter(); HydratedBloc.storage = await HydratedStorage.build( @@ -81,6 +81,8 @@ void main() async { Locale('es'), Locale('fr'), Locale('ca'), + Locale('de'), + Locale('nl'), ], fallbackLocale: const Locale('en'), useFallbackTranslations: true, diff --git a/lib/shared_prefs.dart b/lib/shared_prefs.dart index 780f5612f68f979f96e2c459f91b88af70679202..6eb8301bb31b3e87d6b061e6b538a90fa34dbee7 100644 --- a/lib/shared_prefs.dart +++ b/lib/shared_prefs.dart @@ -2,9 +2,12 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:durt/durt.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'data/models/cesium_card.dart'; +import 'data/models/credit_card_themes.dart'; import 'g1/g1_helper.dart'; import 'ui/logger.dart'; @@ -39,6 +42,32 @@ class SharedPreferencesHelper { .map((dynamic e) => CesiumCard.fromJson(e as Map<String, dynamic>)) .toList(); } + + // Migrate the current pair if exists + await migrateCurrentPair(); + } + + Future<void> migrateCurrentPair() async { + if (_prefs.containsKey(_seedKey) && + _prefs.containsKey(_pubKey) && + cesiumCards.isEmpty) { + final String seed = _prefs.getString(_seedKey)!; + final String pubKey = _prefs.getString(_pubKey)!; + final CesiumCard card = buildCesiumCard(seed: seed, pubKey: pubKey); + addCesiumCard(card); + // Let's do this later + // await _prefs.remove(_seedKey); + // await _prefs.remove(_pubKey); + setCurrentWalletIndex(0); + } + } + + CesiumCard buildCesiumCard({required String seed, required String pubKey}) { + return CesiumCard( + seed: seed, + pubKey: pubKey, + theme: CreditCardThemes.theme1, + name: dotenv.env['CARD_TEXT'] ?? tr('g1_wallet')); } void addCesiumCard(CesiumCard cesiumCard) { @@ -47,8 +76,11 @@ class SharedPreferencesHelper { } void removeCesiumCard(int index) { - cesiumCards.removeAt(index); - saveCesiumCards(); + // Don't allow the last card to be removed + if (cesiumCards.length > 1) { + cesiumCards.removeAt(index); + saveCesiumCards(); + } } Future<void> saveCesiumCards() async { @@ -57,40 +89,62 @@ class SharedPreferencesHelper { await _prefs.setString('cesiumCards', json); } -/* WIP part */ - -// I'll only use shared prefs for the duniter seed - Future<void> _saveString(String key, String value) async { - await _prefs.setString(key, value); - } - - Future<CesiumWallet> getWallet() async { - String? s = _getString(_seedKey); - if (s == null) { + // Get the wallet from the specified index (default to first wallet) + Future<CesiumWallet> getWallet({int index = 0}) async { + if (cesiumCards.isNotEmpty && index < cesiumCards.length) { + final CesiumCard card = cesiumCards[index]; + return CesiumWallet.fromSeed(seedFromString(card.seed)); + } else { + // Generate a new wallet if no wallets exist final Uint8List uS = generateUintSeed(); - s = seedToString(uS); - await _saveString(_seedKey, s); + final String seed = seedToString(uS); final CesiumWallet wallet = CesiumWallet.fromSeed(uS); logger('Generated public key: ${wallet.pubkey}'); - await _saveString(_pubKey, wallet.pubkey); + addCesiumCard(buildCesiumCard(seed: seed, pubKey: wallet.pubkey)); return wallet; - } else { - return CesiumWallet.fromSeed(seedFromString(s)); } } - String getPubKey() { - // At this point should exists - final String? pubKey = _prefs.getString(_pubKey); - return pubKey!; + // Get the public key from the specified index (default to first wallet) + String getPubKey({int index = 0}) { + final CesiumCard card = cesiumCards[index]; + return card.pubKey; + } + + List<CesiumCard> get cards => cesiumCards; + + static const String _currentWalletIndexKey = 'current_wallet_index'; + + // Get the current wallet index from shared preferences + int getCurrentWalletIndex() { + return _prefs.getInt(_currentWalletIndexKey) ?? 0; + } + + // Set the current wallet index in shared preferences + Future<void> setCurrentWalletIndex(int index) async { + await _prefs.setInt(_currentWalletIndexKey, index); + } + + // Select the current wallet and save its index in shared preferences + Future<void> selectCurrentWallet(int index) async { + if (index < cesiumCards.length) { + final CesiumCard card = cesiumCards[index]; + await setCurrentWalletIndex(index); + logger('Selected wallet: ${card.pubKey}'); + } else { + logger('Invalid wallet index: $index'); + } } - String? _getString(String key) { - return _prefs.getString(key); + // Get the currently selected wallet + Future<CesiumWallet> getCurrentWallet() async { + final int index = getCurrentWalletIndex(); + return getWallet(index: index); } - Future<void> setKeys(String pubKey, String seed) async { - await _saveString(_seedKey, seed); - await _saveString(_pubKey, pubKey); + @Deprecated('We should remove this in the future when multi-card is enabled') + void setDefaultWallet(CesiumCard defCesiumCard) { + cesiumCards[0] = defCesiumCard; + saveCesiumCards(); } } diff --git a/lib/ui/contacts_cache.dart b/lib/ui/contacts_cache.dart index 578a7a5481a19bc16afcf10cc26a27bcb65c57c5..ae4fd8a081827c196552ee54140fb7904134e0a7 100644 --- a/lib/ui/contacts_cache.dart +++ b/lib/ui/contacts_cache.dart @@ -123,7 +123,7 @@ class ContactsCache { if (record != null) { final Map<String, dynamic> typedRecord = - Map<String, dynamic>.from(record as Map); + Map<String, dynamic>.from(record as Map<String, dynamic>); final DateTime timestamp = DateTime.parse(typedRecord['timestamp'] as String); final bool before = DateTime.now().isBefore(timestamp.add(duration)); diff --git a/lib/ui/ui_helpers.dart b/lib/ui/ui_helpers.dart index d5874a452c3cedf889d46f420a3cefb67328de8d..845b792c3738134d40ab70dd848e36fea8324a6c 100644 --- a/lib/ui/ui_helpers.dart +++ b/lib/ui/ui_helpers.dart @@ -133,7 +133,7 @@ String formatKAmount(BuildContext context, double amount) => double parseToDoubleLocalized(String locale, String double) => NumberFormat.decimalPattern(locale).parse(double).toDouble(); -String getAppVersion() => '0.0.11'; +String getAppVersion() => '0.0.12'; String localizeNumber(BuildContext context, double amount) => NumberFormat.decimalPattern(context.locale.toString()).format(amount); diff --git a/lib/ui/widgets/card_drawer.dart b/lib/ui/widgets/card_drawer.dart index 7cda1c960889b414eda24d2a8806fa184a7b974e..01d6e9f12480907473cf0584e3cd343adece62e0 100644 --- a/lib/ui/widgets/card_drawer.dart +++ b/lib/ui/widgets/card_drawer.dart @@ -1,4 +1,7 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; import '../../data/models/cesium_card.dart'; import '../../shared_prefs.dart'; @@ -9,47 +12,93 @@ class CardDrawer extends StatelessWidget { @override Widget build(BuildContext context) { final List<CesiumCard> cards = SharedPreferencesHelper().cesiumCards; - - return Drawer( - child: Column( - children: <Widget>[ - const SizedBox( - height: 200, - child: Center( - child: Text( - '', // 'Drawer Header', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - Expanded( - child: Container( - decoration: const BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(20), + const ImageIcon g1nkgoIcon = ImageIcon( + AssetImage('img/favicon.png'), + size: 24, + ); + return FutureBuilder<PackageInfo>( + future: PackageInfo.fromPlatform(), + builder: (BuildContext context, AsyncSnapshot<PackageInfo> snapshot) { + if (snapshot.hasData) { + return Drawer( + child: Column( + children: <Widget>[ + DrawerHeader( + /* decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + ), */ + child: Column( + children: <Widget>[ + Image.asset( + 'assets/img/logo.png', + fit: BoxFit.scaleDown, + height: 80.0, + ), + // const SizedBox(height: 20.0), + /* Text(tr('app_name'), + style: const TextStyle( + fontSize: 24.0, + color: Colors.white, + )), */ + ], + ), ), - ), - child: ListView.builder( - shrinkWrap: true, - itemCount: cards.length, - itemBuilder: (BuildContext context, int index) { - final CesiumCard card = cards[index]; - return InkWell( - onTap: () { - // SharedPreferencesHelper().selectCesiumCard(person); - Navigator.pop(context); - }, - child: Text(card.pubKey), - ); - }, - ), + if (!kReleaseMode) + const SizedBox( + height: 200, + child: Center( + child: Text( + 'Cards', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + if (!kReleaseMode) + Expanded( + child: Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + ), + ), + child: ListView.builder( + shrinkWrap: true, + itemCount: cards.length, + itemBuilder: (BuildContext context, int index) { + final CesiumCard card = cards[index]; + return InkWell( + onTap: () { + SharedPreferencesHelper() + .selectCurrentWallet(index); + Navigator.pop(context); + }, + child: Text(card.pubKey), + ); + }, + ), + ), + ), + AboutListTile( + icon: g1nkgoIcon, + applicationName: tr('app_name'), + applicationVersion: + 'Version: ${snapshot.data!.version} build: ${snapshot.data!.buildNumber}', + applicationIcon: g1nkgoIcon, + applicationLegalese: + '© 2023-${DateTime.now().year} Comunes Association, under AGPLv3', + aboutBoxChildren: const <Widget>[ + SizedBox(height: 10.0), + ]), + ], ), - ), - ], - ), + ); + } else { + return const Center(child: CircularProgressIndicator()); + } + }, ); } } diff --git a/lib/ui/widgets/fifth_screen/import_dialog.dart b/lib/ui/widgets/fifth_screen/import_dialog.dart index 060623729605d3836958e6be4d1cc85b2a0e4b0c..473c642f0ac939b1c719f1c254b298639638c669 100644 --- a/lib/ui/widgets/fifth_screen/import_dialog.dart +++ b/lib/ui/widgets/fifth_screen/import_dialog.dart @@ -68,8 +68,14 @@ class _ImportDialogState extends State<ImportDialog> { keyEncrypted, pattern.join()); final bool? confirm = await confirmImport(context); if (confirm != null && confirm) { - SharedPreferencesHelper().setKeys( - keys['pub'] as String, keys['seed'] as String); + /* SharedPreferencesHelper().addCesiumCard( + SharedPreferencesHelper().buildCesiumCard( + pubKey: keys['pub'] as String, + seed: keys['seed'] as String));*/ + SharedPreferencesHelper().setDefaultWallet( + SharedPreferencesHelper().buildCesiumCard( + pubKey: keys['pub'] as String, + seed: keys['seed'] as String)); if (!mounted) { return; } diff --git a/lib/ui/widgets/first_screen/card_text_style.dart b/lib/ui/widgets/first_screen/card_text_style.dart new file mode 100644 index 0000000000000000000000000000000000000000..f345ca9967dcb8697de33f69df8ab96e3f91f5aa --- /dev/null +++ b/lib/ui/widgets/first_screen/card_text_style.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +TextStyle cardTextStyle(BuildContext context) { + return TextStyle( + fontFamily: 'SourceCodePro', + // decoration: TextDecoration.underline, + color: Colors.white, + fontSize: MediaQuery.of(context).size.width * 0.06, + fontWeight: FontWeight.bold, + shadows: <Shadow>[ + Shadow( + blurRadius: 1, + color: Colors.black.withOpacity(0.7), + offset: const Offset(0, 2), + ), + Shadow( + blurRadius: 1, + color: Colors.white.withOpacity(0.5), + offset: const Offset(0, -1), + ), + ], + ); +} diff --git a/lib/ui/widgets/first_screen/credit_card.dart b/lib/ui/widgets/first_screen/credit_card.dart index 8e3be06b27f7f47683833c75a0b1f4b55ced042e..7487d598299f6516e90de25e140c9a23cf33d2e3 100644 --- a/lib/ui/widgets/first_screen/credit_card.dart +++ b/lib/ui/widgets/first_screen/credit_card.dart @@ -6,32 +6,13 @@ import 'package:qr_flutter/qr_flutter.dart'; import '../../../shared_prefs.dart'; import '../../ui_helpers.dart'; +import 'card_text_style.dart'; class CreditCard extends StatelessWidget { CreditCard({super.key}); final String publicKey = SharedPreferencesHelper().getPubKey(); - TextStyle cardTextStyle(BuildContext context) => TextStyle( - fontFamily: 'SourceCodePro', - // decoration: TextDecoration.underline, - color: Colors.white, - fontSize: MediaQuery.of(context).size.width * 0.06, - fontWeight: FontWeight.bold, - shadows: <Shadow>[ - Shadow( - blurRadius: 1, - color: Colors.black.withOpacity(0.7), - offset: const Offset(0, 2), - ), - Shadow( - blurRadius: 1, - color: Colors.white.withOpacity(0.5), - offset: const Offset(0, -1), - ), - ], - ); - @override Widget build(BuildContext context) { const double cardRadius = 10.0; @@ -80,7 +61,7 @@ class CreditCard extends StatelessWidget { child: FittedBox( fit: BoxFit.scaleDown, child: Text( - dotenv.env['CARD_COLOR_TEXT'] ?? tr('g1_wallet'), + dotenv.env['CARD_TEXT'] ?? tr('g1_wallet'), style: TextStyle( color: Colors.white, fontSize: diff --git a/lib/ui/widgets/first_screen/credit_card_mini.dart b/lib/ui/widgets/first_screen/credit_card_mini.dart new file mode 100644 index 0000000000000000000000000000000000000000..5b1a6224fbd76923eef33033e6636e00836a8112 --- /dev/null +++ b/lib/ui/widgets/first_screen/credit_card_mini.dart @@ -0,0 +1,95 @@ +import 'package:durt/durt.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +import '../../ui_helpers.dart'; +import 'card_text_style.dart'; + +class CreditCardMini extends StatelessWidget { + const CreditCardMini({super.key, required this.wallet}); + + final CesiumWallet wallet; + + @override + Widget build(BuildContext context) { + final String pubKey = wallet.pubkey; + const double cardRadius = 10.0; + final bool bigDevice = bigScreen(context); + final double cardPadding = bigDevice ? 26.0 : 16.0; + return Card( + elevation: 8.0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(cardRadius), + ), + child: AspectRatio( + aspectRatio: 1.58, // Credit cart aspect ratio + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(cardRadius), + boxShadow: <BoxShadow>[ + BoxShadow( + color: Colors.grey[400]!, + blurRadius: 10.0, + spreadRadius: 1.0, + ) + ], + gradient: LinearGradient( + begin: Alignment.bottomLeft, + end: Alignment.topRight, + colors: <Color>[ + Color(int.parse("${dotenv.env['CARD_COLOR_LEFT']}")), + Color(int.parse("${dotenv.env['CARD_COLOR_RIGHT']}")), + ], + ), + ), + child: Stack(children: <Widget>[ + Padding( + padding: const EdgeInsets.fromLTRB(160, 10, 0, 0), + child: Opacity( + opacity: 0.1, + child: Image.asset('assets/img/gbrevedot_alt.png'))), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: <Widget>[ + Padding( + padding: EdgeInsets.all(cardPadding), + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + dotenv.env['CARD_TEXT'] ?? tr('g1_wallet'), + style: TextStyle( + color: Colors.white, + fontSize: + MediaQuery.of(context).size.width * 0.07, + fontWeight: FontWeight.bold, + ), + )), + ), + const SizedBox(height: 6.0), + Padding( + padding: + EdgeInsets.symmetric(horizontal: cardPadding), + child: Row(children: <Widget>[ + GestureDetector( + onTap: () => showTooltip( + context, '', tr('keys_tooltip')), + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text('**** **** ', + style: cardTextStyle(context)))), + FittedBox( + fit: BoxFit.scaleDown, + child: Text( + '${pubKey.substring(0, 4)} ${pubKey.substring(4, 8)}', + style: cardTextStyle(context), + )) + ])), + if (bigDevice) const SizedBox(height: 6.0), + const SizedBox(height: 18.0), + ]), + ]), + ))); + } +} diff --git a/proxy-gva.conf b/proxy-gva.conf index 3ede88220bf8a1e6067ec848c2502335a9f4ab7c..dfa6f5927ab340738454a8360ea0802f567d7a84 100644 --- a/proxy-gva.conf +++ b/proxy-gva.conf @@ -2,9 +2,10 @@ location ~ ^/proxy/(.*)/(gva(/.*)?)$ { set $proxy_url $1; set $proxy_uri $2; # resolver 1.1.1.1; - add_header 'Access-Control-Allow-Origin' '*'; - add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; - add_header 'Access-Control-Allow-Headers' 'X-Requested-With'; + # Try without this to not open the gva proxy to everyone (without rate limits) + # add_header 'Access-Control-Allow-Origin' '*'; + # add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + # add_header 'Access-Control-Allow-Headers' 'X-Requested-With'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; diff --git a/pubspec.lock b/pubspec.lock index 34bcdc43e160763e68ea388ba8afa506a12b2bc7..4572287369cd19369f83bfd154f366e08114106a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -821,7 +821,7 @@ packages: source: hosted version: "2.1.0" package_info_plus: - dependency: transitive + dependency: "direct main" description: name: package_info_plus sha256: "8df5ab0a481d7dc20c0e63809e90a588e496d276ba53358afc4c4443d0a00697" diff --git a/pubspec.yaml b/pubspec.yaml index 77331bd39215340d43b645a25a171a93af0a3b6b..9bd7d78653560809a15c5d56196c9475011908d2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.0.11 +version: 0.0.12 environment: sdk: ">=2.17.1 <3.0.0" @@ -63,6 +63,7 @@ dependencies: once: ^1.5.1 pattern_lock: ^2.0.0 backdrop: ^0.8.1 + package_info_plus: ^3.0.3 dev_dependencies: flutter_test: @@ -102,6 +103,7 @@ flutter: - assets/img/undraw_intro_5.png - assets/img/chip.svg - assets/img/logo.png + - assets/img/favicon.png - assets/img/logo-duniter.png - assets/img/logo-cesium.png - assets/tx.json diff --git a/startup.sh b/startup.sh deleted file mode 100644 index a539531f2b312229a385ae99bfc6c4b02a106fad..0000000000000000000000000000000000000000 --- a/startup.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -if [ -z "$(ls -A /etc/nginx)" ]; then - cp -a /etc/nginx-default/* /etc/nginx/ -fi