sync_indicator.dart 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import 'dart:async';
  2. import 'package:flutter/material.dart';
  3. import 'package:photos/core/configuration.dart';
  4. import 'package:photos/core/event_bus.dart';
  5. import 'package:photos/events/sync_status_update_event.dart';
  6. import 'package:photos/services/sync_service.dart';
  7. class SyncIndicator extends StatefulWidget {
  8. const SyncIndicator({Key key}) : super(key: key);
  9. @override
  10. _SyncIndicatorState createState() => _SyncIndicatorState();
  11. }
  12. class _SyncIndicatorState extends State<SyncIndicator> {
  13. SyncStatusUpdate _event;
  14. double _containerHeight = 48;
  15. StreamSubscription<SyncStatusUpdate> _subscription;
  16. @override
  17. void initState() {
  18. _subscription = Bus.instance.on<SyncStatusUpdate>().listen((event) {
  19. setState(() {
  20. _event = event;
  21. });
  22. });
  23. _event = SyncService.instance.getLastSyncStatusEvent();
  24. super.initState();
  25. }
  26. @override
  27. void dispose() {
  28. _subscription.cancel();
  29. super.dispose();
  30. }
  31. @override
  32. Widget build(BuildContext context) {
  33. if (Configuration.instance.hasConfiguredAccount() && _event != null) {
  34. if (_event.status == SyncStatus.completed) {
  35. Future.delayed(Duration(milliseconds: 3000), () {
  36. if (mounted) {
  37. setState(() {
  38. _containerHeight = 0;
  39. });
  40. }
  41. });
  42. } else {
  43. _containerHeight = 48;
  44. }
  45. var icon;
  46. if (_event.status == SyncStatus.completed) {
  47. icon = Icon(
  48. Icons.cloud_done_outlined,
  49. color: Theme.of(context).accentColor,
  50. );
  51. } else if (_event.status == SyncStatus.error) {
  52. icon = Icon(
  53. Icons.error_outline,
  54. color: Theme.of(context).accentColor,
  55. );
  56. } else {
  57. icon = CircularProgressIndicator(strokeWidth: 2);
  58. }
  59. return AnimatedContainer(
  60. duration: Duration(milliseconds: 300),
  61. height: _containerHeight,
  62. width: double.infinity,
  63. padding: EdgeInsets.all(8),
  64. alignment: Alignment.center,
  65. child: SingleChildScrollView(
  66. physics: NeverScrollableScrollPhysics(),
  67. child: Column(
  68. mainAxisAlignment: MainAxisAlignment.center,
  69. crossAxisAlignment: CrossAxisAlignment.center,
  70. children: [
  71. Row(
  72. mainAxisAlignment: MainAxisAlignment.center,
  73. crossAxisAlignment: CrossAxisAlignment.center,
  74. children: [
  75. Container(
  76. width: 20,
  77. height: 20,
  78. child: icon,
  79. ),
  80. Padding(
  81. padding: const EdgeInsets.fromLTRB(12, 4, 0, 0),
  82. child: Text(_getRefreshingText()),
  83. ),
  84. ],
  85. ),
  86. Padding(padding: EdgeInsets.all(4)),
  87. Divider(),
  88. ],
  89. ),
  90. ),
  91. );
  92. }
  93. return Container();
  94. }
  95. String _getRefreshingText() {
  96. if (_event == null ||
  97. _event.status == SyncStatus.applying_local_diff ||
  98. _event.status == SyncStatus.applying_remote_diff) {
  99. return "syncing...";
  100. }
  101. if (_event.status == SyncStatus.preparing_for_upload) {
  102. return "encrypting backup...";
  103. }
  104. if (_event.status == SyncStatus.in_progress) {
  105. return _event.completed.toString() +
  106. "/" +
  107. _event.total.toString() +
  108. " memories preserved";
  109. }
  110. if (_event.status == SyncStatus.paused) {
  111. return _event.reason;
  112. }
  113. if (_event.status == SyncStatus.completed) {
  114. if (_event.wasStopped) {
  115. return "sync stopped";
  116. } else {
  117. return "all memories preserved";
  118. }
  119. }
  120. // _event.status == SyncStatus.error)
  121. return "upload failed";
  122. }
  123. }