181 lines
4.8 KiB
Dart
181 lines
4.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'core/theme.dart';
|
|
import 'core/config.dart';
|
|
import 'core/auth_gate.dart';
|
|
import 'features/webview/webview_screen.dart';
|
|
import 'features/input/input_screen.dart';
|
|
import 'features/settings/settings_screen.dart';
|
|
|
|
void main() {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// Set system UI overlay style
|
|
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
|
statusBarColor: Colors.transparent,
|
|
statusBarIconBrightness: Brightness.light,
|
|
systemNavigationBarColor: AppTheme.surfaceColor,
|
|
systemNavigationBarIconBrightness: Brightness.light,
|
|
));
|
|
|
|
runApp(const InouApp());
|
|
}
|
|
|
|
class InouApp extends StatefulWidget {
|
|
const InouApp({super.key});
|
|
|
|
// Navigator key for deep linking
|
|
static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
|
|
|
@override
|
|
State<InouApp> createState() => _InouAppState();
|
|
}
|
|
|
|
class _InouAppState extends State<InouApp> {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_initDeepLinks();
|
|
}
|
|
|
|
void _initDeepLinks() {
|
|
// Handle initial deep link (app opened from link)
|
|
_handleInitialDeepLink();
|
|
|
|
// Listen for incoming deep links while app is running
|
|
// Note: In production, use app_links or uni_links package
|
|
// This is a placeholder for the deep link handling logic
|
|
}
|
|
|
|
Future<void> _handleInitialDeepLink() async {
|
|
// Get the initial link that launched the app
|
|
// In production, use PlatformDispatcher.instance.views.first.platformDispatcher
|
|
// or app_links package to get the initial URL
|
|
|
|
// For now, we'll just ensure the app starts normally
|
|
// Deep links will be handled via the onGenerateRoute
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MaterialApp(
|
|
navigatorKey: InouApp.navigatorKey,
|
|
title: AppConfig.appName,
|
|
theme: AppTheme.darkTheme,
|
|
debugShowCheckedModeBanner: false,
|
|
home: const AuthGate(
|
|
child: MainScaffold(),
|
|
),
|
|
onGenerateRoute: _onGenerateRoute,
|
|
);
|
|
}
|
|
|
|
/// Handle deep links: inou.com/app/* should open in WebView
|
|
Route<dynamic>? _onGenerateRoute(RouteSettings settings) {
|
|
final uri = Uri.tryParse(settings.name ?? '');
|
|
|
|
if (uri != null && _isInouAppUrl(uri)) {
|
|
// Deep link to inou.com/app/*
|
|
return MaterialPageRoute(
|
|
builder: (context) => Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text(AppConfig.appName),
|
|
backgroundColor: AppTheme.backgroundColor,
|
|
leading: IconButton(
|
|
icon: const Icon(Icons.close),
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
),
|
|
),
|
|
body: WebViewScreen(
|
|
initialUrl: uri.toString(),
|
|
showAppBar: false,
|
|
),
|
|
),
|
|
settings: settings,
|
|
);
|
|
}
|
|
|
|
// Default route handling
|
|
return null;
|
|
}
|
|
|
|
/// Check if URL is an inou app URL
|
|
bool _isInouAppUrl(Uri uri) {
|
|
return uri.host == 'inou.com' && uri.path.startsWith('/app');
|
|
}
|
|
}
|
|
|
|
class MainScaffold extends StatefulWidget {
|
|
const MainScaffold({super.key});
|
|
|
|
@override
|
|
State<MainScaffold> createState() => MainScaffoldState();
|
|
}
|
|
|
|
class MainScaffoldState extends State<MainScaffold> {
|
|
int _currentIndex = 0;
|
|
final GlobalKey<WebViewScreenState> _webViewKey = GlobalKey();
|
|
|
|
final List<Widget> _screens = [];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_screens.addAll([
|
|
WebViewScreen(key: _webViewKey),
|
|
const InputScreen(),
|
|
const SettingsScreen(),
|
|
]);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: IndexedStack(
|
|
index: _currentIndex,
|
|
children: _screens,
|
|
),
|
|
bottomNavigationBar: NavigationBar(
|
|
selectedIndex: _currentIndex,
|
|
onDestinationSelected: (index) {
|
|
setState(() {
|
|
_currentIndex = index;
|
|
});
|
|
},
|
|
backgroundColor: AppTheme.surfaceColor,
|
|
indicatorColor: AppTheme.primaryColor.withOpacity(0.2),
|
|
destinations: const [
|
|
NavigationDestination(
|
|
icon: Icon(Icons.home_outlined),
|
|
selectedIcon: Icon(Icons.home),
|
|
label: 'Home',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.edit_outlined),
|
|
selectedIcon: Icon(Icons.edit),
|
|
label: 'Input',
|
|
),
|
|
NavigationDestination(
|
|
icon: Icon(Icons.settings_outlined),
|
|
selectedIcon: Icon(Icons.settings),
|
|
label: 'Settings',
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// Navigate to the WebView and load a specific URL
|
|
void loadInWebView(String url) {
|
|
setState(() {
|
|
_currentIndex = 0;
|
|
});
|
|
_webViewKey.currentState?.loadUrl(url);
|
|
}
|
|
|
|
/// Reload the WebView
|
|
void reloadWebView() {
|
|
_webViewKey.currentState?.reload();
|
|
}
|
|
}
|