diff --git a/auth/lib/ui/code_timer_progress.dart b/auth/lib/ui/code_timer_progress.dart index e594e15fb1..ea62860268 100644 --- a/auth/lib/ui/code_timer_progress.dart +++ b/auth/lib/ui/code_timer_progress.dart @@ -1,58 +1,58 @@ -import 'package:ente_auth/services/preference_service.dart'; +import 'dart:async'; +import 'dart:io'; + import 'package:ente_auth/theme/ente_theme.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; - -class CodeTimerProgressCache { - static final Map _cache = {}; - - static CodeTimerProgress getCachedWidget(int period) { - if (!_cache.containsKey(period)) { - _cache[period] = CodeTimerProgress(period: period); - } - return _cache[period]!; - } -} class CodeTimerProgress extends StatefulWidget { final int period; - + final bool isCompactMode; const CodeTimerProgress({ super.key, required this.period, + this.isCompactMode = false, }); @override State createState() => _CodeTimerProgressState(); } -class _CodeTimerProgressState extends State - with SingleTickerProviderStateMixin { - late final Ticker _ticker; +class _CodeTimerProgressState extends State { + late final Timer _timer; late final ValueNotifier _progress; - late final int _microSecondsInPeriod; - late bool _isCompactMode=false; + late final int _periodInMicros; + + // Cache the start time to avoid repeated system calls + late final int _startMicros; + + // Reduce update frequency + final int _updateIntervalMs = + (Platform.isAndroid || Platform.isIOS) ? 16 : 500; // approximately 60 FPS @override void initState() { super.initState(); - _microSecondsInPeriod = widget.period * 1000000; + _periodInMicros = widget.period * 1000000; _progress = ValueNotifier(0.0); - _ticker = createTicker(_updateTimeRemaining); - _ticker.start(); - _isCompactMode = PreferenceService.instance.isCompactMode(); - _updateTimeRemaining(Duration.zero); + _startMicros = DateTime.now().microsecondsSinceEpoch; + + // Use a Timer instead of a Ticker + _timer = Timer.periodic(Duration(milliseconds: _updateIntervalMs), (timer) { + final now = DateTime.now().microsecondsSinceEpoch; + _updateTimeRemaining(now); + }); } - void _updateTimeRemaining(Duration elapsed) { - int timeRemaining = _microSecondsInPeriod - - (DateTime.now().microsecondsSinceEpoch % _microSecondsInPeriod); - _progress.value = timeRemaining / _microSecondsInPeriod; + void _updateTimeRemaining(int currentMicros) { + // More efficient time calculation using modulo + final elapsed = (currentMicros - _startMicros) % _periodInMicros; + final timeRemaining = _periodInMicros - elapsed; + _progress.value = timeRemaining / _periodInMicros; } @override void dispose() { - _ticker.dispose(); + _timer.cancel(); _progress.dispose(); super.dispose(); } @@ -60,18 +60,19 @@ class _CodeTimerProgressState extends State @override Widget build(BuildContext context) { return SizedBox( - height: _isCompactMode ?1:3, + height: widget.isCompactMode ? 1 : 3, child: ValueListenableBuilder( valueListenable: _progress, builder: (context, progress, _) { return CustomPaint( + key: Key(progress.toString()), // Add key here painter: _ProgressPainter( progress: progress, color: progress > 0.4 ? getEnteColorScheme(context).primary700 : Colors.orange, ), - size: Size.infinite, + size: const Size.fromHeight(double.infinity), ); }, ), @@ -83,7 +84,10 @@ class _ProgressPainter extends CustomPainter { final double progress; final Color color; - _ProgressPainter({required this.progress, required this.color}); + const _ProgressPainter({ + required this.progress, + required this.color, + }); @override void paint(Canvas canvas, Size size) { diff --git a/auth/lib/ui/code_widget.dart b/auth/lib/ui/code_widget.dart index c04feddfb0..509060f3cd 100644 --- a/auth/lib/ui/code_widget.dart +++ b/auth/lib/ui/code_widget.dart @@ -146,8 +146,10 @@ class _CodeWidgetState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (widget.code.type.isTOTPCompatible) - CodeTimerProgressCache.getCachedWidget( - widget.code.period, + CodeTimerProgress( + key: ValueKey('period_${widget.code.period}'), + period: widget.code.period, + isCompactMode: widget.isCompactMode, ), widget.isCompactMode ? const SizedBox(height: 4) diff --git a/auth/macos/Runner.xcodeproj/project.pbxproj b/auth/macos/Runner.xcodeproj/project.pbxproj index 492f710ada..a2ed68c3c5 100644 --- a/auth/macos/Runner.xcodeproj/project.pbxproj +++ b/auth/macos/Runner.xcodeproj/project.pbxproj @@ -429,6 +429,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; + ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.ente.auth.mac; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; diff --git a/auth/pubspec.lock b/auth/pubspec.lock index b6e72978b2..0568bf396d 100644 --- a/auth/pubspec.lock +++ b/auth/pubspec.lock @@ -42,10 +42,10 @@ packages: dependency: "direct main" description: name: app_links - sha256: ad1a6d598e7e39b46a34f746f9a8b011ee147e4c275d407fa457e7a62f84dd99 + sha256: "433df2e61b10519407475d7f69e470789d23d593f28224c38ba1068597be7950" url: "https://pub.dev" source: hosted - version: "6.3.2" + version: "6.3.3" app_links_linux: dependency: transitive description: @@ -528,10 +528,10 @@ packages: dependency: "direct main" description: name: flutter_inappwebview - sha256: "93cfcca02bdda4b26cd700cf70d9ddba09d8348e3e8f2857638c23ed23a4fcb4" + sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.1.5" flutter_inappwebview_android: dependency: transitive description: @@ -584,10 +584,10 @@ packages: dependency: transitive description: name: flutter_inappwebview_windows - sha256: "95ebc65aecfa63b2084c822aec6ba0545f0a0afaa3899f2c752ec96c09108db5" + sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055" url: "https://pub.dev" source: hosted - version: "0.5.0+2" + version: "0.6.0" flutter_launcher_icons: dependency: "direct main" description: @@ -985,10 +985,10 @@ packages: dependency: "direct main" description: name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.0" macros: dependency: transitive description: @@ -1655,10 +1655,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "6.3.1" url_launcher_android: dependency: transitive description: @@ -1668,7 +1668,7 @@ packages: source: hosted version: "6.3.11" url_launcher_ios: - dependency: transitive + dependency: "direct main" description: name: url_launcher_ios sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e diff --git a/auth/pubspec.yaml b/auth/pubspec.yaml index 6d2a932c40..e691cd8d16 100644 --- a/auth/pubspec.yaml +++ b/auth/pubspec.yaml @@ -1,6 +1,6 @@ name: ente_auth description: ente two-factor authenticator -version: 4.2.0+420 +version: 4.2.1+421 publish_to: none environment: