forked from firka/firka
switch to go_router
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:typed_data';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:firka/api/client/kreta_client.dart';
|
||||
import 'package:firka/data/models/token_model.dart';
|
||||
import 'package:firka/core/state/update_notifier.dart';
|
||||
@@ -17,12 +18,19 @@ final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
late AppInitialization initData;
|
||||
bool initDone = false;
|
||||
|
||||
/// Set when app router is created; used for deep links and notifications.
|
||||
GoRouter? appRouter;
|
||||
|
||||
final dio = Dio();
|
||||
final isBeta = true;
|
||||
|
||||
final ValueNotifier<bool> isLightMode = ValueNotifier<bool>(true);
|
||||
final UpdateNotifier globalUpdate = UpdateNotifier();
|
||||
|
||||
/// Used by home shell screens for pull-to-refresh coordination.
|
||||
final UpdateNotifier homeUpdateNotifier = UpdateNotifier();
|
||||
final UpdateNotifier homeUpdateFinishedNotifier = UpdateNotifier();
|
||||
|
||||
class DeviceInfo {
|
||||
String model;
|
||||
|
||||
|
||||
@@ -6,16 +6,21 @@ import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/app/initialization.dart';
|
||||
import 'package:firka/core/firka_bundle.dart';
|
||||
import 'package:firka/routing/app_router.dart';
|
||||
import 'package:firka/services/watch_sync_helper.dart';
|
||||
import 'package:firka/l10n/app_localizations.dart';
|
||||
import 'package:firka/ui/phone/screens/debug/debug_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/login/login_screen.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class InitializationScreen extends StatelessWidget {
|
||||
InitializationScreen({super.key});
|
||||
class InitializationScreen extends StatefulWidget {
|
||||
const InitializationScreen({super.key});
|
||||
|
||||
@override
|
||||
State<InitializationScreen> createState() => _InitializationScreenState();
|
||||
}
|
||||
|
||||
class _InitializationScreenState extends State<InitializationScreen> {
|
||||
GoRouter? _router;
|
||||
final Future<AppInitialization> _init = initializeApp().timeout(
|
||||
const Duration(seconds: 20),
|
||||
);
|
||||
@@ -25,7 +30,6 @@ class InitializationScreen extends StatelessWidget {
|
||||
return FutureBuilder<AppInitialization>(
|
||||
future: _init,
|
||||
builder: (context, snapshot) {
|
||||
// Check if initialization is complete
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
if (snapshot.hasError) {
|
||||
logger.shout(
|
||||
@@ -36,16 +40,15 @@ class InitializationScreen extends StatelessWidget {
|
||||
|
||||
FlutterNativeSplash.remove();
|
||||
|
||||
// Handle initialization error
|
||||
return MaterialApp(
|
||||
key: ValueKey('errorPage'),
|
||||
key: const ValueKey('errorPage'),
|
||||
home: DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: Scaffold(
|
||||
body: Center(
|
||||
child: Text(
|
||||
'Error initializing app: ${snapshot.error}',
|
||||
style: TextStyle(color: Colors.red),
|
||||
style: const TextStyle(color: Colors.red),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -53,9 +56,6 @@ class InitializationScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// Initialization successful, determine which screen to show
|
||||
Widget screen;
|
||||
|
||||
assert(snapshot.data != null);
|
||||
initData = snapshot.data!;
|
||||
initDone = true;
|
||||
@@ -89,43 +89,33 @@ class InitializationScreen extends StatelessWidget {
|
||||
watchChannel.invokeMethod('sendMessageToWatch', {
|
||||
"id": "pong",
|
||||
});
|
||||
navigatorKey.currentState?.push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => HomeScreen(
|
||||
initData,
|
||||
true,
|
||||
model: msg["model"] as String? ?? "unknown",
|
||||
),
|
||||
),
|
||||
);
|
||||
_router?.go('/home');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (snapshot.data!.tokens.isEmpty) {
|
||||
screen = LoginScreen(initData, key: ValueKey('loginScreen'));
|
||||
} else {
|
||||
screen = HomeScreen(initData, false, key: ValueKey('homeScreen'));
|
||||
if (_router == null) {
|
||||
_router = createAppRouter();
|
||||
appRouter = _router;
|
||||
}
|
||||
|
||||
return MaterialApp(
|
||||
return MaterialApp.router(
|
||||
title: 'Firka',
|
||||
key: ValueKey('firkaApp'),
|
||||
navigatorKey: navigatorKey,
|
||||
key: const ValueKey('firkaApp'),
|
||||
routerConfig: _router!,
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.lightGreen,
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
localizationsDelegates: [
|
||||
localizationsDelegates: const [
|
||||
AppLocalizations.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: ValueListenableBuilder<bool>(
|
||||
builder: (context, child) {
|
||||
return ValueListenableBuilder<bool>(
|
||||
valueListenable: isLightMode,
|
||||
builder: (context, isLight, _) {
|
||||
final overlay = SystemUiOverlayStyle(
|
||||
@@ -143,24 +133,10 @@ class InitializationScreen extends StatelessWidget {
|
||||
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
value: overlay,
|
||||
child: screen,
|
||||
child: child ?? const SizedBox.shrink(),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
routes: {
|
||||
'/login': (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: LoginScreen(initData, key: ValueKey('loginScreen')),
|
||||
),
|
||||
'/home': (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeScreen(initData, false, key: ValueKey('homeScreen')),
|
||||
),
|
||||
'/debug': (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: DebugScreen(initData, key: ValueKey('debugScreen')),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/app/initialization.dart';
|
||||
import 'package:firka/app/initialization_screen.dart';
|
||||
import 'package:firka/ui/phone/pages/error/error_page.dart';
|
||||
|
||||
void main() async {
|
||||
logger = Logger("Firka");
|
||||
@@ -35,14 +34,8 @@ void main() async {
|
||||
logger.shout('Caught error: $error');
|
||||
logger.shout('Stack trace: $stackTrace');
|
||||
|
||||
navigatorKey.currentState?.push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ErrorPage(
|
||||
key: ValueKey('errorPage'),
|
||||
exception: error.toString(),
|
||||
),
|
||||
),
|
||||
);
|
||||
final message = '$error\n$stackTrace';
|
||||
appRouter?.go('/error', extra: message);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
268
firka/lib/routing/app_router.dart
Normal file
268
firka/lib/routing/app_router.dart
Normal file
@@ -0,0 +1,268 @@
|
||||
import 'dart:collection';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:firka/core/firka_bundle.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/core/settings.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_grades.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_grades_subject.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_main.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_timetable.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_timetable_mo.dart';
|
||||
import 'package:firka/ui/phone/screens/debug/debug_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/home/beta_screen.dart';
|
||||
import 'package:firka/ui/phone/pages/error/error_page.dart';
|
||||
import 'package:firka/ui/phone/screens/login/login_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/message/message_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/settings/settings_screen.dart';
|
||||
import 'package:firka/routing/shell_with_nav_bar.dart';
|
||||
import 'package:firka/routing/swipable_navigator_container.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:firka/api/model/notice_board.dart';
|
||||
|
||||
GoRouter createAppRouter() {
|
||||
return GoRouter(
|
||||
navigatorKey: navigatorKey,
|
||||
initialLocation: _initialLocation,
|
||||
redirect: _redirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/error',
|
||||
builder: (context, state) {
|
||||
final exception = state.extra is String
|
||||
? state.extra as String
|
||||
: 'Unknown error';
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: ErrorPage(key: state.pageKey, exception: exception),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/login',
|
||||
builder: (context, state) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: LoginScreen(initData, key: state.pageKey),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/beta',
|
||||
builder: (context, state) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: BetaScreen(initData, key: state.pageKey),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/debug',
|
||||
builder: (context, state) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: DebugScreen(initData, key: state.pageKey),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/settings',
|
||||
builder: (context, state) {
|
||||
final items = state.extra != null
|
||||
? state.extra! as LinkedHashMap<String, SettingsItem>
|
||||
: initData.settings.items;
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: SettingsScreen(initData, items, key: state.pageKey),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: '/message',
|
||||
builder: (context, state) {
|
||||
final info = state.extra as InfoBoardItem?;
|
||||
if (info == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: MessageScreen(initData, info, key: state.pageKey),
|
||||
);
|
||||
},
|
||||
),
|
||||
StatefulShellRoute(
|
||||
builder: (context, state, navigationShell) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeScreen(
|
||||
child: ShellWithNavBar(
|
||||
navigationShell: navigationShell,
|
||||
child: navigationShell,
|
||||
),
|
||||
),
|
||||
),
|
||||
navigatorContainerBuilder: (context, navigationShell, children) {
|
||||
return SwipableNavigatorContainer(
|
||||
navigationShell: navigationShell,
|
||||
children: children,
|
||||
);
|
||||
},
|
||||
branches: [
|
||||
StatefulShellBranch(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/home',
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
key: state.pageKey,
|
||||
child: DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeMainScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'subject/:uid',
|
||||
builder: (context, state) {
|
||||
final uid = state.pathParameters['uid'] ?? '';
|
||||
activeSubjectUid = uid;
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeGradesSubjectScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
StatefulShellBranch(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/grades',
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
key: state.pageKey,
|
||||
child: DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeGradesScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'subject/:uid',
|
||||
builder: (context, state) {
|
||||
final uid = state.pathParameters['uid'] ?? '';
|
||||
activeSubjectUid = uid;
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeGradesSubjectScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
StatefulShellBranch(
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/timetable',
|
||||
pageBuilder: (context, state) => NoTransitionPage(
|
||||
key: state.pageKey,
|
||||
child: DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeTimetableScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'monthly',
|
||||
builder: (context, state) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeTimetableMonthlyScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: 'subject/:uid',
|
||||
builder: (context, state) {
|
||||
final uid = state.pathParameters['uid'] ?? '';
|
||||
activeSubjectUid = uid;
|
||||
return DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeGradesSubjectScreen(
|
||||
initData,
|
||||
homeUpdateNotifier,
|
||||
homeUpdateFinishedNotifier,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String get _initialLocation {
|
||||
if (!initDone) return '/';
|
||||
if (initData.tokens.isEmpty) return '/login';
|
||||
final betaWarning = initData.settings
|
||||
.group('settings')
|
||||
.boolean('beta_warning');
|
||||
if (!betaWarning) return '/beta';
|
||||
return '/home';
|
||||
}
|
||||
|
||||
String? _redirect(BuildContext context, GoRouterState state) {
|
||||
if (!initDone) return null;
|
||||
final location = state.matchedLocation;
|
||||
final hasTokens = initData.tokens.isNotEmpty;
|
||||
final betaWarning = initData.settings
|
||||
.group('settings')
|
||||
.boolean('beta_warning');
|
||||
|
||||
if (!hasTokens) {
|
||||
if (location != '/login') return '/login';
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!betaWarning && location != '/beta') {
|
||||
return '/beta';
|
||||
}
|
||||
|
||||
if (betaWarning && location == '/beta') {
|
||||
return '/home';
|
||||
}
|
||||
|
||||
if (hasTokens && location == '/login') {
|
||||
return '/home';
|
||||
}
|
||||
|
||||
if (location == '/' || location.isEmpty) {
|
||||
return '/home';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
118
firka/lib/routing/shell_with_nav_bar.dart
Normal file
118
firka/lib/routing/shell_with_nav_bar.dart
Normal file
@@ -0,0 +1,118 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/ui/phone/pages/extras/extras.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/phone/widgets/bottom_nav_icon.dart';
|
||||
|
||||
class ShellWithNavBar extends StatelessWidget {
|
||||
const ShellWithNavBar({
|
||||
super.key,
|
||||
required this.navigationShell,
|
||||
required this.child,
|
||||
});
|
||||
|
||||
final StatefulNavigationShell navigationShell;
|
||||
final Widget child;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final data = initData;
|
||||
final currentIndex = navigationShell.currentIndex;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: appStyle.colors.background,
|
||||
body: child,
|
||||
bottomNavigationBar: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.bottomCenter,
|
||||
end: Alignment.topCenter,
|
||||
colors: [
|
||||
appStyle.colors.background,
|
||||
appStyle.colors.background.withValues(alpha: 0.0),
|
||||
],
|
||||
stops: const [0.0, 1.0],
|
||||
),
|
||||
),
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
child: SafeArea(
|
||||
top: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(55, 0, 55, 12),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
BottomNavIconWidget(
|
||||
() {
|
||||
if (currentIndex != 0) {
|
||||
navigationShell.goBranch(0);
|
||||
}
|
||||
},
|
||||
currentIndex == 0,
|
||||
currentIndex == 0
|
||||
? Majesticon.homeSolid
|
||||
: Majesticon.homeLine,
|
||||
data.l10n.home,
|
||||
currentIndex == 0
|
||||
? appStyle.colors.accent
|
||||
: appStyle.colors.secondary,
|
||||
appStyle.colors.textPrimary,
|
||||
),
|
||||
BottomNavIconWidget(
|
||||
() {
|
||||
if (currentIndex != 1) {
|
||||
navigationShell.goBranch(1);
|
||||
}
|
||||
},
|
||||
currentIndex == 1,
|
||||
currentIndex == 1
|
||||
? Majesticon.bookmarkSolid
|
||||
: Majesticon.bookmarkLine,
|
||||
data.l10n.grades,
|
||||
currentIndex == 1
|
||||
? appStyle.colors.accent
|
||||
: appStyle.colors.secondary,
|
||||
appStyle.colors.textPrimary,
|
||||
),
|
||||
BottomNavIconWidget(
|
||||
() {
|
||||
if (currentIndex != 2) {
|
||||
navigationShell.goBranch(2);
|
||||
}
|
||||
},
|
||||
currentIndex == 2,
|
||||
currentIndex == 2
|
||||
? Majesticon.calendarSolid
|
||||
: Majesticon.calendarLine,
|
||||
data.l10n.timetable,
|
||||
currentIndex == 2
|
||||
? appStyle.colors.accent
|
||||
: appStyle.colors.secondary,
|
||||
appStyle.colors.textPrimary,
|
||||
),
|
||||
BottomNavIconWidget(
|
||||
() {
|
||||
HapticFeedback.lightImpact();
|
||||
showExtrasBottomSheet(context, data);
|
||||
},
|
||||
false,
|
||||
data.profilePicture != null
|
||||
? data.profilePicture!
|
||||
: Majesticon.menuLine,
|
||||
data.l10n.other,
|
||||
appStyle.colors.secondary,
|
||||
appStyle.colors.textPrimary,
|
||||
isProfilePicture: data.profilePicture != null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
92
firka/lib/routing/swipable_navigator_container.dart
Normal file
92
firka/lib/routing/swipable_navigator_container.dart
Normal file
@@ -0,0 +1,92 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class SwipableNavigatorContainer extends StatefulWidget {
|
||||
const SwipableNavigatorContainer({
|
||||
super.key,
|
||||
required this.navigationShell,
|
||||
required this.children,
|
||||
});
|
||||
|
||||
final StatefulNavigationShell navigationShell;
|
||||
final List<Widget> children;
|
||||
|
||||
@override
|
||||
State<SwipableNavigatorContainer> createState() =>
|
||||
_SwipableNavigatorContainerState();
|
||||
}
|
||||
|
||||
class _SwipableNavigatorContainerState
|
||||
extends State<SwipableNavigatorContainer> {
|
||||
late PageController _pageController;
|
||||
bool _isAnimating = false;
|
||||
bool _isFirstBuild = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_pageController = PageController(
|
||||
initialPage: widget.navigationShell.currentIndex,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(SwipableNavigatorContainer oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.navigationShell.currentIndex !=
|
||||
widget.navigationShell.currentIndex) {
|
||||
_syncToShellIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void _syncToShellIndex() {
|
||||
if (_isFirstBuild) {
|
||||
_isFirstBuild = false;
|
||||
if (_pageController.hasClients &&
|
||||
_pageController.page?.round() !=
|
||||
widget.navigationShell.currentIndex) {
|
||||
_pageController.jumpToPage(widget.navigationShell.currentIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!_pageController.hasClients) return;
|
||||
if (_pageController.page?.round() == widget.navigationShell.currentIndex) {
|
||||
return;
|
||||
}
|
||||
_isAnimating = true;
|
||||
_pageController
|
||||
.animateToPage(
|
||||
widget.navigationShell.currentIndex,
|
||||
duration: const Duration(milliseconds: 175),
|
||||
curve: Curves.easeInOut,
|
||||
)
|
||||
.then((_) {
|
||||
if (mounted) _isAnimating = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _onPageChanged(int index) {
|
||||
if (_isAnimating) return;
|
||||
if (index != widget.navigationShell.currentIndex) {
|
||||
HapticFeedback.heavyImpact();
|
||||
widget.navigationShell.goBranch(index);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PageView(
|
||||
controller: _pageController,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
onPageChanged: _onPageChanged,
|
||||
children: widget.children,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,9 @@ import 'package:intl/intl.dart';
|
||||
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:firka/ui/phone/pages/home/home_grades.dart';
|
||||
import 'package:firka/ui/phone/widgets/lesson.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:firka/ui/shared/class_icon.dart';
|
||||
import 'package:firka/api/model/timetable.dart';
|
||||
import 'package:firka/ui/components/firka_card.dart';
|
||||
@@ -295,11 +296,14 @@ Future<void> showLessonBottomSheet(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
),
|
||||
onTap: () {
|
||||
activeSubjectUid = lesson.subject!.uid;
|
||||
subjectName = lesson.subject!.name;
|
||||
subjectId = lesson.subject!.uid;
|
||||
subjectCategory = lesson.subject!.category.name ?? "";
|
||||
subjectInfo = [];
|
||||
Navigator.pop(context);
|
||||
pageNavNotifier.value = PageNavData(
|
||||
HomePage.grades,
|
||||
lesson.subject!.uid,
|
||||
lesson.subject!.name,
|
||||
context.push(
|
||||
'/timetable/subject/${lesson.subject!.uid}',
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -728,11 +732,15 @@ Future<void> showGradeBottomSheet(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
),
|
||||
onTap: () {
|
||||
activeSubjectUid = grade.subject.uid;
|
||||
subjectName = grade.subject.name;
|
||||
subjectId = grade.subject.uid;
|
||||
subjectCategory =
|
||||
grade.subject.category.name ?? "";
|
||||
subjectInfo = [];
|
||||
Navigator.pop(context);
|
||||
pageNavNotifier.value = PageNavData(
|
||||
HomePage.grades,
|
||||
grade.subject.uid,
|
||||
grade.subject.name,
|
||||
context.go(
|
||||
'/grades/subject/${grade.subject.uid}',
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -955,12 +963,13 @@ Future<void> showHomeworkBottomSheet(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
),
|
||||
onTap: () {
|
||||
activeSubjectUid = homework.subject.uid;
|
||||
subjectName = homework.subjectName;
|
||||
subjectId = homework.subject.uid;
|
||||
subjectCategory = "";
|
||||
subjectInfo = [];
|
||||
Navigator.pop(context);
|
||||
pageNavNotifier.value = PageNavData(
|
||||
HomePage.grades,
|
||||
homework.subject.uid,
|
||||
homework.subjectName,
|
||||
);
|
||||
context.push('/home/subject/${homework.subject.uid}');
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -3,14 +3,11 @@ import 'package:firka/core/settings.dart';
|
||||
import 'package:firka/ui/components/firka_shadow.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/phone/screens/settings/settings_screen.dart';
|
||||
import 'package:firka/ui/shared/firka_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
|
||||
import 'package:firka/core/firka_bundle.dart';
|
||||
import 'package:firka/ui/phone/screens/debug/debug_screen.dart';
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
Widget Function(double) debugBtn = (_) => const SizedBox();
|
||||
@@ -20,17 +17,9 @@ void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
if (isDeveloper()) {
|
||||
debugBtn = (double itemWidth) => GestureDetector(
|
||||
// Fejlesztői menü
|
||||
onTap: () => {
|
||||
Navigator.pop(context),
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: DebugScreen(data),
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
context.pop();
|
||||
context.push('/debug');
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 60,
|
||||
@@ -126,20 +115,11 @@ void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
GestureDetector(
|
||||
// Fiókod
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: SettingsScreen(
|
||||
data,
|
||||
data.settings.items.group(
|
||||
"profile_settings",
|
||||
),
|
||||
),
|
||||
),
|
||||
context.pop();
|
||||
context.push(
|
||||
'/settings',
|
||||
extra: data.settings.items.group(
|
||||
"profile_settings",
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -189,20 +169,8 @@ void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
GestureDetector(
|
||||
// Beállítás
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) =>
|
||||
DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: SettingsScreen(
|
||||
data,
|
||||
data.settings.items,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
context.pop();
|
||||
context.push('/settings');
|
||||
},
|
||||
child: SizedBox(
|
||||
height: 60,
|
||||
@@ -289,22 +257,8 @@ void showExtrasBottomSheet(BuildContext context, AppInitialization data) {
|
||||
.group("settings")["developer_enabled"]!
|
||||
.postUpdate();
|
||||
|
||||
Navigator.of(
|
||||
navigatorKey.currentContext!,
|
||||
).popUntil((route) => false);
|
||||
Navigator.push(
|
||||
navigatorKey.currentContext!,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: HomeScreen(
|
||||
data,
|
||||
false,
|
||||
key: ValueKey('homeScreen'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
context.pop();
|
||||
context.go('/home');
|
||||
} else if (debugCounter < 10) {
|
||||
debugCounter++;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import 'package:firka/ui/components/grade_helpers.dart';
|
||||
import 'package:firka/ui/phone/widgets/grade_chart.dart';
|
||||
import 'package:firka/ui/shared/grade_small_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:firka/api/consts.dart';
|
||||
import 'package:firka/api/model/class_group.dart';
|
||||
@@ -23,13 +24,11 @@ class HomeGradesScreen extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
final UpdateNotifier updateNotifier;
|
||||
final UpdateNotifier finishNotifier;
|
||||
final void Function(int) pageController;
|
||||
|
||||
const HomeGradesScreen(
|
||||
this.data,
|
||||
this.updateNotifier,
|
||||
this.finishNotifier,
|
||||
this.pageController, {
|
||||
this.finishNotifier, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -185,7 +184,7 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
subjectInfo = subjects
|
||||
.where((s) => s.uid == subject.uid)
|
||||
.toList();
|
||||
widget.pageController(1);
|
||||
context.go('/grades/subject/${subject.uid}');
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -201,7 +200,7 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
subjectInfo = subjects
|
||||
.where((s) => s.uid == subject.uid)
|
||||
.toList();
|
||||
widget.pageController(1);
|
||||
context.go('/grades/subject/${subject.uid}');
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:firka/ui/phone/pages/home/home_grades.dart';
|
||||
import 'package:firka/ui/shared/class_icon.dart';
|
||||
import 'package:firka/ui/shared/firka_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
|
||||
@@ -19,13 +20,11 @@ class HomeGradesSubjectScreen extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
final UpdateNotifier updateNotifier;
|
||||
final UpdateNotifier finishNotifier;
|
||||
final void Function(int) pageController;
|
||||
|
||||
const HomeGradesSubjectScreen(
|
||||
this.data,
|
||||
this.updateNotifier,
|
||||
this.finishNotifier,
|
||||
this.pageController, {
|
||||
this.finishNotifier, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -142,235 +141,241 @@ class _HomeGradesSubjectScreen extends FirkaState<HomeGradesSubjectScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: GestureDetector(
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.chevronLeftLine,
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
onTap: () {
|
||||
widget.pageController(0);
|
||||
},
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: Text(
|
||||
widget.data.l10n.subjects,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GestureDetector(
|
||||
child: Card(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.menuSolid,
|
||||
size: 26.0,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
// Navigator.push(context, Settings)
|
||||
// showSubjectBottomSheetSettings(
|
||||
// context,
|
||||
// widget.data,
|
||||
// aGrade.subject,
|
||||
// );
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// SizedBox(height: 16),
|
||||
// GradeChart(grades: grades?.toList() ?? []),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
230,
|
||||
child: ListView(
|
||||
return Material(
|
||||
color: appStyle.colors.background,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 12),
|
||||
Column(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Card(
|
||||
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
|
||||
color: appStyle.colors.a15p,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsGeometry.all(6),
|
||||
child: ClassIconWidget(
|
||||
uid: aGrade.subject.uid,
|
||||
className: aGrade.subject.name,
|
||||
category: aGrade.subject.category.name!,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
aGrade.subject.name,
|
||||
style: appStyle.fonts.H_H2.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
aGrade.teacher,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: gradeWidgets,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: GestureDetector(
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.chevronLeftLine,
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
onTap: () {
|
||||
widget.pageController(0);
|
||||
},
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 1),
|
||||
child: Text(
|
||||
widget.data.l10n.subjects,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
230,
|
||||
child: ListView(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Card(
|
||||
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
|
||||
color: appStyle.colors.a15p,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsGeometry.all(6),
|
||||
child: ClassIconWidget(
|
||||
uid: subjectId,
|
||||
className: subjectName,
|
||||
category: subjectCategory,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
subjectName,
|
||||
style: appStyle.fonts.H_H2.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
widget.data.l10n.unknown_teacher,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
320,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
Row(
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/images/logos/dave.svg",
|
||||
width: 48,
|
||||
height: 48,
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: GestureDetector(
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.chevronLeftLine,
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
onTap: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
widget.data.l10n.no_grades,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: Text(
|
||||
widget.data.l10n.subjects,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
GestureDetector(
|
||||
child: Card(
|
||||
color: appStyle.colors.buttonSecondaryFill,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.menuSolid,
|
||||
size: 26.0,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
// Navigator.push(context, Settings)
|
||||
// showSubjectBottomSheetSettings(
|
||||
// context,
|
||||
// widget.data,
|
||||
// aGrade.subject,
|
||||
// );
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
// SizedBox(height: 16),
|
||||
// GradeChart(grades: grades?.toList() ?? []),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
230,
|
||||
child: ListView(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Card(
|
||||
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
|
||||
color: appStyle.colors.a15p,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsGeometry.all(6),
|
||||
child: ClassIconWidget(
|
||||
uid: aGrade.subject.uid,
|
||||
className: aGrade.subject.name,
|
||||
category: aGrade.subject.category.name!,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
aGrade.subject.name,
|
||||
style: appStyle.fonts.H_H2.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
aGrade.teacher,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: gradeWidgets,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Material(
|
||||
color: appStyle.colors.background,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 16.0, right: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 0),
|
||||
child: GestureDetector(
|
||||
child: FirkaIconWidget(
|
||||
FirkaIconType.majesticons,
|
||||
Majesticon.chevronLeftLine,
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
onTap: () {
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
Transform.translate(
|
||||
offset: const Offset(-4, 1),
|
||||
child: Text(
|
||||
widget.data.l10n.subjects,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
230,
|
||||
child: ListView(
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Card(
|
||||
shadowColor: const Color.fromRGBO(0, 0, 0, 0),
|
||||
color: appStyle.colors.a15p,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsetsGeometry.all(6),
|
||||
child: ClassIconWidget(
|
||||
uid: subjectId,
|
||||
className: subjectName,
|
||||
category: subjectCategory,
|
||||
color: appStyle.colors.accent,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8),
|
||||
Text(
|
||||
subjectName,
|
||||
style: appStyle.fonts.H_H2.apply(
|
||||
color: appStyle.colors.textPrimary,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
Text(
|
||||
widget.data.l10n.unknown_teacher,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height:
|
||||
MediaQuery.of(context).size.height -
|
||||
MediaQuery.of(context).padding.top -
|
||||
320,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SvgPicture.asset(
|
||||
"assets/images/logos/dave.svg",
|
||||
width: 48,
|
||||
height: 48,
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
Text(
|
||||
widget.data.l10n.no_grades,
|
||||
style: appStyle.fonts.B_16R.apply(
|
||||
color: appStyle.colors.textSecondary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,13 +4,13 @@ import 'package:firka/api/client/kreta_stream.dart';
|
||||
import 'package:firka/api/model/grade.dart';
|
||||
import 'package:firka/core/extensions.dart';
|
||||
import 'package:firka/ui/components/common_bottom_sheets.dart';
|
||||
import 'package:firka/ui/phone/screens/message/message_screen.dart';
|
||||
import 'package:firka/ui/phone/widgets/home_main_starting_soon.dart';
|
||||
import 'package:firka/ui/phone/widgets/homework.dart';
|
||||
import 'package:firka/ui/phone/widgets/info_board_item.dart';
|
||||
import 'package:firka/ui/phone/widgets/lesson_small.dart';
|
||||
import 'package:firka/ui/shared/delayed_spinner.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
|
||||
import 'package:firka/api/model/homework.dart';
|
||||
@@ -326,11 +326,7 @@ class _HomeMainScreen extends FirkaState<HomeMainScreen> {
|
||||
GestureDetector(
|
||||
child: InfoBoardItemWidget(item),
|
||||
onTap: () {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MessageScreen(widget.data, item),
|
||||
),
|
||||
);
|
||||
context.push('/message', extra: item);
|
||||
},
|
||||
),
|
||||
item.date,
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:firka/core/state/firka_state.dart';
|
||||
import 'package:firka/core/state/update_notifier.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
|
||||
class PageWithSubPages extends StatefulWidget {
|
||||
final int pageIndex;
|
||||
final List<Widget Function(void Function(int))> subPages;
|
||||
final ValueNotifier<bool> subPageActive;
|
||||
final UpdateNotifier back;
|
||||
|
||||
const PageWithSubPages(
|
||||
this.subPages,
|
||||
this.subPageActive,
|
||||
this.back, {
|
||||
super.key,
|
||||
required this.pageIndex,
|
||||
});
|
||||
|
||||
@override
|
||||
PageWithSubPagesState createState() => PageWithSubPagesState();
|
||||
}
|
||||
|
||||
class PageWithSubPagesState extends FirkaState<PageWithSubPages> {
|
||||
int _currentSubPage = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
widget.back.addListener(_backListener);
|
||||
}
|
||||
|
||||
void _backListener() {
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
subPageActive.value = false;
|
||||
_currentSubPage = 0;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(PageWithSubPages oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
|
||||
widget.back.removeListener(_backListener);
|
||||
widget.back.addListener(_backListener);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
|
||||
widget.back.removeListener(_backListener);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: appStyle.colors.background,
|
||||
body: widget.subPages[_currentSubPage]((page) {
|
||||
subPageActive.value = _currentSubPage == 0;
|
||||
setState(() {
|
||||
_currentSubPage = page;
|
||||
});
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import 'package:firka/ui/phone/screens/settings/settings_screen.dart';
|
||||
import 'package:firka/ui/phone/widgets/bubble_test.dart';
|
||||
import 'package:firka/ui/shared/delayed_spinner.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
import 'package:transparent_pointer/transparent_pointer.dart';
|
||||
@@ -29,13 +30,11 @@ class HomeTimetableScreen extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
final UpdateNotifier updateNotifier;
|
||||
final UpdateNotifier finishNotifier;
|
||||
final void Function(int) pageController;
|
||||
|
||||
const HomeTimetableScreen(
|
||||
this.data,
|
||||
this.updateNotifier,
|
||||
this.finishNotifier,
|
||||
this.pageController, {
|
||||
this.finishNotifier, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -555,7 +554,7 @@ class _HomeTimetableScreen extends FirkaState<HomeTimetableScreen>
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
widget.pageController(1);
|
||||
context.push('/timetable/monthly');
|
||||
},
|
||||
),
|
||||
/* TODO: 1.1.0
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:firka/core/settings.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/shared/delayed_spinner.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
import 'package:transparent_pointer/transparent_pointer.dart';
|
||||
@@ -22,13 +23,11 @@ class HomeTimetableMonthlyScreen extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
final UpdateNotifier updateNotifier;
|
||||
final UpdateNotifier finishNotifier;
|
||||
final void Function(int) pageController;
|
||||
|
||||
const HomeTimetableMonthlyScreen(
|
||||
this.data,
|
||||
this.updateNotifier,
|
||||
this.finishNotifier,
|
||||
this.pageController, {
|
||||
this.finishNotifier, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -392,7 +391,7 @@ class _HomeTimetableMonthlyScreen
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
widget.pageController(0);
|
||||
context.pop();
|
||||
},
|
||||
),
|
||||
// Nincs elkészítve jelenleg: Dolgozat stb hozzáadása(?)
|
||||
|
||||
@@ -7,12 +7,11 @@ import 'package:firka/core/extensions.dart';
|
||||
import 'package:firka/core/icon_helper.dart';
|
||||
import 'package:firka/core/profile_picture.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/ui/phone/screens/login/login_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
import 'package:firka/core/debug_helper.dart';
|
||||
import 'package:firka/core/firka_bundle.dart';
|
||||
import 'package:firka/core/state/firka_state.dart';
|
||||
import 'package:firka/ui/shared/firka_icon.dart';
|
||||
|
||||
@@ -221,15 +220,7 @@ class _DebugScreen extends FirkaState<DebugScreen> {
|
||||
widget.data.tokens = List.empty(growable: true);
|
||||
|
||||
if (!context.mounted) return;
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: LoginScreen(widget.data),
|
||||
),
|
||||
),
|
||||
);
|
||||
context.go('/login');
|
||||
},
|
||||
child: const Text('wipe users'),
|
||||
),
|
||||
|
||||
@@ -5,8 +5,8 @@ import 'package:firka/data/models/app_settings_model.dart';
|
||||
import 'package:firka/core/settings.dart';
|
||||
import 'package:firka/ui/components/firka_button.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/phone/screens/home/home_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'package:firka/core/state/firka_state.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
@@ -123,12 +123,7 @@ class _BetaScreenState extends FirkaState<BetaScreen> {
|
||||
.group("settings")["beta_warning"]!
|
||||
.postUpdate();
|
||||
if (!context.mounted) return;
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => HomeScreen(widget.data, false),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
context.go('/home');
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,10 @@ import 'package:firka/ui/components/firka_button.dart';
|
||||
import 'package:firka/ui/components/firka_card.dart';
|
||||
import 'package:firka/app/app_state.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import 'package:firka/ui/phone/screens/login/login_screen.dart';
|
||||
import 'package:firka/ui/shared/firka_icon.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:isar_community/isar.dart';
|
||||
import 'package:majesticons_flutter/majesticons_flutter.dart';
|
||||
@@ -185,15 +185,7 @@ class _SettingsScreenState extends FirkaState<SettingsScreen> {
|
||||
launchUrlString("https://firka.app/privacy");
|
||||
return;
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: SettingsScreen(widget.data, item.children),
|
||||
),
|
||||
),
|
||||
);
|
||||
context.push('/settings', extra: item.children);
|
||||
}
|
||||
},
|
||||
child: item.redirectTo != null
|
||||
@@ -995,12 +987,7 @@ class _SettingsScreenState extends FirkaState<SettingsScreen> {
|
||||
KretaClient.clearReauthFlag();
|
||||
}
|
||||
if (!mounted) return;
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (context) => LoginScreen(widget.data),
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
context.go('/login');
|
||||
} else {
|
||||
if (Platform.isIOS) {
|
||||
final nextToken = accounts.first;
|
||||
|
||||
@@ -13,12 +13,10 @@ import 'package:firka/services/watch_sync_helper.dart';
|
||||
import 'package:firka/api/consts.dart';
|
||||
import 'package:firka/api/token_grant.dart';
|
||||
import 'package:firka/data/models/token_model.dart';
|
||||
import 'package:firka/core/firka_bundle.dart';
|
||||
import 'package:firka/app/initialization_screen.dart';
|
||||
import 'package:firka/core/state/firka_state.dart';
|
||||
import 'package:firka/core/settings.dart';
|
||||
import 'package:firka/ui/theme/style.dart';
|
||||
import '../pages/error/error_page.dart';
|
||||
|
||||
class LoginWebviewWidget extends StatefulWidget {
|
||||
final AppInitialization data;
|
||||
@@ -166,15 +164,7 @@ class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget>
|
||||
} else {
|
||||
logger.shout("oauthredirect failed:", ex.toString());
|
||||
}
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => DefaultAssetBundle(
|
||||
bundle: FirkaBundle(),
|
||||
child: ErrorPage(exception: ex.toString()),
|
||||
),
|
||||
),
|
||||
);
|
||||
appRouter?.go('/error', extra: ex.toString());
|
||||
}
|
||||
|
||||
return NavigationDecision.prevent;
|
||||
|
||||
@@ -51,6 +51,7 @@ dependencies:
|
||||
flutter_html: ^3.0.0
|
||||
fl_chart: ^1.1.1
|
||||
flutter_native_splash: ^2.4.7
|
||||
go_router: ^17.1.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
Reference in New Issue
Block a user