жижа сука не притрагивайся к анимациям

This commit is contained in:
klockky
2026-06-03 16:34:03 +03:00
parent e207d236d3
commit 09fdb19854
4 changed files with 69 additions and 92 deletions
@@ -193,7 +193,16 @@ class _CodeConfirmationScreenState extends State<CodeConfirmationScreen>
if (!mounted) return;
showLoginSuccess(context, avatar: avatar);
Navigator.pushAndRemoveUntil(
context,
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 240),
pageBuilder: (_, __, ___) => LoginSuccessScreen(avatar: avatar),
transitionsBuilder: (_, animation, __, child) =>
FadeTransition(opacity: animation, child: child),
),
(route) => false,
);
} catch (e) {
if (!mounted) return;
_showError(e.toString());
@@ -51,7 +51,16 @@ class _Password2FAScreenState extends State<Password2FAScreen> {
if (!mounted) return;
showLoginSuccess(context, avatar: avatar);
Navigator.pushAndRemoveUntil(
context,
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 240),
pageBuilder: (_, __, ___) => LoginSuccessScreen(avatar: avatar),
transitionsBuilder: (_, animation, __, child) =>
FadeTransition(opacity: animation, child: child),
),
(route) => false,
);
} catch (e) {
if (!mounted) return;
@@ -8,6 +8,7 @@ import '../../../core/config/app_pranks.dart';
import '../../../core/config/app_stories.dart';
import '../../../core/config/app_media_cache.dart';
import '../../../core/protocol/opcode_map.dart';
import '../../../core/storage/app_database.dart';
import '../../../core/protocol/packet.dart';
import '../../../core/utils/logger.dart';
import '../../../core/utils/media_cache.dart';
@@ -736,12 +737,19 @@ class _DebugMenuScreenState extends State<DebugMenuScreen> {
borderRadius: BorderRadius.circular(20),
child: InkWell(
borderRadius: BorderRadius.circular(20),
onTap: () {
onTap: () async {
final profile = await AppDatabase.loadActiveProfile();
if (!context.mounted) return;
final avatar = await precacheLoginAvatar(
context,
profile?.baseUrl,
);
if (!context.mounted) return;
Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
const LoginSuccessScreen(preview: true),
LoginSuccessScreen(preview: true, avatar: avatar),
),
);
},
+39 -88
View File
@@ -20,29 +20,8 @@ Future<ImageProvider?> precacheLoginAvatar(
}
}
void showLoginSuccess(BuildContext context, {ImageProvider? avatar}) {
final navigator = Navigator.of(context);
navigator.pushAndRemoveUntil(
PageRouteBuilder(
transitionDuration: Duration.zero,
pageBuilder: (_, _, _) => const AdaptiveShell(),
),
(route) => false,
);
navigator.push(
PageRouteBuilder(
opaque: false,
barrierColor: Colors.transparent,
transitionDuration: Duration.zero,
reverseTransitionDuration: Duration.zero,
pageBuilder: (_, _, _) => LoginSuccessScreen(avatar: avatar),
),
);
}
class LoginSuccessScreen extends StatefulWidget {
final ImageProvider? avatar;
final bool preview;
const LoginSuccessScreen({super.key, this.avatar, this.preview = false});
@@ -52,7 +31,7 @@ class LoginSuccessScreen extends StatefulWidget {
}
class _LoginSuccessScreenState extends State<LoginSuccessScreen>
with TickerProviderStateMixin {
with SingleTickerProviderStateMixin {
static const Duration _duration = Duration(milliseconds: 1900);
static const List<String> _greetings = [
@@ -75,10 +54,6 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
late final Animation<double> _subtitleOffset;
late final Animation<double> _fadeOut;
late final AnimationController _exitController;
late final Animation<double> _bgFadeOut;
late final Animation<double> _greetingFadeOut;
bool _navigated = false;
@override
@@ -132,21 +107,7 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
curve: const Interval(0.88, 1.0, curve: Curves.easeInCubic),
);
_exitController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1200),
);
_bgFadeOut = CurvedAnimation(
parent: _exitController,
curve: const Interval(0.0, 0.3, curve: Curves.easeOut),
);
_greetingFadeOut = CurvedAnimation(
parent: _exitController,
curve: const Interval(0.55, 1.0, curve: Curves.easeInCubic),
);
_controller.addStatusListener(_onStatus);
_exitController.addStatusListener(_onExitStatus);
_controller.forward();
Haptics.success();
}
@@ -156,15 +117,25 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
_navigated = true;
if (widget.preview) {
Navigator.of(context).pop();
} else {
_exitController.forward();
return;
}
}
}
void _onExitStatus(AnimationStatus status) {
if (status == AnimationStatus.completed && mounted) {
Navigator.of(context).pop();
Navigator.of(context).pushAndRemoveUntil(
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 360),
reverseTransitionDuration: const Duration(milliseconds: 200),
pageBuilder: (_, __, ___) => const AdaptiveShell(),
transitionsBuilder: (_, animation, __, child) {
return FadeTransition(
opacity: CurvedAnimation(
parent: animation,
curve: Curves.easeOutCubic,
),
child: child,
);
},
),
(route) => false,
);
}
}
@@ -172,8 +143,6 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
void dispose() {
_controller.removeStatusListener(_onStatus);
_controller.dispose();
_exitController.removeStatusListener(_onExitStatus);
_exitController.dispose();
super.dispose();
}
@@ -181,24 +150,15 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Scaffold(
backgroundColor: Colors.transparent,
backgroundColor: cs.surface,
body: AnimatedBuilder(
animation: Listenable.merge([_controller, _exitController]),
animation: _controller,
builder: (context, _) {
final celebrationOpacity = 1.0 - _fadeOut.value;
final bgOpacity = 1.0 - _bgFadeOut.value;
final greetingOpacity = 1.0 - _greetingFadeOut.value;
return Stack(
children: [
Positioned.fill(
child: Opacity(
opacity: bgOpacity,
child: ColoredBox(color: cs.surface),
),
),
Positioned.fill(
child: Opacity(
opacity: celebrationOpacity * bgOpacity,
return Opacity(
opacity: 1.0 - _fadeOut.value,
child: Stack(
children: [
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
gradient: RadialGradient(
@@ -214,14 +174,11 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
),
),
),
),
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Opacity(
opacity: celebrationOpacity,
child: SizedBox(
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 220,
height: 220,
child: Stack(
@@ -234,21 +191,15 @@ class _LoginSuccessScreenState extends State<LoginSuccessScreen>
],
),
),
),
const SizedBox(height: 28),
Opacity(
opacity: celebrationOpacity,
child: _buildTitle(cs),
),
const SizedBox(height: 8),
Opacity(
opacity: greetingOpacity,
child: _buildSubtitle(cs),
),
],
const SizedBox(height: 28),
_buildTitle(cs),
const SizedBox(height: 8),
_buildSubtitle(cs),
],
),
),
),
],
],
),
);
},
),