free_space_page.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import 'package:flutter/material.dart';
  2. import 'package:intl/intl.dart';
  3. import 'package:logging/logging.dart';
  4. import 'package:photos/models/backup_status.dart';
  5. import 'package:photos/ui/common/gradient_button.dart';
  6. import 'package:photos/utils/data_util.dart';
  7. import 'package:photos/utils/delete_file_util.dart';
  8. class FreeSpacePage extends StatefulWidget {
  9. final BackupStatus status;
  10. final bool clearSpaceForFolder;
  11. const FreeSpacePage(
  12. this.status, {
  13. Key? key,
  14. this.clearSpaceForFolder = false,
  15. }) : super(key: key);
  16. @override
  17. State<FreeSpacePage> createState() => _FreeSpacePageState();
  18. }
  19. class _FreeSpacePageState extends State<FreeSpacePage> {
  20. @override
  21. Widget build(BuildContext context) {
  22. return Scaffold(
  23. appBar: AppBar(
  24. elevation: 0,
  25. title: const Text("Free up space"),
  26. ),
  27. body: _getBody(),
  28. );
  29. }
  30. Widget _getBody() {
  31. Logger("FreeSpacePage").info(
  32. "Number of uploaded files: " + widget.status.localIDs.length.toString(),
  33. );
  34. Logger("FreeSpacePage")
  35. .info("Space consumed: " + widget.status.size.toString());
  36. return SingleChildScrollView(
  37. child: _getWidget(widget.status),
  38. );
  39. }
  40. Widget _getWidget(BackupStatus status) {
  41. final count = status.localIDs.length;
  42. final formattedCount = NumberFormat().format(count);
  43. final String textMessage = widget.clearSpaceForFolder
  44. ? formattedCount.toString() +
  45. " file${count == 1 ? "" : "s"} in this album has been backed up "
  46. "safely"
  47. : formattedCount.toString() +
  48. " file${count == 1 ? "" : "s"} on this device have been backed up safely";
  49. final informationTextStyle = TextStyle(
  50. fontSize: 14,
  51. height: 1.3,
  52. color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8),
  53. fontWeight: FontWeight.w500,
  54. );
  55. final isLightMode =
  56. MediaQuery.of(context).platformBrightness == Brightness.light;
  57. return Column(
  58. mainAxisAlignment: MainAxisAlignment.center,
  59. crossAxisAlignment: CrossAxisAlignment.center,
  60. children: [
  61. const SizedBox(height: 24),
  62. Stack(
  63. alignment: Alignment.center,
  64. children: [
  65. isLightMode
  66. ? Image.asset(
  67. 'assets/loading_photos_background.png',
  68. color: Colors.white.withOpacity(0.4),
  69. colorBlendMode: BlendMode.modulate,
  70. )
  71. : Image.asset(
  72. 'assets/loading_photos_background_dark.png',
  73. color: Colors.white.withOpacity(0.25),
  74. ),
  75. Padding(
  76. padding: const EdgeInsets.only(top: 16),
  77. child: Image.asset(
  78. "assets/gallery_locked.png",
  79. height: 160,
  80. ),
  81. ),
  82. ],
  83. ),
  84. const SizedBox(height: 24),
  85. Padding(
  86. padding: const EdgeInsets.only(left: 36, right: 40),
  87. child: Row(
  88. children: [
  89. const Icon(
  90. Icons.cloud_done_outlined,
  91. color: Color.fromRGBO(45, 194, 98, 1.0),
  92. ),
  93. const Padding(padding: EdgeInsets.all(10)),
  94. Expanded(
  95. child: Text(
  96. textMessage,
  97. style: informationTextStyle,
  98. ),
  99. ),
  100. ],
  101. ),
  102. ),
  103. const Padding(padding: EdgeInsets.all(12)),
  104. Padding(
  105. padding: const EdgeInsets.only(left: 36, right: 40),
  106. child: Row(
  107. children: [
  108. const Icon(
  109. Icons.delete_outline,
  110. color: Color.fromRGBO(45, 194, 98, 1.0),
  111. ),
  112. const Padding(padding: EdgeInsets.all(10)),
  113. Expanded(
  114. child: Text(
  115. (count == 1 ? "It" : "They") +
  116. " can be deleted from the device to free up " +
  117. formatBytes(status.size),
  118. style: informationTextStyle,
  119. ),
  120. ),
  121. ],
  122. ),
  123. ),
  124. const Padding(padding: EdgeInsets.all(12)),
  125. Padding(
  126. padding: const EdgeInsets.only(left: 36, right: 40),
  127. child: Row(
  128. children: [
  129. const Icon(
  130. Icons.devices,
  131. color: Color.fromRGBO(45, 194, 98, 1.0),
  132. ),
  133. const Padding(padding: EdgeInsets.all(10)),
  134. Expanded(
  135. child: Text(
  136. "You can still access " +
  137. (count == 1 ? "it" : "them") +
  138. " on ente as long as you have an active subscription",
  139. style: informationTextStyle,
  140. ),
  141. ),
  142. ],
  143. ),
  144. ),
  145. const Padding(padding: EdgeInsets.all(24)),
  146. Container(
  147. width: double.infinity,
  148. constraints: const BoxConstraints(
  149. minHeight: 64,
  150. ),
  151. padding: const EdgeInsets.fromLTRB(60, 0, 60, 0),
  152. child: GradientButton(
  153. onTap: () async {
  154. await _freeStorage(status);
  155. },
  156. text: "Free up " + formatBytes(status.size),
  157. ),
  158. ),
  159. const Padding(padding: EdgeInsets.all(24)),
  160. ],
  161. );
  162. }
  163. Future<void> _freeStorage(BackupStatus status) async {
  164. final result = await deleteLocalFiles(context, status.localIDs);
  165. if (result) {
  166. Navigator.of(context).pop(true);
  167. }
  168. }
  169. }