114 lines
3.5 KiB
Dart
114 lines
3.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:supabase_flutter/supabase_flutter.dart';
|
|
import 'package:intl/date_symbol_data_local.dart';
|
|
import 'package:app_links/app_links.dart';
|
|
import 'core/routes.dart';
|
|
|
|
const _supabaseUrl = 'https://xeotegswjwmhkwvtuxgx.supabase.co';
|
|
const _supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inhlb3RlZ3N3andtaGt3dnR1eGd4Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzIxODEwMjcsImV4cCI6MjA4Nzc1NzAyN30.PW6IQhpO8PRhPzA3ycPOgy_-Pqw9XQ0BCCE5ukPCcVM';
|
|
|
|
void main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
await initializeDateFormatting('pt_PT', null);
|
|
|
|
await Supabase.initialize(
|
|
url: _supabaseUrl,
|
|
anonKey: _supabaseAnonKey,
|
|
authOptions: const FlutterAuthClientOptions(
|
|
authFlowType: AuthFlowType.pkce,
|
|
),
|
|
);
|
|
|
|
runApp(const ProviderScope(child: CrecheApp()));
|
|
}
|
|
|
|
class CrecheApp extends ConsumerStatefulWidget {
|
|
const CrecheApp({super.key});
|
|
@override
|
|
ConsumerState<CrecheApp> createState() => _CrecheAppState();
|
|
}
|
|
|
|
class _CrecheAppState extends ConsumerState<CrecheApp> {
|
|
final _appLinks = AppLinks();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_initDeepLinks();
|
|
}
|
|
|
|
Future<void> _initDeepLinks() async {
|
|
try {
|
|
final initialUri = await _appLinks.getInitialLink();
|
|
if (initialUri != null && _isAuthUri(initialUri)) {
|
|
await _handleDeepLink(initialUri);
|
|
}
|
|
} catch (_) {}
|
|
|
|
_appLinks.uriLinkStream.listen(
|
|
(uri) { if (_isAuthUri(uri)) _handleDeepLink(uri); },
|
|
onError: (_) {},
|
|
);
|
|
}
|
|
|
|
bool _isAuthUri(Uri uri) {
|
|
final q = uri.queryParameters;
|
|
return q.containsKey('code') ||
|
|
q.containsKey('access_token') ||
|
|
q.containsKey('token_hash') ||
|
|
uri.host == 'login-callback' ||
|
|
uri.path.contains('login-callback');
|
|
}
|
|
|
|
Future<void> _handleDeepLink(Uri uri) async {
|
|
try {
|
|
await Supabase.instance.client.auth.getSessionFromUrl(uri);
|
|
} catch (e) {
|
|
debugPrint('Deep link error: $e');
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final router = ref.watch(goRouterProvider);
|
|
return MaterialApp.router(
|
|
title: 'Diário do Candengue',
|
|
debugShowCheckedModeBanner: false,
|
|
routerConfig: router,
|
|
theme: ThemeData(
|
|
brightness: Brightness.dark,
|
|
scaffoldBackgroundColor: const Color(0xFF0D1117),
|
|
colorScheme: const ColorScheme.dark(
|
|
primary: Color(0xFF4FC3F7),
|
|
secondary: Color(0xFF2ECC71),
|
|
surface: Color(0xFF161B22),
|
|
error: Color(0xFFE74C3C),
|
|
),
|
|
appBarTheme: const AppBarTheme(
|
|
backgroundColor: Color(0xFF161B22),
|
|
elevation: 0,
|
|
iconTheme: IconThemeData(color: Color(0xFF4FC3F7)),
|
|
titleTextStyle: TextStyle(
|
|
color: Color(0xFF4FC3F7), fontSize: 18, fontWeight: FontWeight.bold),
|
|
),
|
|
bottomNavigationBarTheme: const BottomNavigationBarThemeData(
|
|
backgroundColor: Color(0xFF161B22),
|
|
selectedItemColor: Color(0xFF4FC3F7),
|
|
unselectedItemColor: Color(0xFF888888),
|
|
type: BottomNavigationBarType.fixed,
|
|
),
|
|
inputDecorationTheme: InputDecorationTheme(
|
|
filled: true,
|
|
fillColor: Colors.white.withOpacity(0.04),
|
|
border: OutlineInputBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
borderSide: BorderSide(color: Colors.white.withOpacity(0.09)),
|
|
),
|
|
),
|
|
useMaterial3: true,
|
|
),
|
|
);
|
|
}
|
|
}
|