Skip to content
Snippets Groups Projects
Commit 0991ce96 authored by vjrj's avatar vjrj
Browse files

Another hackathon

parent 70cf53b4
No related branches found
No related tags found
No related merge requests found
Showing
with 437 additions and 121 deletions
......@@ -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"]
......@@ -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
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
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:
#!/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;"
......@@ -47,6 +47,8 @@
<string>es</string>
<string>fr</string>
<string>ca</string>
<string>de</string>
<string>nl</string>
</array>
<key>LSApplicationQueriesSchemes</key>
<array>
......
......@@ -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,
......
......@@ -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();
}
}
......@@ -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));
......
......@@ -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);
......
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());
}
},
);
}
}
......@@ -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;
}
......
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),
),
],
);
}
......@@ -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:
......
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),
]),
]),
)));
}
}
......@@ -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;
......
......@@ -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"
......
......@@ -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
......
#!/bin/bash
if [ -z "$(ls -A /etc/nginx)" ]; then
cp -a /etc/nginx-default/* /etc/nginx/
fi
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment