diff --git a/kplayer/core/DatabaseManager.swift b/kplayer/core/DatabaseManager.swift index d6b8343..30cd391 100644 --- a/kplayer/core/DatabaseManager.swift +++ b/kplayer/core/DatabaseManager.swift @@ -24,11 +24,9 @@ class DatabaseManager { let results = try! managedObjectContext.fetch(fetchRequest) - var saved = false - for r in results { print(r.name) - saved = true + item.favorite = r.favorite for s in r.snapshots as! Set { print("DB -- Found snapshot at \(s.index)") @@ -43,6 +41,7 @@ class DatabaseManager { c.offset.x = CGFloat(s.offx) c.offset.y = CGFloat(s.offy) c.scale = s.scale + c.rating = Int(s.rating) } } print(s) @@ -67,11 +66,12 @@ class DatabaseManager { return r } - var new = KItem(context: managedObjectContext) + let new = KItem(context: managedObjectContext) new.name = item.name new.root = item.root new.path = item.path new.local = item.local + new.favorite = item.favorite new.type = item.type.rawValue do { @@ -87,9 +87,11 @@ class DatabaseManager { if (item.type == ItemType.VIDEO) { let k = getKItem(item) + k.favorite = item.favorite + var kstimes = Set() - var ksitems = k.snapshots as! Set + let ksitems = k.snapshots as! Set for snap in ksitems { print(snap) @@ -108,6 +110,7 @@ class DatabaseManager { snap.sizex = Int16(c.size.width) snap.sizey = Int16(c.size.height) snap.scale = c.scale + snap.rating = Int16(c.rating) snap.thumb = c.thumbUrl k.addToSnapshots(snap) @@ -124,6 +127,7 @@ class DatabaseManager { snap.sizex = Int16(c.size.width) snap.sizey = Int16(c.size.height) snap.scale = c.scale + snap.rating = Int16(c.rating) snap.thumb = c.thumbUrl print("DB -- Update snapshot at \(c.indexId)") diff --git a/kplayer/core/KItem+CoreDataProperties.swift b/kplayer/core/KItem+CoreDataProperties.swift index 3fd4ce5..9275dda 100644 --- a/kplayer/core/KItem+CoreDataProperties.swift +++ b/kplayer/core/KItem+CoreDataProperties.swift @@ -2,7 +2,7 @@ // KItem+CoreDataProperties.swift // kplayer // -// Created by Marco Schmickler on 17.01.22. +// Created by Marco Schmickler on 19.01.22. // Copyright © 2022 Marco Schmickler. All rights reserved. // // @@ -22,6 +22,7 @@ extension KItem { @NSManaged public var path: String? @NSManaged public var root: String? @NSManaged public var type: String? + @NSManaged public var favorite: Bool @NSManaged public var snapshots: NSSet? } diff --git a/kplayer/core/LocalManager.swift b/kplayer/core/LocalManager.swift index 15b63bf..e7e3114 100644 --- a/kplayer/core/LocalManager.swift +++ b/kplayer/core/LocalManager.swift @@ -119,11 +119,11 @@ class LocalManager { if (fileURL.pathExtension == "jpg" && fileURL.absoluteString.contains("/images/")) { let p = fileURL.absoluteString.substringAfter("/Documents") - var path = p.substringBefore("/") + let path = p.substringBefore("/") let fp = fileURL.absoluteString.substringAfter("/Documents/images/") - var fpath = fp.substringBefore("/") + let fpath = fp.substringBefore("/") var folder = itemsMap[fpath] @@ -150,6 +150,8 @@ class LocalManager { m.scale = item.scale m.offset = item.offset m.size = item.size + + DatabaseManager.sharedInstance.saveItemMetaData(m) } } catch { @@ -192,10 +194,10 @@ class LocalManager { i.externalURL = fileURL.absoluteString i.local = true } - + DatabaseManager.sharedInstance.saveItemMetaData(mediaItem) res.append(mediaItem) } catch { - var path = p.substringBefore("/") + let path = p.substringBefore("/") let m = MediaItem(name: fileURL.lastPathComponent, path: path, root: "fav", type: ItemType.VIDEO) m.local = true diff --git a/kplayer/core/MediaItem.swift b/kplayer/core/MediaItem.swift index 3d146fd..aba1845 100644 --- a/kplayer/core/MediaItem.swift +++ b/kplayer/core/MediaItem.swift @@ -60,6 +60,9 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { @Published var length: TimeInterval = 0.0 + @Published + var rating = 0 + @Published var loop = true @@ -72,6 +75,8 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { var leaf = false var cancelled = false + var favorite = false + @Published var scale = 0.0 @Published @@ -90,6 +95,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { self.scale = model.scale self.offset = model.offset self.size = model.size + self.favorite = model.favorite self.loaded = true self.local = true @@ -121,6 +127,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { model.size = size model.offset = offset model.scale = scale + model.favorite = favorite return model } @@ -234,7 +241,7 @@ class MediaItem: CustomDebugStringConvertible, ObservableObject, Identifiable { if encodedDir!.count >= 10 { let index = encodedDir!.index(encodedDir!.startIndex, offsetBy: 10) - encoded = encodedDir!.substring(from:index) + encoded = String(encodedDir![index...]) } else { encoded = encodedDir! diff --git a/kplayer/core/MediaModel.swift b/kplayer/core/MediaModel.swift index e55b415..63c37bc 100644 --- a/kplayer/core/MediaModel.swift +++ b/kplayer/core/MediaModel.swift @@ -14,6 +14,7 @@ public struct MediaModel : Codable { var time = 0.0 var length = 0.0 var loop = false + var favorite = false var thumbURL : String? var externalURL : String? diff --git a/kplayer/core/NetworkManager.swift b/kplayer/core/NetworkManager.swift index 0ed88b7..d6a0af2 100644 --- a/kplayer/core/NetworkManager.swift +++ b/kplayer/core/NetworkManager.swift @@ -163,8 +163,8 @@ class NetworkManager { print("Empfange \(result.count) Ergebnisse") for s in result { - var name = s[0] - var type = s[1] + let name = s[0] + let type = s[1] var t = ItemType.FOLDER @@ -343,7 +343,7 @@ class NetworkManager { func saveItem(_ item: MediaItem) { var ch = item.children - print(ch) +// print(ch) if (item.local) { return diff --git a/kplayer/core/ThumbnailCache.swift b/kplayer/core/ThumbnailCache.swift index a15a9a1..147b23f 100644 --- a/kplayer/core/ThumbnailCache.swift +++ b/kplayer/core/ThumbnailCache.swift @@ -135,7 +135,7 @@ class ThumbnailCache { urlSession!.dataTask(with: URL, completionHandler: { (da, response, error) in if let d = da { - DispatchQueue.global(priority: DispatchQueue.GlobalQueuePriority.high).async { + DispatchQueue.global(qos: .default).async { () -> Void in self.loadData(d, start: start, end: end) } diff --git a/kplayer/detail/DetailViewController.swift b/kplayer/detail/DetailViewController.swift index 3d08de5..46ff703 100644 --- a/kplayer/detail/DetailViewController.swift +++ b/kplayer/detail/DetailViewController.swift @@ -96,7 +96,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout if detailItem != nil { if detailItem!.children != nil { var d = detailItem!.children - print("Details \(d)") + // print("Details \(d)") } } } @@ -411,7 +411,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout print(detail.toJSON()) // NetworkManager.sharedInstance.saveFavDir(name: "fav.json", item: detail) - var sectionItem = detail.children[indexPath.section] + let sectionItem = detail.children[indexPath.section] currentItem = sectionItem var selectedItem = currentItem! @@ -479,7 +479,7 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout if selectedItem.name.contains("strip") { let chromeURL = selectedItem.name.replacingOccurrences(of: "https://", with: "googlechrome://") - UIApplication.shared.openURL(URL(string: chromeURL)!) + UIApplication.shared.open(URL(string: chromeURL)!) return } diff --git a/kplayer/detail/EditItemView.swift b/kplayer/detail/EditItemView.swift index 3683a55..9a70583 100644 --- a/kplayer/detail/EditItemView.swift +++ b/kplayer/detail/EditItemView.swift @@ -80,6 +80,9 @@ struct EditItemView: View { }, label: { Text("Reset") }).padding(10).buttonStyle(BorderlessButtonStyle()); + Stepper(value:$item.rating, in: -1...5){ + Text("*\(item.rating)").frame(width: 25) + } Button(action: { delegate.cancelEdit() }, label: { diff --git a/kplayer/detail/ItemCell.swift b/kplayer/detail/ItemCell.swift index 31a0a5e..49529b2 100644 --- a/kplayer/detail/ItemCell.swift +++ b/kplayer/detail/ItemCell.swift @@ -13,6 +13,7 @@ class ItemCell: UICollectionViewCell { var item: MediaItem? var image: UIImageView! + var fav: UIImageView! var progress: UIProgressView! required init?(coder aDecoder: NSCoder) { @@ -26,6 +27,13 @@ class ItemCell: UICollectionViewCell { image = UIImageView(frame: frame) image.contentMode = UIView.ContentMode.scaleAspectFit + let fi = UIImage(systemName: "heart") + fav = UIImageView(image: fi) + // fav.contentMode = UIView.ContentMode.scaleAspectFill + + image.addSubview(fav) + fav.isHidden = true + progress = UIProgressView(progressViewStyle: .default) progress.progressTintColor = .red progress.trackTintColor = .lightGray @@ -45,6 +53,13 @@ class ItemCell: UICollectionViewCell { progress.progress = Float(item.length) return } + var f = false + + if item.type == ItemType.SNAPSHOT { + f = item.parent!.favorite + } + + fav.isHidden = !f if let _ = item.thumbUrl, let nsurl = URL(string: item.thumbUrlAbsolute) { image.hnk_setImageFromURL(nsurl, placeholder: defaultImage) diff --git a/kplayer/kplayer.xcdatamodeld/kplayer.xcdatamodel/contents b/kplayer/kplayer.xcdatamodeld/kplayer.xcdatamodel/contents index db5fe73..33522f2 100644 --- a/kplayer/kplayer.xcdatamodeld/kplayer.xcdatamodel/contents +++ b/kplayer/kplayer.xcdatamodeld/kplayer.xcdatamodel/contents @@ -1,6 +1,7 @@ + @@ -29,7 +30,7 @@ - + diff --git a/kplayer/master/KSettingsView.swift b/kplayer/master/KSettingsView.swift index 53b6cb9..479dc55 100644 --- a/kplayer/master/KSettingsView.swift +++ b/kplayer/master/KSettingsView.swift @@ -17,7 +17,7 @@ struct KSettingsView: View { Section(header: Text("K Settings")) { HStack { Text("Size") - Slider(value: $kSettings.scale, in: 0...1) + Slider(value: $kSettings.scale, in: 1...2) Toggle(isOn: $kSettings.autoloop, label: { Text("Autoloop") }) diff --git a/kplayer/svideo/SVideoModel.swift b/kplayer/svideo/SVideoModel.swift index c1762d5..efaf0d3 100644 --- a/kplayer/svideo/SVideoModel.swift +++ b/kplayer/svideo/SVideoModel.swift @@ -24,6 +24,7 @@ class SVideoModel : ObservableObject { @Published var edit = false @Published var loop = false @Published var zoomed = false + @Published var favorite = false @Published var speed: Float = 1.0 @@ -40,6 +41,8 @@ class SVideoModel : ObservableObject { self.allItems = allItems self.currentSnapshot = currentSnapshot self.baseItem = baseItem + + self.favorite = baseItem.favorite } func currentPlayerItem() -> AVPlayerItem { diff --git a/kplayer/svideo/SVideoPlayer.swift b/kplayer/svideo/SVideoPlayer.swift index 78dc213..d1976a0 100644 --- a/kplayer/svideo/SVideoPlayer.swift +++ b/kplayer/svideo/SVideoPlayer.swift @@ -51,25 +51,37 @@ struct SVideoPlayer: View, EditItemDelegate { var body: some View { VStack { HStack { - Button(action: { - player.pause() - player.replaceCurrentItem(with: nil) - model.currentURL = nil - cleanup() - completionHandler!(model.edit) - }, label: { - Text("cancel") - }).buttonStyle(BorderlessButtonStyle()) - Button(action: { - model.loop.toggle() - }, label: { - Text("loop") - }).foregroundColor(model.loop ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) - Button(action: { - model.zoomed.toggle() - }, label: { - Text("zoom") - }).foregroundColor(model.zoomed ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) + Group { + Button(action: { + model.baseItem.favorite = model.favorite + player.pause() + player.replaceCurrentItem(with: nil) + model.currentURL = nil + cleanup() + completionHandler!(model.edit) + }, label: { + Text("cancel") + }) + .buttonStyle(BorderlessButtonStyle()) + Button(action: { + model.loop.toggle() + }, label: { + Text("loop") + }) + .foregroundColor(model.loop ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) + Button(action: { + model.zoomed.toggle() + }, label: { + Text("zoom") + }) + .foregroundColor(model.zoomed ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) + Button(action: { + model.favorite.toggle() + }, label: { + Image(systemName: "heart.fill") + }) + .foregroundColor(model.favorite ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle()) + } Button(action: { for s in steps { @@ -224,7 +236,7 @@ struct SVideoPlayer: View, EditItemDelegate { self.orientation = UIDevice.current.orientation } } - + func doSnapshot() { let currentItem = player.currentItem! let asset = currentItem.asset @@ -278,31 +290,31 @@ struct SVideoPlayer: View, EditItemDelegate { } if let time = getCurrentTime() { - let sk = model.seeking - model.seeking = false + // let sk = model.seeking + // model.seeking = false // print("Start \(start.y) Drag \(dragged.width)))") let dragWidth = 20.0 - - if (start.y < 130) { - if model.scale > 1.0 { - return true - } - if dragged.width > dragWidth { - seekTime(time + 8.0) - } else if dragged.width < -dragWidth { - seekTime(time - 10.0) - } - } - else { - if dragged.width > dragWidth { - seekTime(time + 30.0) - } else if dragged.width < -dragWidth { - seekTime(time - 30.0) + if !model.seeking { + if (start.y < 130) { + if model.scale > 1.0 { + return true + } + if dragged.width > dragWidth { + seekTime(time + 8.0) + } else if dragged.width < -dragWidth { + seekTime(time - 10.0) + } + } else { + if dragged.width > dragWidth { + seekTime(time + 30.0) + } else if dragged.width < -dragWidth { + seekTime(time - 30.0) + } } } - model.seeking = sk + // model.seeking = sk } if dragged.height > 100 && timeCounter == 0 { @@ -326,6 +338,7 @@ struct SVideoPlayer: View, EditItemDelegate { func seekTime(_ time: Double) { print("Seek \(time)") + self.model.seeking = true player.pause() // player.cancelPendingPrerolls() @@ -333,11 +346,13 @@ struct SVideoPlayer: View, EditItemDelegate { item.cancelPendingSeeks() } - player.seek(to: CMTime(seconds: time, preferredTimescale: CMTimeScale(10000)), - toleranceBefore: CMTime(seconds: 0.3, preferredTimescale: CMTimeScale(10000)), - toleranceAfter: CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(10000))){ _ in + player.seek(to: CMTime(seconds: time, preferredTimescale: CMTimeScale(600))){ _ in +// player.seek(to: CMTime(seconds: time, preferredTimescale: CMTimeScale(10000)), +// toleranceBefore: CMTime(seconds: 0.3, preferredTimescale: CMTimeScale(10000)), +// toleranceAfter: CMTime(seconds: 1.0, preferredTimescale: CMTimeScale(10000))){ _ in player.play() player.rate = model.speed + self.model.seeking = false } } @@ -393,8 +408,8 @@ struct SVideoPlayer: View, EditItemDelegate { } else { if model.zoomed && f > 0.0 { - if f < 0.5 { - f = f * 1.5 + if f < 0.6 { + f = f * CGFloat(LocalManager.sharedInstance.settings.scale) } model.scale = f }