VLCEditController.swift 9.61 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*****************************************************************************
 * VLCEditController.swift
 *
 * Copyright © 2018 VLC authors and VideoLAN
 * Copyright © 2018 Videolabs
 *
 * Authors: Soomin Lee <bubu@mikan.io>
 *
 * Refer to the COPYING file of the official project for license.
 *****************************************************************************/

protocol VLCEditControllerDataSource {
    func toolbarNeedsUpdate(editing: Bool)
}

class VLCEditController: NSObject {
17
    private var selectedCellIndexPaths = Set<IndexPath>()
18 19 20
    private let collectionView: UICollectionView
    private let category: MediaLibraryBaseModel

21 22 23 24 25 26 27
//    private lazy var editToolbar: VLCEditToolbar = {
//        let editToolbar = VLCEditToolbar(frame: CGRect(x: 0, y: 400,
//                                                       width: collectionView.frame.width, height: 50))
//        editToolbar.isHidden = true
//        editToolbar.delegate = self
//        return editToolbar
//    }()
28 29 30 31 32 33

    init(collectionView: UICollectionView, category: MediaLibraryBaseModel) {
        self.collectionView = collectionView
        self.category = category
        super.init()

34 35
//        collectionView.addSubview(editToolbar)
//        collectionView.bringSubview(toFront: editToolbar)
36 37 38
    }
}

39 40 41 42
// MARK: - Helpers

private extension VLCEditController {
    private func resetCell(at indexPath: IndexPath) {
43 44
        if let cell = collectionView.cellForItem(at: indexPath) as? MediaEditCell {
            cell.isChecked = false
45 46
        }
    }
47 48

    private func resetAllVisibleCell() {
49 50
        for case let cell as MediaEditCell in collectionView.visibleCells {
            cell.isChecked = false
51 52
        }
    }
53 54 55 56

    private struct TextFieldAlertInfo {
        var alertTitle: String
        var placeHolder: String
57 58 59 60 61 62 63 64 65
        var confirmActionTitle: String

        init(alertTitle: String = "",
             placeHolder: String = "",
             confirmActionTitle: String = NSLocalizedString("BUTTON_DONE", comment: "")) {
            self.alertTitle = alertTitle
            self.placeHolder = placeHolder
            self.confirmActionTitle = confirmActionTitle
        }
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    }

    private func presentTextFieldAlert(with info: TextFieldAlertInfo,
                                       completionHandler: @escaping (String) -> Void) {
        let alertController = UIAlertController(title: info.alertTitle,
                                                message: "",
                                                preferredStyle: .alert)

        alertController.addTextField(configurationHandler: {
            textField in
            textField.placeholder = info.placeHolder
        })

        let cancelButton = UIAlertAction(title: NSLocalizedString("BUTTON_CANCEL", comment: ""),
                                         style: .default)


83
        let confirmAction = UIAlertAction(title: info.confirmActionTitle, style: .default) {
84 85 86 87 88 89 90 91 92 93 94
            [weak alertController] _ in
            guard let alertController = alertController,
                let textField = alertController.textFields?.first else { return }
            completionHandler(textField.text ?? "")
        }

        alertController.addAction(cancelButton)
        alertController.addAction(confirmAction)

        UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
    }
95 96
}

97 98
// MARK: - VLCEditControllerDataSource

99 100
extension VLCEditController: VLCEditControllerDataSource {
    func toolbarNeedsUpdate(editing: Bool) {
101
//        editToolbar.isHidden = !editing
102 103 104 105
        if !editing {
            // not in editing mode anymore should reset
            selectedCellIndexPaths.removeAll(keepingCapacity: false)
        }
106 107 108
    }
}

109 110
// MARK: - VLCEditToolbarDelegate

111 112
extension VLCEditController: VLCEditToolbarDelegate {
    func createPlaylist() {
113
        if let model = category as? PlaylistModel {
114 115 116 117 118 119 120 121
            let alertInfo = TextFieldAlertInfo(alertTitle: NSLocalizedString("VIDEO_PLAYLISTS", comment: ""),
                placeHolder: "NEW_PLAYLIST")

            presentTextFieldAlert(with: alertInfo, completionHandler: {
                text -> Void in
                    model.create(name: text)
                })

122
        } else if let model = category as? VideoModel {
123 124 125 126 127 128 129 130 131 132
            let alertInfo = TextFieldAlertInfo(alertTitle: NSLocalizedString("VIDEO_PLAYLISTS", comment: ""),
                                               placeHolder: "NEW_PLAYLIST")

            presentTextFieldAlert(with: alertInfo, completionHandler: {
                [selectedCellIndexPaths, category] text -> Void in
                let playlist = model.medialibrary.createPlaylist(with: text)
                for indexPath in selectedCellIndexPaths {
                    if let media = category.anyfiles[indexPath.row] as? VLCMLMedia {
                        playlist.appendMedia(withIdentifier: media.identifier())
                    }
133
                }
134
            })
135
        }
136 137 138
    }

    func delete() {
139 140 141 142 143 144 145 146
        var objectsToDelete = [VLCMLObject]()

        for indexPath in selectedCellIndexPaths {
            objectsToDelete.append(category.anyfiles[indexPath.row])
        }

        let cancelButton = VLCAlertButton(title: NSLocalizedString("BUTTON_CANCEL", comment: ""))
        let deleteButton = VLCAlertButton(title: NSLocalizedString("BUTTON_DELETE", comment: ""),
147
                                          style: .destructive,
148 149 150 151 152 153
                                          action: {
                                            [weak self] action in
                                            self?.category.delete(objectsToDelete)
                                            self?.selectedCellIndexPaths.removeAll()
                                            self?.resetAllVisibleCell()
        })
154

155 156 157 158 159
        VLCAlertViewController.alertViewManager(title: NSLocalizedString("DELETE_TITLE", comment: ""),
                                                errorMessage: NSLocalizedString("DELETE_MESSAGE", comment: ""),
                                                viewController: (UIApplication.shared.keyWindow?.rootViewController)!,
                                                buttonsAction: [cancelButton,
                                                                deleteButton])
160 161 162
    }

    func rename() {
163
        // FIXME: Multiple renaming of files(multiple alert can get unfriendly if too many files)
164 165 166
        for indexPath in selectedCellIndexPaths {
            if let media = category.anyfiles[indexPath.row] as? VLCMLMedia {
                // Not using VLCAlertViewController to have more customization in text fields
167
                let alertInfo = TextFieldAlertInfo(alertTitle: String(format: NSLocalizedString("RENAME_MEDIA_TO", comment: ""), media.title),
168 169
                                                   placeHolder: "NEW_NAME",
                                                   confirmActionTitle: NSLocalizedString("BUTTON_RENAME", comment: ""))
170 171
                presentTextFieldAlert(with: alertInfo, completionHandler: {
                    [weak self] text -> Void in
172 173 174 175 176 177
                    guard text != "" else {
                        VLCAlertViewController.alertViewManager(title: NSLocalizedString("ERROR_RENAME_FAILED", comment: ""),
                                                                errorMessage: NSLocalizedString("ERROR_EMPTY_NAME", comment: ""),
                                                                viewController: (UIApplication.shared.keyWindow?.rootViewController)!)
                        return
                    }
178
                    media.updateTitle(text)
179
                    self?.resetCell(at: indexPath)
180
                })
181 182
            }
        }
183 184 185
    }
}

186 187
// MARK: - UICollectionViewDataSource

188 189 190 191 192 193
extension VLCEditController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return category.anyfiles.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
194 195 196 197 198 199 200
        if let editCell = (category as? EditableMLModel)?.editCellType() {
            if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: editCell.defaultReuseIdentifier,
                                                             for: indexPath) as? MediaEditCell {
                cell.media = category.anyfiles[indexPath.row]
                cell.isChecked = selectedCellIndexPaths.contains(indexPath)
                return cell
            }
201 202 203 204 205
        }
        return UICollectionViewCell()
    }
}

206 207
// MARK: - UICollectionViewDelegate

208 209
extension VLCEditController: UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
210 211 212
        if let cell = collectionView.cellForItem(at: indexPath) as? MediaEditCell {
            cell.isChecked = !cell.isChecked
            if cell.isChecked {
213 214 215 216 217
                // cell selected, saving indexPath
                selectedCellIndexPaths.insert(indexPath)
            } else {
                selectedCellIndexPaths.remove(indexPath)
            }
218 219 220 221
        }
    }
}

222 223
// MARK: - UICollectionViewDelegateFlowLayout

224 225 226 227 228
extension VLCEditController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let contentInset = collectionView.contentInset
        // FIXME: 5 should be cell padding, but not usable maybe static?
        let insetToRemove = contentInset.left + contentInset.right + (5 * 2)
229
        return CGSize(width: collectionView.frame.width - insetToRemove, height: MediaEditCell.height)
230 231
    }
}