drawRect / Instagram_Stories

Inspired by Instagram Stories functionality. This source is similar to Instagram Stories, which is having both image and video support.
MIT License
415 stars 76 forks source link

Delete a story snap #67

Closed Goldy-74 closed 4 years ago

Goldy-74 commented 5 years ago

Thanks for this awesome library.

Can you please add functionality for deleting a snap at runtime.

Not able to delete a snap in the current code.

Thanks in Advance.

ranmyfriend commented 5 years ago

Hey @Goldy-74

Thanks for your support :)

This snap delete functionality we cannot implement. Because we are leaving it for you. Based on where you are storing your snaps as well as the story. You can able to implement easily. Like, do a service call for deleting the snap with snap Id. and then once it gets successful, remove that deleted snap from the IGStories Model and reload the respective cell Item. That's it, dude. Talk to your Backend people. It will be easily done from your side.

Thanks, Ranjith

Goldy-74 commented 5 years ago

Hi, @ranmyfriend,

Thanks for the reply.

Actually, I'm stuck how to manage the respective indexing of the snaps and stories how to go to next snap and story after deleting snaps depend on snap count.

boominadhaprakash commented 5 years ago

Hi @Goldy-74

You are storing the snaps in IGSnap model right. When you delete it in remote server, delete the snap from IGStory model. IGStory model having array of IGSnaps. After deleting you might have to reload the collectionView.

If you still having any doubts, you can clearly explain your scenario step by step. So that we can help you.

Goldy-74 commented 5 years ago

Hi please look into the following code it is working though but not playing video

Edit: - Done working I have to just reload the collection in async. Might be helpful for someone.

Again thanks for the library. :)

            var story   = self.viewModel?.stories
            var stories = story?.stories

            let currentStory   =   stories?[self.handPickedStoryIndex]

            var currentStorySnaps    =   currentStory?.snaps

            let selectedSnap            =   currentStorySnaps?[currentStory?.lastPlayedSnapIndex ?? 0]

            if  currentStory?.snapsCount == 1 {
                currentStory?.snaps.removeAll()
            } else {
                currentStorySnaps?.removeAll(where: {$0.internalIdentifier == selectedSnap?.internalIdentifier})
                currentStory?.snaps =   currentStorySnaps ?? []
            }

            currentStory?.snapsCount = (currentStory?.snapsCount ?? 1) - 1

            self.handPickedStoryIndex   =   0
            self.nStoryIndex    =   0
            self.story_copy = nil
            currentStory?.lastPlayedSnapIndex   =   0
            stories?[self.handPickedStoryIndex] =   currentStory!
            story?.stories                                     =    stories!
            if let storyCount = story?.count, storyCount == 1 {
                story?.count            =   storyCount - 1
            }

            self.viewModel?.stories?.stories.removeAll()
            self._view.snapsCollectionView.reloadData()

            if let indexForEmptySnaps = story?.stories.firstIndex(where: {$0.snaps.count == 0}) {
                story?.stories.remove(at: indexForEmptySnaps)
            }

            self.viewModel?.stories     =       story

            DispatchQueue.main.async {
                self._view.snapsCollectionView.reloadData()
            }
UtkuDalmaz commented 4 years ago

@Goldy-74 Where did you put a delete button? I also want to implement a delete mechanism, can you help me with it?

ranmyfriend commented 4 years ago

Hi @UtkuDalmaz Why don't you try this?

Screenshot 2020-02-27 at 5 05 01 PM
UtkuDalmaz commented 4 years ago

@ranmyfriend Ok so how can I give a bottom margin and create a view with button and place that view to that margin area just like your header view part?

sourish commented 4 years ago

Hi @Goldy-74 / @ranmyfriend , where should we add the delete functionality code in the code(I mean which class)

ranmyfriend commented 4 years ago

@sourish You can replicate this functionality on Preview controller, Just refer Instagram App and try to post some sample post from your end. And check you post preview options. you will get know easily

sourish commented 4 years ago

@ranmyfriend ,

I have tried but, if i am deleting the last snap then it is not going to next user story. Can you tell me how to fix this.

ranmyfriend commented 4 years ago

@sourish could you please follow this mechanism https://github.com/drawRect/Instagram_Stories/issues/67#issuecomment-503543416

sourish commented 4 years ago

@ranmyfriend : I have followed it but the issue is if i delete the last snap of the stories it doesn't go to the next user story, it reloads and show the same story from 1st snap.

ranmyfriend commented 4 years ago

Hi @sourish Give us some time, we will try to tweak this implementation and let you know

sourish commented 4 years ago

Hi @ranmyfriend ,

Do not mind, is there any update for deleting Snap.

ranmyfriend commented 4 years ago

@sourish give me some time, please. let you know.

boominadhaprakash commented 4 years ago

Hi @sourish,

We are almost going to finish the delete snap implementation. Will finish it in two to three days. Let you know, once the implementation is over. Thanks for your patience.

Goldy-74 commented 4 years ago

Hello All,

First of all i am really sorry for late replying.

All i have followed my own logic at that time.

First i have created a button in IGStoryPreviewHeaderView class

public lazy var btnDelete : UIButton = {
    let btnDelete = UIButton(type: UIButton.ButtonType.system)
    btnDelete.tintColor = .white
    btnDelete.translatesAutoresizingMaskIntoConstraints = false
    btnDelete.setImage(#imageLiteral(resourceName: "delete"), for: UIControl.State.normal)
    return btnDelete
}()

Do Activate its constraints in installLayoutConstraints method in IGStoryPreviewHeaderView class

    //Delete btnDelete
    NSLayoutConstraint.activate([
    btnDelete.centerYAnchor.constraint(equalTo: self.centerYAnchor),
    btnDelete.rightAnchor.constraint(equalTo: closeButton.leftAnchor),
    btnDelete.widthAnchor.constraint(equalToConstant: 60),
    btnDelete.heightAnchor.constraint(equalToConstant: self.frame.height)])

Now in IGStoryPreviewController class , in cellForRowAtItem method please add following code

    cell.storyHeaderView.btnDelete.tag = indexPath.row
    cell.storyHeaderView.btnDelete.addTarget(self, action: #selector(self.deleteAction(sender:)), for: UIControl.Event.touchUpInside)
    if let userId = story?.snaps.first?.internalIdentifier.components(separatedBy: "-").first , userId == ApplicationPreference.getUserId(){
        cell.storyHeaderView.btnDelete.isHidden    =   false
    } else {
        cell.storyHeaderView.btnDelete.isHidden = true
    }

And the last magical code , add it in IGStoryPreviewController class

Please note - self.presenter?.serverRequestForDeleteStory is an API call.

@objc func deleteAction(sender : UIButton){

    if let cell : IGStoryPreviewCell = _view.snapsCollectionView.cellForItem(at: IndexPath(item: sender.tag, section: 0)) as? IGStoryPreviewCell {

        cell.pausePlayer(with: cell.story?.lastPlayedSnapIndex ?? 0)
        cell.pauseSnapProgressors(with: cell.story?.lastPlayedSnapIndex ?? 0 )

        let alert = UIAlertController(title: "Delete?", message: "Delete this snap?", preferredStyle: UIAlertController.Style.alert)
        let actionY = UIAlertAction(title: "Yes", style: UIAlertAction.Style.default) { (action) in

            var story                               =                   self.viewModel?.stories

            var stories                             =                   story?.stories

            let currentStory                     =                   stories?[self.handPickedStoryIndex]

            var currentStorySnaps            =                currentStory?.snaps

            let selectedSnap                     =                currentStorySnaps?[currentStory?.lastPlayedSnapIndex ?? 0]

            if let storyId = selectedSnap?.internalIdentifier.components(separatedBy: "-").last, storyId.count > 0 {
                let deletedIndex           =       currentStorySnaps?.count == 1 ? self.handPickedStoryIndex : nil

                self.presenter?.serverRequestForDeleteStory(storyId, deleteStoryIndex : deletedIndex, callback: { (success, response, message) in

                    if currentStorySnaps?.count == 1 && stories?.count == 1 {
                        self.dismiss(animated: true, completion: nil)
                        return
                    }

                    if  currentStory?.snapsCount == 1 {
                        currentStory?.snaps.removeAll()
                    } else {
                        currentStorySnaps?.removeAll(where: {$0.internalIdentifier == selectedSnap?.internalIdentifier})
                        currentStory?.snaps                                 =               currentStorySnaps ?? []
                    }

                    currentStory?.snapsCount                         =           (currentStory?.snapsCount ?? 1) - 1

                    self.handPickedStoryIndex                        =               0
                    self.nStoryIndex                                         =                   0

                    currentStory?.lastPlayedSnapIndex            =               0
                    stories?[self.handPickedStoryIndex]             =   currentStory!
                    story?.stories                                                  =    stories!
                    if let storyCount = story?.count , currentStory?.snaps.count == 0{
                        story?.count                                        =   storyCount - 1
                    }

                if let indexForEmptySnaps = story?.stories.firstIndex(where: {$0.snaps.count == 0}) {
                    story?.stories.remove(at: indexForEmptySnaps)
                }

                    self.viewModel?.stories?.stories.removeAll()
                    self._view.snapsCollectionView.reloadData()

                    self.viewModel?.stories                          =       story
                if let s = self.viewModel?.stories {
                    self.stories    =   s
                }

                    DispatchQueue.main.async {
                        self._view.snapsCollectionView.reloadData()
                    }
                })
            }

        }

        let actionN =   UIAlertAction(title: "No", style: UIAlertAction.Style.cancel) { (actionN) in
            cell.resumePlayer(with: cell.story?.lastPlayedSnapIndex ?? 0)
            cell.resumePreviousSnapProgress(with: cell.story?.lastPlayedSnapIndex ?? 0 )
        }

        alert.addAction(actionN)
        alert.addAction(actionY)
        self.present(alert, animated: true, completion: nil)

    }
}

I really hope it. will help you.

sourish commented 4 years ago

Hi @boominadhaprakash,

Thank you for the response. I am very much eagerly waiting for the solution. I have tried the solution i.e provided by @Goldy-74 , but that didn't work out. I am not getting the correct "currentStory" and the even the "deletedIndex". let currentStory = stories?[self.handPickedStoryIndex] let deletedIndex = currentStorySnaps?.count == 1 ? self.handPickedStoryIndex : nil.

I will be waiting for your solution of handling the cases. Thank You.

boominadhaprakash commented 4 years ago

Hi @sourish

We have finished that delete snap functionality. Please take the source code from "Boomi/snapdelete" branch. Delete snap functionality only available for current user story.

The delete snap code is available in IGStoryPreviewCell. Please check the documentation. We are not removing the snaps from IGStory. We are handling with isDeleted flag and we are storing the snap id in UserDefaults. Once the snap is deleted send the deleted snap data to server and remove it from UserDefaults using snap internal identifier.

delete_snap

boominadhaprakash commented 4 years ago

Hi @sourish

Do you have any update for us?

sourish commented 3 years ago

Hi @boominadhaprakash, Thank U for the so fast response, apologise for not updating u, I was moved to another task. The delete functionality worked, but there were issues of progress bar.But in the recent build when i saw those issues got fixed.

Thank U so much for the functionality and fixes of progress bar.

halainn commented 1 year ago

Hey @ranmyfriend when i swipe up the ACTION SHEET will open a while, within 1 second it automatically dismiss please explain to me how can i resolve this issue i want to navigate that user to a particular web page URL when someone is perform swipe up in story view.