From 9ef92a805a5af4377fab746f2b6188c8b0a27ef8 Mon Sep 17 00:00:00 2001 From: fiatcode Date: Thu, 30 Apr 2026 18:15:46 +0700 Subject: [PATCH] feat: add easter egg with triple-tap AppBar and animation --- lib/settings_screen.dart | 88 ++++++++++++++++++++++++++++++++++++---- pubspec.lock | 64 +++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 8 deletions(-) diff --git a/lib/settings_screen.dart b/lib/settings_screen.dart index 3a082bd..c2d1b50 100644 --- a/lib/settings_screen.dart +++ b/lib/settings_screen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:url_launcher/url_launcher.dart'; import 'bridge/location_bridge.dart'; import 'preferences.dart'; @@ -19,6 +20,38 @@ class _SettingsScreenState extends State { late int _accuracy; late bool _offlineBuffer; late bool _stopDetection; + bool _showEasterEgg = false; + int _tapCount = 0; + DateTime? _lastTapTime; + + void _handleAppBarTap() { + const tripleTapInterval = Duration(milliseconds: 500); + final now = DateTime.now(); + + if (_lastTapTime != null && + now.difference(_lastTapTime!) > tripleTapInterval) { + _tapCount = 0; + } + + _tapCount++; + _lastTapTime = now; + + if (_tapCount == 3) { + _tapCount = 0; + setState(() => _showEasterEgg = true); + } + } + + Future _triggerEasterEgg() async { + await Future.delayed(const Duration(milliseconds: 1500)); + final uri = Uri.parse('https://fiatcode.dev'); + if (await canLaunchUrl(uri)) { + await launchUrl(uri, mode: LaunchMode.externalApplication); + } + if (mounted) { + setState(() => _showEasterEgg = false); + } + } @override void initState() { @@ -116,14 +149,17 @@ class _SettingsScreenState extends State { ), onPressed: () => Navigator.pop(context), ), - title: const Text( - 'SETTINGS', - style: TextStyle( - fontFamily: 'monospace', - fontSize: 14, - fontWeight: FontWeight.w700, - letterSpacing: 2, - color: Color(0xFFe0e0e0), + title: GestureDetector( + onTap: _handleAppBarTap, + child: const Text( + 'SETTINGS', + style: TextStyle( + fontFamily: 'monospace', + fontSize: 14, + fontWeight: FontWeight.w700, + letterSpacing: 2, + color: Color(0xFFe0e0e0), + ), ), ), bottom: PreferredSize( @@ -168,6 +204,7 @@ class _SettingsScreenState extends State { const SizedBox(height: 32), _buildSaveButton(), const SizedBox(height: 20), + if (_showEasterEgg) _buildEasterEggOverlay(), ], ), ); @@ -400,4 +437,39 @@ class _SettingsScreenState extends State { ), ); } + + Widget _buildEasterEggOverlay() { + return AnimatedOpacity( + opacity: _showEasterEgg ? 1.0 : 0.0, + duration: const Duration(milliseconds: 300), + onEnd: _triggerEasterEgg, + child: AnimatedScale( + scale: _showEasterEgg ? 1.0 : 0.5, + duration: const Duration(milliseconds: 300), + curve: Curves.easeOutBack, + child: Container( + color: Colors.black.withValues(alpha: 0.85), + width: double.infinity, + height: double.infinity, + child: Center( + child: Text( + '🎉 FIAT CODE! 🎉', + style: TextStyle( + fontFamily: 'monospace', + fontSize: 32, + fontWeight: FontWeight.w700, + color: const Color(0xFF00e676), + shadows: [ + Shadow( + color: const Color(0xFF00e676).withValues(alpha: 0.5), + blurRadius: 20, + ), + ], + ), + ), + ), + ), + ), + ); + } } diff --git a/pubspec.lock b/pubspec.lock index e784132..2e14c69 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -485,6 +485,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" + url: "https://pub.dev" + source: hosted + version: "6.3.29" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f + url: "https://pub.dev" + source: hosted + version: "2.4.2" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" vector_math: dependency: transitive description: