added loading spinner, fade out, and matched the color theme to the login page

This commit is contained in:
2025-10-13 00:08:36 +02:00
committed by 4831c0
parent 1d8d341f2d
commit ae9ef1603a
2 changed files with 111 additions and 37 deletions

View File

@@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:firka/helpers/db/models/app_settings_model.dart';
@@ -16,6 +17,7 @@ import '../../../helpers/db/models/token_model.dart';
import '../../../helpers/firka_bundle.dart';
import '../../../helpers/firka_state.dart';
import '../../../helpers/settings.dart';
import '../../../ui/model/style.dart';
import '../pages/error/error_page.dart';
class LoginWebviewWidget extends StatefulWidget {
@@ -30,13 +32,25 @@ class LoginWebviewWidget extends StatefulWidget {
State<LoginWebviewWidget> createState() => _LoginWebviewWidgetState();
}
class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget> {
class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget>
with TickerProviderStateMixin {
late WebViewController _webViewController;
bool _isLoading = true;
AnimationController? _fadeAnimationController;
Animation<double>? _fadeAnimation;
@override
void initState() {
super.initState();
_fadeAnimationController = AnimationController(
duration: const Duration(milliseconds: 200),
vsync: this,
);
_fadeAnimation =
Tween<double>(begin: 1.0, end: 0.0).animate(_fadeAnimationController!);
var loginUrl = KretaEndpoints.kretaLoginUrl;
if (widget.username != null && widget.schoolId != null) {
@@ -50,6 +64,24 @@ class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget> {
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(Uri.parse(loginUrl))
..setNavigationDelegate(NavigationDelegate(
onPageFinished: (String url) {
Timer(const Duration(milliseconds: 500), () {
if (mounted) {
setState(() {
_isLoading = false;
});
_fadeAnimationController?.forward().then((_) {
_fadeAnimationController?.reset();
});
}
});
},
onPageStarted: (String url) {
setState(() {
_isLoading = true;
});
_fadeAnimationController?.reset();
},
onNavigationRequest: (NavigationRequest request) async {
var uri = Uri.parse(request.url);
@@ -137,48 +169,89 @@ class _LoginWebviewWidgetState extends FirkaState<LoginWebviewWidget> {
}));
}
@override
void dispose() {
_fadeAnimationController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: FractionallySizedBox(
heightFactor: 0.90,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Container(
decoration: const BoxDecoration(
color: Color(0xFFB9C8E5),
borderRadius: BorderRadius.all(Radius.circular(2)),
return Material(
color: appStyle.colors.card,
child: Padding(
padding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
child: FractionallySizedBox(
heightFactor: 0.90,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Container(
decoration: BoxDecoration(
color: appStyle.colors.secondary.withValues(alpha: 0.5),
borderRadius: BorderRadius.all(Radius.circular(2)),
),
width: 40,
height: 4,
),
width: 40,
height: 4,
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.8,
// Adjust height for content
margin: const EdgeInsets.symmetric(horizontal: 16),
// Add ClipRRect for circular edges
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Stack(
children: [
WebViewWidget(
controller: _webViewController,
),
if (_fadeAnimationController != null && _fadeAnimation != null)
AnimatedBuilder(
animation: _fadeAnimationController!,
builder: (context, child) => AnimatedOpacity(
opacity: _isLoading
? 1.0
: _fadeAnimationController!.isAnimating
? _fadeAnimation!.value
: 0.0,
duration: const Duration(milliseconds: 500),
child: Container(
color: appStyle.colors.background,
child: Center(
child: SizedBox(
width: 32,
height: 32,
child: CircularProgressIndicator(
strokeWidth: 3,
valueColor: AlwaysStoppedAnimation<Color>(
appStyle.colors.accent,
),
),
),
),
),
),
),
],
),
),
],
),
Container(
height: MediaQuery.of(context).size.height * 0.8,
// Adjust height for content
margin: const EdgeInsets.symmetric(horizontal: 16),
// Add ClipRRect for circular edges
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: WebViewWidget(
controller: _webViewController,
),
),
),
],
],
),
),
),
),

1
firka/vendor/fmb_dart vendored Submodule

Submodule firka/vendor/fmb_dart added at fb711c8c40