Skip to content
Snippets Groups Projects
Commit 397d0173 authored by vjrj's avatar vjrj
Browse files

Asociate june:// to ginkgo

parent 2168badf
No related branches found
No related tags found
No related merge requests found
...@@ -39,6 +39,12 @@ ...@@ -39,6 +39,12 @@
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="june" />
</intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below. <!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
...@@ -48,10 +54,10 @@ ...@@ -48,10 +54,10 @@
</application> </application>
<queries> <queries>
<!-- If your app opens https URLs -->
<intent> <intent>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<data android:scheme="https" /> <data android:scheme="https" />
</intent> </intent>
</queries> </queries>
</manifest> </manifest>
...@@ -21,6 +21,7 @@ import 'package:responsive_framework/responsive_wrapper.dart'; ...@@ -21,6 +21,7 @@ import 'package:responsive_framework/responsive_wrapper.dart';
import 'package:responsive_framework/utils/scroll_behavior.dart'; import 'package:responsive_framework/utils/scroll_behavior.dart';
import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:sentry_logging/sentry_logging.dart'; import 'package:sentry_logging/sentry_logging.dart';
import 'package:uni_links/uni_links.dart';
import 'app_bloc_observer.dart'; import 'app_bloc_observer.dart';
import 'config/theme.dart'; import 'config/theme.dart';
...@@ -37,6 +38,7 @@ import 'data/models/payment_cubit.dart'; ...@@ -37,6 +38,7 @@ import 'data/models/payment_cubit.dart';
import 'data/models/theme_cubit.dart'; import 'data/models/theme_cubit.dart';
import 'data/models/transaction_cubit.dart'; import 'data/models/transaction_cubit.dart';
import 'g1/api.dart'; import 'g1/api.dart';
import 'g1/g1_helper.dart';
import 'shared_prefs.dart'; import 'shared_prefs.dart';
import 'ui/contacts_cache.dart'; import 'ui/contacts_cache.dart';
import 'ui/logger.dart'; import 'ui/logger.dart';
...@@ -44,6 +46,7 @@ import 'ui/notification_controller.dart'; ...@@ -44,6 +46,7 @@ import 'ui/notification_controller.dart';
import 'ui/screens/skeleton_screen.dart'; import 'ui/screens/skeleton_screen.dart';
import 'ui/ui_helpers.dart'; import 'ui/ui_helpers.dart';
import 'ui/widgets/connectivity_widget_wrapper_wrapper.dart'; import 'ui/widgets/connectivity_widget_wrapper_wrapper.dart';
import 'ui/widgets/first_screen/pay_contact_search_page.dart';
void main() async { void main() async {
await NotificationController.initializeLocalNotifications(); await NotificationController.initializeLocalNotifications();
...@@ -79,7 +82,7 @@ void main() async { ...@@ -79,7 +82,7 @@ void main() async {
final Box<dynamic> box = await Hive.openBox('hydrated_box', final Box<dynamic> box = await Hive.openBox('hydrated_box',
path: HydratedStorage.webStorageDirectory.path); path: HydratedStorage.webStorageDirectory.path);
final List<dynamic> keysToDelete = final List<dynamic> keysToDelete =
box.keys.where((dynamic key) => '$key'.startsWith('minified')).toList(); box.keys.where((dynamic key) => '$key'.startsWith('minified')).toList();
box.deleteAll(keysToDelete); box.deleteAll(keysToDelete);
// This should we done after init // This should we done after init
// await HydratedBloc.storage.clear(); // await HydratedBloc.storage.clear();
...@@ -93,7 +96,7 @@ void main() async { ...@@ -93,7 +96,7 @@ void main() async {
final Directory tmpDir = await getTemporaryDirectory(); final Directory tmpDir = await getTemporaryDirectory();
Hive.init(tmpDir.toString()); Hive.init(tmpDir.toString());
HydratedBloc.storage = HydratedBloc.storage =
await HydratedStorage.build(storageDirectory: tmpDir); await HydratedStorage.build(storageDirectory: tmpDir);
} }
PWAInstall().setup(installCallback: () { PWAInstall().setup(installCallback: () {
...@@ -102,7 +105,8 @@ void main() async { ...@@ -102,7 +105,8 @@ void main() async {
Bloc.observer = AppBlocObserver(); Bloc.observer = AppBlocObserver();
void appRunner() => runApp( void appRunner() =>
runApp(
EasyLocalization( EasyLocalization(
path: 'assets/translations', path: 'assets/translations',
supportedLocales: const <Locale>[ supportedLocales: const <Locale>[
...@@ -146,9 +150,7 @@ void main() async { ...@@ -146,9 +150,7 @@ void main() async {
if (kReleaseMode) { if (kReleaseMode) {
// Only use sentry in production // Only use sentry in production
await SentryFlutter.init(( await SentryFlutter.init((SentryFlutterOptions options,) {
SentryFlutterOptions options,
) {
options.tracesSampleRate = 1.0; options.tracesSampleRate = 1.0;
options.reportPackages = false; options.reportPackages = false;
// options.addInAppInclude('sentry_flutter_example'); // options.addInAppInclude('sentry_flutter_example');
...@@ -195,7 +197,7 @@ class AppIntro extends StatefulWidget { ...@@ -195,7 +197,7 @@ class AppIntro extends StatefulWidget {
class _AppIntro extends State<AppIntro> { class _AppIntro extends State<AppIntro> {
final GlobalKey<IntroductionScreenState> introKey = final GlobalKey<IntroductionScreenState> introKey =
GlobalKey<IntroductionScreenState>(); GlobalKey<IntroductionScreenState>();
void _onIntroEnd(BuildContext context, AppCubit cubit) { void _onIntroEnd(BuildContext context, AppCubit cubit) {
cubit.introViewed(); cubit.introViewed();
...@@ -209,40 +211,43 @@ class _AppIntro extends State<AppIntro> { ...@@ -209,40 +211,43 @@ class _AppIntro extends State<AppIntro> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<AppCubit, AppState>( return BlocBuilder<AppCubit, AppState>(
builder: (BuildContext buildContext, AppState state) { builder: (BuildContext buildContext, AppState state) {
final AppCubit cubit = context.read<AppCubit>(); final AppCubit cubit = context.read<AppCubit>();
return IntroductionScreen( return IntroductionScreen(
key: introKey, key: introKey,
pages: <PageViewModel>[ pages: <PageViewModel>[
for (int i = 1; i <= 5; i++) for (int i = 1; i <= 5; i++)
createPageViewModel('intro_${i}_title', 'intro_${i}_description', createPageViewModel(
'assets/img/undraw_intro_$i.png', context), 'intro_${i}_title', 'intro_${i}_description',
], 'assets/img/undraw_intro_$i.png', context),
onDone: () => _onIntroEnd(buildContext, cubit), ],
showSkipButton: true, onDone: () => _onIntroEnd(buildContext, cubit),
skipOrBackFlex: 0, showSkipButton: true,
onSkip: () => _onIntroEnd(buildContext, cubit), skipOrBackFlex: 0,
nextFlex: 0, onSkip: () => _onIntroEnd(buildContext, cubit),
skip: Text(tr('skip')), nextFlex: 0,
next: const Icon(Icons.arrow_forward), skip: Text(tr('skip')),
done: Text(tr('start'), next: const Icon(Icons.arrow_forward),
style: const TextStyle(fontWeight: FontWeight.w600)), done: Text(tr('start'),
dotsDecorator: const DotsDecorator( style: const TextStyle(fontWeight: FontWeight.w600)),
size: Size(10.0, 10.0), dotsDecorator: const DotsDecorator(
color: Color(0xFFBDBDBD), size: Size(10.0, 10.0),
activeColor: Colors.blueAccent, color: Color(0xFFBDBDBD),
activeSize: Size(22.0, 10.0), activeColor: Colors.blueAccent,
activeShape: RoundedRectangleBorder( activeSize: Size(22.0, 10.0),
borderRadius: BorderRadius.all(Radius.circular(25.0)), activeShape: RoundedRectangleBorder(
), borderRadius: BorderRadius.all(Radius.circular(25.0)),
), ),
); ),
}); );
});
} }
} }
PageViewModel createPageViewModel( PageViewModel createPageViewModel(String title, String body, String imageAsset,
String title, String body, String imageAsset, BuildContext context) { BuildContext context) {
final ColorScheme colorScheme = Theme.of(context).colorScheme; final ColorScheme colorScheme = Theme
.of(context)
.colorScheme;
final TextStyle titleStyle = TextStyle( final TextStyle titleStyle = TextStyle(
color: colorScheme.primary, color: colorScheme.primary,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
...@@ -270,7 +275,7 @@ class GinkgoApp extends StatefulWidget { ...@@ -270,7 +275,7 @@ class GinkgoApp extends StatefulWidget {
// The navigator key is necessary to navigate using static methods // The navigator key is necessary to navigate using static methods
static final GlobalKey<NavigatorState> navigatorKey = static final GlobalKey<NavigatorState> navigatorKey =
GlobalKey<NavigatorState>(); GlobalKey<NavigatorState>();
@override @override
State<GinkgoApp> createState() => _GinkgoAppState(); State<GinkgoApp> createState() => _GinkgoAppState();
...@@ -286,10 +291,16 @@ class _GinkgoAppState extends State<GinkgoApp> { ...@@ -286,10 +291,16 @@ class _GinkgoAppState extends State<GinkgoApp> {
} }
void _printNodeStatus({String prefix = 'Starting'}) { void _printNodeStatus({String prefix = 'Starting'}) {
final int nDuniterNodes = NodeManager().nodeList(NodeType.duniter).length; final int nDuniterNodes = NodeManager()
.nodeList(NodeType.duniter)
.length;
final int nCesiumPlusNodes = final int nCesiumPlusNodes =
NodeManager().nodeList(NodeType.cesiumPlus).length; NodeManager()
final int nGvaNodes = NodeManager().nodeList(NodeType.gva).length; .nodeList(NodeType.cesiumPlus)
.length;
final int nGvaNodes = NodeManager()
.nodeList(NodeType.gva)
.length;
logger( logger(
'$prefix with $nDuniterNodes duniter nodes, $nCesiumPlusNodes c+ nodes, and $nGvaNodes gva nodes'); '$prefix with $nDuniterNodes duniter nodes, $nCesiumPlusNodes c+ nodes, and $nGvaNodes gva nodes');
if (!kReleaseMode) { if (!kReleaseMode) {
...@@ -303,12 +314,13 @@ class _GinkgoAppState extends State<GinkgoApp> { ...@@ -303,12 +314,13 @@ class _GinkgoAppState extends State<GinkgoApp> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_initDeepLinkListener();
NodeManager().loadFromCubit(context.read<NodeListCubit>()); NodeManager().loadFromCubit(context.read<NodeListCubit>());
// Only after at least the action method is set, the notification events are delivered // Only after at least the action method is set, the notification events are delivered
NotificationController.startListeningNotificationEvents(); NotificationController.startListeningNotificationEvents();
Once.runHourly('load_nodes', callback: () async { Once.runHourly('load_nodes', callback: () async {
final bool isConnected = final bool isConnected =
await ConnectivityWidgetWrapperWrapper.isConnected; await ConnectivityWidgetWrapperWrapper.isConnected;
if (isConnected) { if (isConnected) {
logger('Load nodes via once'); logger('Load nodes via once');
_loadNodes(); _loadNodes();
...@@ -323,7 +335,10 @@ class _GinkgoAppState extends State<GinkgoApp> { ...@@ -323,7 +335,10 @@ class _GinkgoAppState extends State<GinkgoApp> {
Once.runDaily('clear_cache', callback: () { Once.runDaily('clear_cache', callback: () {
logger('clear cache via once'); logger('clear cache via once');
ContactsCache().clear(); ContactsCache().clear();
ContactsCache().addContacts(context.read<ContactsCubit>().state.contacts); ContactsCache().addContacts(context
.read<ContactsCubit>()
.state
.contacts);
}); });
Once.runOnce('resize_avatars', callback: () { Once.runOnce('resize_avatars', callback: () {
logger('resize avatar via once'); logger('resize avatar via once');
...@@ -334,101 +349,146 @@ class _GinkgoAppState extends State<GinkgoApp> { ...@@ -334,101 +349,146 @@ class _GinkgoAppState extends State<GinkgoApp> {
@override @override
void dispose() { void dispose() {
ContactsCache().dispose(); ContactsCache().dispose();
_disposeDeepLinkListener();
super.dispose(); super.dispose();
} }
late StreamSubscription<dynamic>? _sub;
Future<void> _initDeepLinkListener() async {
_sub = linkStream.listen((String? link) async {
if (!mounted) {
return;
}
if (link != null) {
logger('got link: $link');
if (parseScannedUri(link) != null) {
showDialog(
context: context,
builder: (BuildContext context) {
return
PayContactSearchPage(uri: link);
},
);
}
}
}, onError: (Object err) {
if (!mounted) {
return;
}
logger('got err: $err');
});
}
void _disposeDeepLinkListener() {
if (_sub != null) {
_sub!.cancel();
_sub = null;
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<NodeListCubit, NodeListState>( return BlocBuilder<NodeListCubit, NodeListState>(
builder: (BuildContext nodeContext, NodeListState state) { builder: (BuildContext nodeContext, NodeListState state) {
return ConnectivityAppWrapper( return ConnectivityAppWrapper(
app: FilesystemPickerDefaultOptions( app: FilesystemPickerDefaultOptions(
fileTileSelectMode: FileTileSelectMode.wholeTile, fileTileSelectMode: FileTileSelectMode.wholeTile,
theme: FilesystemPickerTheme( theme: FilesystemPickerTheme(
topBar: FilesystemPickerTopBarThemeData( topBar: FilesystemPickerTopBarThemeData(
backgroundColor: Theme.of(context).colorScheme.primary, backgroundColor: Theme
), .of(context)
), .colorScheme
child: MaterialApp( .primary,
/// Localization is not available for the title. ),
title: 'Ğ1nkgo', ),
theme: ThemeData( child: MaterialApp(
useMaterial3: true, colorScheme: lightColorScheme),
darkTheme: /// Localization is not available for the title.
title: 'Ğ1nkgo',
theme: ThemeData(
useMaterial3: true, colorScheme: lightColorScheme),
darkTheme:
ThemeData(useMaterial3: true, colorScheme: darkColorScheme), ThemeData(useMaterial3: true, colorScheme: darkColorScheme),
navigatorKey: GinkgoApp.navigatorKey, navigatorKey: GinkgoApp.navigatorKey,
scaffoldMessengerKey: globalMessengerKey, scaffoldMessengerKey: globalMessengerKey,
/// Theme stuff /// Theme stuff
themeMode: context.watch<ThemeCubit>().state.themeMode, themeMode: context
.watch<ThemeCubit>()
/// Localization stuff .state
localizationsDelegates: context.localizationDelegates, .themeMode,
supportedLocales: context.supportedLocales,
locale: context.locale, /// Localization stuff
debugShowCheckedModeBanner: false, localizationsDelegates: context.localizationDelegates,
home: context.read<AppCubit>().isIntroViewed supportedLocales: context.supportedLocales,
? BetterFeedback( locale: context.locale,
debugShowCheckedModeBanner: false,
home: context
.read<AppCubit>()
.isIntroViewed
? BetterFeedback(
localizationsDelegates: context.localizationDelegates localizationsDelegates: context.localizationDelegates
..add(CustomFeedbackLocalizationsDelegate()), ..add(CustomFeedbackLocalizationsDelegate()),
child: const SkeletonScreen()) child: const SkeletonScreen())
: const AppIntro(), : const AppIntro(),
builder: (BuildContext buildContext, Widget? widget) { builder: (BuildContext buildContext, Widget? widget) {
NotificationController.locale = context.locale; NotificationController.locale = context.locale;
return ResponsiveWrapper.builder( return ResponsiveWrapper.builder(
BouncingScrollWrapper.builder( BouncingScrollWrapper.builder(
context, context,
ConnectivityWidgetWrapperWrapper( ConnectivityWidgetWrapperWrapper(
//message: tr('offline'), //message: tr('offline'),
//height: 18, //height: 18,
offlineWidget: /* Container( offlineWidget: /* Container(
color: Colors.transparent, color: Colors.transparent,
child: Center( child: Center(
child: */ child: */
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
const Icon( const Icon(
Icons.cloud_off, Icons.cloud_off,
size: 48, size: 48,
color: Colors.grey,
),
const SizedBox(height: 6),
Container(
padding: const EdgeInsets.all(5.0),
decoration: const BoxDecoration(
color: Colors.grey, color: Colors.grey,
borderRadius:
BorderRadius.all(Radius.circular(10.0)),
), ),
child: Text( const SizedBox(height: 6),
tr('offline'), Container(
style: const TextStyle( padding: const EdgeInsets.all(5.0),
color: Colors.white, decoration: const BoxDecoration(
decoration: TextDecoration.none, color: Colors.grey,
fontSize: 14, borderRadius:
), BorderRadius.all(Radius.circular(10.0)),
)), ),
const SizedBox(height: 110), child: Text(
], tr('offline'),
), style: const TextStyle(
color: Colors.white,
child: widget!, decoration: TextDecoration.none,
)), fontSize: 14,
maxWidth: 480, ),
minWidth: 480, )),
// defaultScale: true, const SizedBox(height: 110),
breakpoints: <ResponsiveBreakpoint>[ ],
const ResponsiveBreakpoint.resize(200, name: MOBILE), ),
const ResponsiveBreakpoint.resize(480, name: TABLET),
const ResponsiveBreakpoint.resize(1000, name: DESKTOP), child: widget!,
], )),
background: Container(color: const Color(0xFFF5F5F5)), maxWidth: 480,
); minWidth: 480,
}, // defaultScale: true,
))); breakpoints: <ResponsiveBreakpoint>[
}); const ResponsiveBreakpoint.resize(200, name: MOBILE),
const ResponsiveBreakpoint.resize(480, name: TABLET),
const ResponsiveBreakpoint.resize(
1000, name: DESKTOP),
],
background: Container(color: const Color(0xFFF5F5F5)),
);
},
)));
});
} }
} }
...@@ -1459,6 +1459,30 @@ packages: ...@@ -1459,6 +1459,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
uni_links:
dependency: "direct main"
description:
name: uni_links
sha256: "051098acfc9e26a9fde03b487bef5d3d228ca8f67693480c6f33fd4fbb8e2b6e"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
uni_links_platform_interface:
dependency: transitive
description:
name: uni_links_platform_interface
sha256: "929cf1a71b59e3b7c2d8a2605a9cf7e0b125b13bc858e55083d88c62722d4507"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
uni_links_web:
dependency: transitive
description:
name: uni_links_web
sha256: "7539db908e25f67de2438e33cc1020b30ab94e66720b5677ba6763b25f6394df"
url: "https://pub.dev"
source: hosted
version: "0.1.0"
universal_html: universal_html:
dependency: "direct main" dependency: "direct main"
description: description:
......
...@@ -92,6 +92,7 @@ dependencies: ...@@ -92,6 +92,7 @@ dependencies:
crypto: ^3.0.3 crypto: ^3.0.3
flutter_nfc_kit: ^3.3.1 flutter_nfc_kit: ^3.3.1
ndef: ^0.3.1 ndef: ^0.3.1
uni_links: ^0.5.1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
......
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