fading_bottom_bar.dart 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import 'dart:io';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:photos/core/configuration.dart';
  5. import 'package:photos/models/file.dart';
  6. import 'package:photos/models/file_type.dart';
  7. import 'package:photos/models/magic_metadata.dart';
  8. import 'package:photos/models/trash_file.dart';
  9. import 'package:photos/ui/file_info_dialog.dart';
  10. import 'package:photos/utils/archive_util.dart';
  11. import 'package:photos/utils/delete_file_util.dart';
  12. import 'package:photos/utils/share_util.dart';
  13. import 'package:photos/utils/toast_util.dart';
  14. import 'common/dialogs.dart';
  15. class FadingBottomBar extends StatefulWidget {
  16. final File file;
  17. final Function(File) onEditRequested;
  18. final bool showOnlyInfoButton;
  19. FadingBottomBar(
  20. this.file,
  21. this.onEditRequested,
  22. this.showOnlyInfoButton, {
  23. Key key,
  24. }) : super(key: key);
  25. @override
  26. FadingBottomBarState createState() => FadingBottomBarState();
  27. }
  28. class FadingBottomBarState extends State<FadingBottomBar> {
  29. bool _shouldHide = false;
  30. @override
  31. Widget build(BuildContext context) {
  32. return _getBottomBar();
  33. }
  34. void hide() {
  35. setState(() {
  36. _shouldHide = true;
  37. });
  38. }
  39. void show() {
  40. setState(() {
  41. _shouldHide = false;
  42. });
  43. }
  44. void safeRefresh() {
  45. if (mounted) {
  46. setState(() {});
  47. }
  48. }
  49. Widget _getBottomBar() {
  50. List<Widget> children = [];
  51. children.add(
  52. Tooltip(
  53. message: "info",
  54. child: Padding(
  55. padding: const EdgeInsets.only(top: 12, bottom: 12),
  56. child: IconButton(
  57. icon: Icon(
  58. Platform.isAndroid ? Icons.info_outline : CupertinoIcons.info),
  59. onPressed: () {
  60. _displayInfo(widget.file);
  61. },
  62. ),
  63. ),
  64. ),
  65. );
  66. if (widget.file is TrashFile) {
  67. _addTrashOptions(children);
  68. }
  69. if (!widget.showOnlyInfoButton && widget.file is! TrashFile) {
  70. if (widget.file.fileType == FileType.image ||
  71. widget.file.fileType == FileType.livePhoto) {
  72. children.add(
  73. Tooltip(
  74. message: "edit",
  75. child: Padding(
  76. padding: const EdgeInsets.only(top: 12, bottom: 12),
  77. child: IconButton(
  78. icon: Icon(Icons.tune_outlined),
  79. onPressed: () {
  80. widget.onEditRequested(widget.file);
  81. },
  82. ),
  83. ),
  84. ),
  85. );
  86. }
  87. if (widget.file.uploadedFileID != null &&
  88. widget.file.ownerID == Configuration.instance.getUserID()) {
  89. bool isArchived =
  90. widget.file.magicMetadata.visibility == kVisibilityArchive;
  91. children.add(
  92. Tooltip(
  93. message: isArchived ? "unarchive" : "archive",
  94. child: Padding(
  95. padding: const EdgeInsets.only(top: 12, bottom: 12),
  96. child: IconButton(
  97. icon: Icon(
  98. Platform.isAndroid
  99. ? (isArchived
  100. ? Icons.unarchive_outlined
  101. : Icons.archive_outlined)
  102. : (isArchived
  103. ? CupertinoIcons.archivebox_fill
  104. : CupertinoIcons.archivebox)),
  105. onPressed: () async {
  106. await changeVisibility(
  107. context,
  108. [widget.file],
  109. isArchived ? kVisibilityVisible : kVisibilityArchive,
  110. );
  111. safeRefresh();
  112. },
  113. ),
  114. ),
  115. ),
  116. );
  117. }
  118. children.add(
  119. Tooltip(
  120. message: "share",
  121. child: Padding(
  122. padding: const EdgeInsets.only(top: 12, bottom: 12),
  123. child: IconButton(
  124. icon: Icon(Platform.isAndroid
  125. ? Icons.share_outlined
  126. : CupertinoIcons.share),
  127. onPressed: () {
  128. share(context, [widget.file]);
  129. },
  130. ),
  131. ),
  132. ),
  133. );
  134. }
  135. return AnimatedOpacity(
  136. child: Align(
  137. alignment: Alignment.bottomCenter,
  138. child: Container(
  139. decoration: BoxDecoration(
  140. gradient: LinearGradient(
  141. begin: Alignment.topCenter,
  142. end: Alignment.bottomCenter,
  143. colors: [
  144. Colors.transparent,
  145. Colors.black.withOpacity(0.5),
  146. Colors.black.withOpacity(0.64),
  147. ],
  148. stops: const [0, 0.8, 1],
  149. ),
  150. ),
  151. child: Row(
  152. mainAxisAlignment: MainAxisAlignment.spaceAround,
  153. children: children,
  154. ),
  155. ),
  156. ),
  157. opacity: _shouldHide ? 0 : 1,
  158. duration: Duration(milliseconds: 150),
  159. );
  160. }
  161. void _addTrashOptions(List<Widget> children) {
  162. children.add(
  163. Tooltip(
  164. message: "restore",
  165. child: Padding(
  166. padding: const EdgeInsets.only(top: 12, bottom: 12),
  167. child: IconButton(
  168. icon: Icon(Icons.restore_outlined),
  169. onPressed: () {
  170. showToast("coming soon");
  171. Navigator.pop(context);
  172. },
  173. ),
  174. ),
  175. ),
  176. );
  177. children.add(
  178. Tooltip(
  179. message: "delete",
  180. child: Padding(
  181. padding: const EdgeInsets.only(top: 12, bottom: 12),
  182. child: IconButton(
  183. icon: Icon(Icons.delete_forever_outlined),
  184. onPressed: () async {
  185. final trashedFile = <TrashFile>[];
  186. trashedFile.add(widget.file);
  187. if (await deleteFromTrash(context, trashedFile) == true) {
  188. Navigator.pop(context);
  189. }
  190. },
  191. ),
  192. ),
  193. ),
  194. );
  195. }
  196. Future<void> _displayInfo(File file) async {
  197. return showDialog<void>(
  198. context: context,
  199. builder: (BuildContext context) {
  200. return FileInfoWidget(file);
  201. },
  202. );
  203. }
  204. }