Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Data/Data/Element/EditVideoElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ struct EditVideoElement: Codable, Hashable {
let endTime: Double

func hash(into hasher: inout Hasher) {
// hasher.combine(url.lastPathComponent)
hasher.combine(name)
}

static func == (lhs: EditVideoElement, rhs: EditVideoElement) -> Bool {
return lhs.name == rhs.name
}
// lhs.url.lastPathComponent == rhs.url.lastPathComponent &&
}

struct User: Codable, Hashable {
Expand Down
45 changes: 21 additions & 24 deletions Domain/UseCase/VideoUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Interfaces
public final class VideoUseCase {
private var cancellables: Set<AnyCancellable> = []
private var sharedVideos: [SharedVideo] = []
private var editingVideos = [String: Video]()
private var editingVideos = [Video]()
private let sharingVideoRepository: SharingVideoRepositoryInterface
private let editVideoRepository: EditVideoRepositoryInterface

Expand Down Expand Up @@ -61,7 +61,7 @@ extension VideoUseCase: EditVideoUseCaseInterface {
public func fetchVideos() async -> [Video] {
var videos = [Video]()
let sortedVideos = sharedVideos
.sorted { $0.localUrl.path < $1.localUrl.path }
.sorted { $0.localUrl.lastPathComponent < $1.localUrl.lastPathComponent }

for (index, video) in sortedVideos.enumerated() {
let duration = await duration(url: video.localUrl)
Expand All @@ -76,8 +76,8 @@ extension VideoUseCase: EditVideoUseCaseInterface {
videos.append(video)
}

videos.forEach { editingVideos[$0.url.path] = $0 }
editVideoRepository.initializedVideo(videos)
editingVideos = videos
return videos
}

Expand All @@ -87,7 +87,7 @@ extension VideoUseCase: EditVideoUseCaseInterface {
}

public func reArrangingVideo(url: URL, index: Int) {
let videos = updatedVideos(url: url, index: index)
let videos = updatedVideos(url: url, to: index)
editVideoRepository.reArrangingVideo(videos)
}
}
Expand All @@ -107,12 +107,16 @@ private extension VideoUseCase {
.store(in: &cancellables)

editVideoRepository.editedVideos
.subscribe(editedVideos)
.sink(with: self) { (owner, videos) in
owner.editingVideos = videos
owner.editedVideos.send(videos)
}
.store(in: &cancellables)
}

func updatedVideo(url: URL, startTime: Double, endTime: Double) -> Video? {
guard let video = editingVideos[url.path] else { return nil }
guard let video = editingVideos.first(where: { $0.url.path == url.path })
else { return nil }

let newVideo = Video(
url: video.url,
Expand All @@ -125,36 +129,29 @@ private extension VideoUseCase {
endTime: endTime
)

editingVideos[url.path] = video

return newVideo
}

func updatedVideos(url: URL, index: Int) -> [Video] {
guard let video = editingVideos[url.path] else { return [] }
var newVideos = [Video]()
let beforeIndex = video.index
let adder = beforeIndex < index ? -1 : 1

let lowerBound = min(beforeIndex, index)
let upperBound = min(beforeIndex, index)

let videos = editingVideos.values
.filter { $0.index >= lowerBound && $0.index < upperBound }
.map { updatedVideo(video: $0, index: index + adder) }
func updatedVideos(url: URL, to index: Int) -> [Video] {
guard let oldIndex = editingVideos.firstIndex(where: { $0.url.lastPathComponent == url.lastPathComponent })
else { return editingVideos }

newVideos.append(contentsOf: videos)
newVideos.append(updatedVideo(video: video, index: index))
newVideos.forEach { editingVideos[$0.url.path] = $0 }
let video = editingVideos.remove(at: oldIndex)
editingVideos.insert(video, at: index)

let listIndexOrderedVideo = editingVideos.enumerated().map { (index, video) in
updatedVideo(video: video, index: index)
}

editingVideos = listIndexOrderedVideo
return newVideos
}

func updatedVideo(video: Video, index: Int) -> Video {
return Video(
url: video.url,
name: video.name,
index: video.index,
index: index,
duration: video.duration,
author: video.author,
editor: video.editor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ struct VideoPresentationModel {
let endTime: Double
let frameImage: UIImageWrapper
}

extension VideoPresentationModel: Equatable {
static func == (lhs: VideoPresentationModel, rhs: VideoPresentationModel) -> Bool {
if lhs.url == rhs.url { return true }
return false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,25 @@ extension SharedVideoEditViewController: UICollectionViewDropDelegate {

snapshot.deleteItems(draggedItems)
let targetIndex = destinationIndexPath.item

let currentItems = snapshot.itemIdentifiers
var updatedItems = currentItems
updatedItems.insert(contentsOf: draggedItems, at: targetIndex)

applySnapShot(with: updatedItems)

coordinator.items.forEach { item in
coordinator.drop(item.dragItem, toItemAt: destinationIndexPath)
}

applySnapShot(with: updatedItems)

collectionView.scrollToItem(
at: destinationIndexPath,
at: .centeredHorizontally,
animated: true
)

guard let reorderItem = videoTimelineDataSource.itemIdentifier(for: destinationIndexPath) else { return }

input.send(.timelineCellOrderDidChanged(to: targetIndex, url: reorderItem.url))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ enum SharedVideoEditViewInput {
case sliderModelLowerValueDidChanged(value: Double)
case sliderModelUpperValueDidChanged(value: Double)
case sliderEditSaveButtonDidTapped
case timelineCellOrderDidChanged(to: Int, url: URL)
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,18 @@ extension SharedVideoEditViewModel {
owner.updateTappedVideoPresentationModel(upperValue: value)
case .sliderEditSaveButtonDidTapped:
guard let currentTappedVideoPresentationModel = owner.tappedVideoPresentationModel else { return }

if let index = owner.videoPresentationModels.firstIndex(where: {
$0 == currentTappedVideoPresentationModel
}) {
owner.videoPresentationModels[index] = currentTappedVideoPresentationModel
}
owner.usecase.trimmingVideo(
url: currentTappedVideoPresentationModel.url,
startTime: currentTappedVideoPresentationModel.startTime,
endTime: currentTappedVideoPresentationModel.endTime
)
case .timelineCellOrderDidChanged(let to, let url):
owner.videoOrderChanged(to: to, url: url)
}
}
.store(in: &cancellables)
Expand All @@ -69,19 +75,24 @@ private extension SharedVideoEditViewModel {
if let currentTappedVideoPresentationModel = owner.tappedVideoPresentationModel {
guard
let tappedVideo = videos.first(
where: { $0.url == currentTappedVideoPresentationModel.url }),
where: { $0.url.path == currentTappedVideoPresentationModel.url.path }),
let model = await owner.makeVideoPresentationModel(video: tappedVideo)
else { return }
owner.setTappedVideoPresentationModel(model: model)
}

// Timeline 순서 편집 처리
let newTimelineItems = await videos.asyncCompactMap { video in
let orderdVideos = videos.sorted { $0.index < $1.index }
var timeLineItem: [VideoTimelineItem] = []
for video in orderdVideos {
let asset = AVAsset(url: video.url)
owner.appendVideoPresentationModels(video: video)
return await owner.makeVideoTimelineItem(with: video.url, asset: asset)
async let item = owner.makeVideoTimelineItem(with: video.url, asset: asset)
await timeLineItem.append(item)
}
owner.output.send(.timelineItemsDidChanged(items: newTimelineItems))
// let newTimelineItems = await orderdVideos.asyncCompactMap { video in
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: 주석 제거 하셔야 할꺼 같습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영했습니다!

// return await
// }
owner.output.send(.timelineItemsDidChanged(items: timeLineItem))
}
}
.store(in: &cancellables)
Expand Down Expand Up @@ -236,4 +247,15 @@ private extension SharedVideoEditViewModel {
setTappedVideoPresentationModel(model: tappedModel)
}
}

func videoOrderChanged(
to: Int,
url: URL
) {
guard let index = videoPresentationModels.firstIndex(where: { $0.url == url })
else { return }
let video = videoPresentationModels.remove(at: index)
videoPresentationModels.insert(video, at: to)
usecase.reArrangingVideo(url: video.url, index: to)
}
}
Loading