Optimize automatic updates

This commit is contained in:
2026-05-31 09:32:32 +08:00
parent 8dfc22691a
commit 61ad85f6fc
4 changed files with 175 additions and 98 deletions
@@ -5,6 +5,7 @@ import 'package:url_launcher/url_launcher.dart';
import 'package:package_info_plus/package_info_plus.dart';
import '../../../data/models/user_model.dart';
import '../../../data/models/user_setting_model.dart';
import '../../../services/update_service.dart';
import '../../../services/user_setting_service.dart';
import '../../providers/auth_provider.dart';
import '../../providers/user_setting_provider.dart';
@@ -154,11 +155,7 @@ class _SettingsPageState extends State<SettingsPage> {
title: const Text('应用名称'),
subtitle: const Text('公云存储'),
),
ListTile(
leading: const Icon(Icons.tag),
title: const Text('版本号'),
subtitle: Text(_appVersion.isEmpty ? '加载中...' : _appVersion),
),
_buildVersionTile(),
ListTile(
leading: const Icon(Icons.copyright),
title: const Text('License'),
@@ -404,6 +401,22 @@ class _SettingsPageState extends State<SettingsPage> {
);
}
Widget _buildVersionTile() {
return AnimatedBuilder(
animation: UpdateService.instance,
builder: (context, _) {
return ListTile(
leading: const Icon(Icons.tag),
title: const Text('版本号'),
subtitle: Text(_appVersion.isEmpty ? '加载中...' : _appVersion),
trailing: UpdateService.instance.hasUpdate
? const _BlinkingUpdateDot()
: null,
);
},
);
}
Widget _buildLogoutButton(BuildContext context, AuthProvider auth) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
@@ -628,6 +641,53 @@ class _SettingsPageState extends State<SettingsPage> {
}
}
class _BlinkingUpdateDot extends StatefulWidget {
const _BlinkingUpdateDot();
@override
State<_BlinkingUpdateDot> createState() => _BlinkingUpdateDotState();
}
class _BlinkingUpdateDotState extends State<_BlinkingUpdateDot>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _opacity;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 900),
)..repeat(reverse: true);
_opacity = Tween<double>(
begin: 0.3,
end: 1,
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _opacity,
child: Container(
width: 10,
height: 10,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
);
}
}
class _NetworkTestConsentText extends StatefulWidget {
final VoidCallback onOpenPrivacy;
final VoidCallback onOpenTerms;