Firelands128 / photo_gallery

A Flutter plugin that retrieves images and videos from mobile native gallery.
BSD 3-Clause "New" or "Revised" License
68 stars 63 forks source link

[Bug] listAlbums method returns deleted video files #4

Closed msarkrish closed 3 years ago

msarkrish commented 4 years ago

I'm displaying all the videos from storage in My app using photo_gallery plugin. When user deleting the video file, I'm again calling the PhotoGallery.listAlbums(mediumType: MediumType.video) method again and displaying the available videos. but listAlbums returns deleted videos also.

My code:

 List<Album> videoAlbumList =
    await PhotoGallery.listAlbums(mediumType: MediumType.video);
 MediaPage videoList = await videoAlbumList[0].listMedia();
 List<Medium> videoMediumList = videoList.items;  

Please fix this bug bro, My app is depend on video functionality.

Firelands128 commented 4 years ago

Please provide your flutter doctor -v and more details to reproduce this bug.

msarkrish commented 4 years ago

@Firelands128 I added my code and Flutter doctor result.

I added my code, After deleting any video, I'm refreshing the screen by calling listAlbum method again. But it returns deleted video also.

` import 'dart:io'; import 'package:collection/collection.dart'; import 'package:project/widgets/grid_item.dart'; import 'package:flutter/foundation.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:open_file/open_file.dart'; import 'package:project/constants/constant.dart'; import 'package:flutter/material.dart'; import 'package:flutter_neumorphic/flutter_neumorphic.dart'; import 'package:photo_gallery/photo_gallery.dart'; import 'package:shimmer/shimmer.dart'; import 'package:sortedmap/sortedmap.dart';

class VideoScreen extends StatefulWidget { final String storagePath;

VideoScreen({@required this.storagePath});

@override _VideoScreenState createState() => _VideoScreenState(); }

class _VideoScreenState extends State { Future videoFiles; Future kk; List selectedVideoList = []; bool showBottomBar = false, showCircleSelected = false, showAllCircleSelected = false; Map groupedVideoFiles = {}; TextEditingController renameController = TextEditingController();

@override void initState() { super.initState(); videoFiles = getVideoFiles(widget.storagePath);

}

@override Widget build(BuildContext context) { return Scaffold( backgroundColor: Constant.kPrimaryColor, bottomNavigationBar: showBottomBar == true ? Container( padding: EdgeInsets.symmetric(horizontal: 4.0), color: Constant.kSecondaryColor, height: 50, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ selectedVideoList.length > 0 ? Text( '${selectedVideoList.length} Selected', style: TextStyle(color: Colors.white), ) : Container(), PopupMenuButton( child: Icon( Icons.more_vert, color: Colors.white, ), onSelected: popUpAction, itemBuilder: (context) { return [

                        PopupMenuItem(
                          child: Text('Delete'),
                          value: 'Delete',
                          enabled: selectedVideoList.length == 1,
                        ),

                      ];
                    })
              ],
            ),
          )
        : null,
    body: SafeArea(
        child: Padding(
            padding: const EdgeInsets.only(
              top: 20.0,
              bottom: 8.0,
              left: 8.0,
              right: 8.0,
            ),
            child: Column(children: <Widget>[
              Row(
                children: <Widget>[
                  NeumorphicButton(
                    onPressed: () {},
                    child: Icon(
                      Icons.sort,
                      color: Colors.orange,
                      size: 35,
                    ),
                    padding: EdgeInsets.all(0.0),
                    style: NeumorphicStyle(
                      color: Constant.kPrimaryColor,
                      shadowLightColor: Colors.white54,
                      shadowDarkColor: Colors.black,
                    ),
                  ),
                  SizedBox(
                    width: 8.0,
                  ),
                  Expanded(
                    child: NeumorphicButton(
                      onPressed: () {},
                      child: Text(
                        'Video',
                        style: TextStyle(color: Constant.kWhiteColor),
                      ),
                      style: NeumorphicStyle(
                        color: Constant.kPrimaryColor,
                        shadowLightColor: Colors.white54,
                        shadowDarkColor: Colors.black,
                      ),
                    ),
                  ),
                ],
              ),
              SizedBox(
                height: 16.0,
              ),
              Expanded(
                child: FutureBuilder(
                    future: videoFiles,
                    builder: (context, snapshot) {
                      Widget returnWidget;
                      if (snapshot.connectionState ==
                          ConnectionState.done) {
                        groupedVideoFiles = snapshot.data;

                        int groupedVideoFilesLength =
                            groupedVideoFiles.length;
                        returnWidget = groupedVideoFilesLength > 0
                            ? ListView.builder(
                                itemCount: groupedVideoFilesLength,
                                itemBuilder: (context, index1) {
                                  List<Medium> singleGroupList =
                                      groupedVideoFiles.values.toList()[
                                          groupedVideoFilesLength -
                                              index1 -
                                              1];
                                  return Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: <Widget>[
                                      Row(
                                        mainAxisAlignment:
                                            MainAxisAlignment.spaceBetween,
                                        children: [
                                          Text(
                                            groupedVideoFiles.keys.toList()[
                                                groupedVideoFilesLength -
                                                    index1 -
                                                    1],
                                            style: TextStyle(
                                                color: Colors.white),
                                          ),
                                          Visibility(
                                            visible: showBottomBar,
                                            maintainSize: true,
                                            maintainAnimation: true,
                                            maintainState: true,
                                            child: IconButton(
                                              icon: Icon(Icons.check_box,
                                                  color: selectedVideoList
                                                          .toSet()
                                                          .containsAll(
                                                              singleGroupList
                                                                  .toSet())
                                                      ? Colors.blue
                                                      : Colors.white),
                                              onPressed: () {
                                                if (selectedVideoList
                                                        .toSet()
                                                        .containsAll(
                                                            singleGroupList
                                                                .toSet()) ==
                                                    true) {
                                                  setState(() {
                                                    selectedVideoList.removeWhere(
                                                        (selectedImage) =>
                                                            singleGroupList
                                                                .contains(
                                                                    selectedImage));
                                                  });
                                                } else {
                                                  setState(() {
                                                    selectedVideoList.removeWhere(
                                                        (selectedImage) =>
                                                            singleGroupList
                                                                .contains(
                                                                    selectedImage));
                                                    selectedVideoList.addAll(
                                                        singleGroupList);
                                                  });
                                                }
                                              },
                                            ),
                                          )
                                        ],
                                      ),
                                      GridView.builder(
                                        gridDelegate:
                                            SliverGridDelegateWithFixedCrossAxisCount(
                                                crossAxisCount: 3),
                                        itemCount: groupedVideoFiles.values
                                            .toList()[
                                                groupedVideoFilesLength -
                                                    index1 -
                                                    1]
                                            .length,
                                        physics:
                                            NeverScrollableScrollPhysics(),
                                        cacheExtent: MediaQuery.of(context)
                                                .size
                                                .height *
                                            3,
                                        shrinkWrap: true,
                                        itemBuilder: (context, index2) {
                                          return Padding(
                                            padding:
                                                const EdgeInsets.all(8.0),
                                            child: GestureDetector(
                                              onLongPress: () {
                                                setState(() {
                                                  showBottomBar = true;
                                                  // showBottomBar =
                                                  //     !showBottomBar;
                                                  selectedVideoList.add(
                                                      singleGroupList[
                                                          index2]);
                                                });
                                              },
                                              onTap: () async {
                                                print("Krishna");
                                                if (showBottomBar ==
                                                    false) {
                                                  print('inside if');
                                                  File file =
                                                      await singleGroupList[
                                                              index2]
                                                          .getFile();
                                                  print(file.path);
                                                  OpenFile.open(file.path);
                                                  // OpenFile.open(
                                                  //     singleGroupList[
                                                  //             index2]
                                                  //         .path);
                                                } else {
                                                  if (selectedVideoList
                                                      .contains(
                                                          singleGroupList[
                                                              index2])) {
                                                    setState(() {
                                                      selectedVideoList
                                                          .remove(
                                                              singleGroupList[
                                                                  index2]);
                                                    });
                                                  } else {
                                                    setState(() {
                                                      selectedVideoList.add(
                                                          singleGroupList[
                                                              index2]);
                                                    });
                                                  }
                                                }
                                              },
                                              child: GridItem(
                                                showSelectionCircle:
                                                    selectedVideoList
                                                                .length >
                                                            0
                                                        ? true
                                                        : false,
                                                showSelected:
                                                    selectedVideoList.contains(
                                                                singleGroupList[
                                                                    index2]) ==
                                                            true
                                                        ? true
                                                        : false,
                                                child: SizedBox(
                                                  width: 50,
                                                  child: VideoThumb(
                                                      medium:
                                                          singleGroupList[
                                                              index2]),

                                                ),
                                              ),
                                            ),
                                          );
                                        },
                                      ),
                                    ],
                                  );
                                })
                            : Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: [
                                  Icon(
                                    Icons.error_outline,
                                    color: Constant.kWhiteColor,
                                    size:
                                        MediaQuery.of(context).size.width /
                                            2,
                                  ),
                                  SizedBox(
                                    height: 8.0,
                                  ),
                                  Text(
                                    'No Video Files Found!',
                                    style: TextStyle(
                                        color: Colors.white, fontSize: 18),
                                  ),
                                ],
                              );
                      } else {
                        returnWidget = ListView.builder(
                          itemCount: 10,
                          itemBuilder: (context, index) {
                            return Shimmer.fromColors(
                              child: Padding(
                                padding: const EdgeInsets.only(
                                    top: 8.0, bottom: 8.0),
                                child: Row(
                                  crossAxisAlignment:
                                      CrossAxisAlignment.end,
                                  children: <Widget>[
                                    Container(
                                      height: 70,
                                      width: 70,
                                      decoration: BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(10),
                                        color: Colors.black,
                                      ),
                                    ),
                                    SizedBox(
                                      width: 15,
                                    ),
                                    Container(
                                      height: 70,
                                      width: 70,
                                      decoration: BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(10),
                                        color: Colors.black,
                                      ),
                                    ),
                                    SizedBox(
                                      width: 15,
                                    ),
                                    Container(
                                      height: 70,
                                      width: 70,
                                      decoration: BoxDecoration(
                                        borderRadius:
                                            BorderRadius.circular(10),
                                        color: Colors.black,
                                      ),
                                    ),
                                  ],
                                ),
                              ),
                              baseColor: Colors.grey[400],
                              highlightColor: Colors.white,
                            );
                          },
                        );
                      }
                      return returnWidget;
                    }),
              )
            ]))));

}

Future getVideoFiles(String storagePath) async { List videoAlbumList = await PhotoGallery.listAlbums(mediumType: MediumType.video); MediaPage videoList = await videoAlbumList[0].listMedia(); List videoMediumList = videoList.items;

var groupedVideoFilesMap;
groupedVideoFilesMap = groupBy(videoMediumList, (obj) {
  return obj.modifiedDate.toString().substring(0, 10);
});
var groupedSortedVideoFilesMap = SortedMap(Ordering.byKey());
groupedSortedVideoFilesMap.addAll(groupedVideoFilesMap);

return groupedSortedVideoFilesMap;

}

void popUpAction(String selectedPopUp) async { if (selectedPopUp == 'Delete') { File file = await selectedVideoList[0].getFile(); file.deleteSync(recursive: true); setState(() { selectedVideoList.removeAt(0); //videoFiles = compute(getVideoFiles, widget.storagePath); videoFiles = getVideoFiles(widget.storagePath); }); Fluttertoast.showToast(msg: 'File Deleted Successfully'); } } }

class VideoThumb extends StatefulWidget { final Medium medium; VideoThumb({@required this.medium});

@override _VideoThumbState createState() => _VideoThumbState(); }

class _VideoThumbState extends State { List thumbnail = []; @override void initState() { // TODO: implement initState super.initState(); getThumbnail(); }

@override Widget build(BuildContext context) { return thumbnail.length != 0 ? Image.memory( thumbnail, cacheHeight: (MediaQuery.of(context).size.width / 2).toInt(), cacheWidth: (MediaQuery.of(context).size.width / 2).toInt(), ) : CircularProgressIndicator(); }

void getThumbnail() async { List data = await PhotoGallery.getThumbnail(mediumId: widget.medium.id); if (this.mounted) { setState(() { thumbnail = data; }); } } } `

GridItem

` import 'package:flutter/material.dart';

class GridItem extends StatefulWidget { final Widget child; final bool showSelected, showSelectionCircle;

GridItem( {@required this.child, @required this.showSelected, @required this.showSelectionCircle}) : assert(child != null && showSelected != null && showSelectionCircle != null); @override _GridItemState createState() => _GridItemState(); }

class _GridItemState extends State { @override Widget build(BuildContext context) { return Stack( children: [ Align(alignment: Alignment.center, child: widget.child), widget.showSelectionCircle == true ? Positioned( right: 4.0, bottom: 4.0, child: Icon( Icons.check_circle, color: widget.showSelected == true ? Colors.blue : Colors.white, ), ) : Container() ], ); } }

`

flutter doctor Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 1.20.2, on Microsoft Windows [Version 6.3.9600], locale en-US) [√] Android toolchain - develop for Android devices (Android SDK version 30.0.1) [√] Android Studio (version 3.5) [√] VS Code (version 1.49.1) [√] Connected device (1 available)

• No issues found!

Firelands128 commented 3 years ago

Sorry, I cannot reproduce this problem.

rohan-adstringo commented 1 year ago

Because of iOS security policy it doesn't give direct access to files. It generates cache files and gives access to cache files only so if you delete file then it is deleting from cache not original file.