Browse Source

Photos

master
marcoschmickler 4 years ago
parent
commit
f7c88a14d5
  1. 8
      kplayer.xcodeproj/project.pbxproj
  2. 8
      kplayer/core/DatabaseManager.swift
  3. 20
      kplayer/detail/DetailViewController+Show.swift
  4. 17
      kplayer/detail/DetailViewController.swift
  5. 11
      kplayer/detail/EditItemView.swift
  6. 15
      kplayer/photo/SPhotoModel.swift
  7. 46
      kplayer/photo/SPhotoView.swift
  8. 20
      kplayer/util/AsyncImage.swift
  9. 14
      kplayer/video/SVideoPlayer.swift

8
kplayer.xcodeproj/project.pbxproj

@ -12,6 +12,7 @@
1C7360C0F2A4F0214FE353BD /* FileHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7367ECBD369A2A0C94C499 /* FileHelper.swift */; };
1C73613562EB375F53A0BD03 /* ServerDownloadDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736595533B56039C417E0D /* ServerDownloadDelegate.swift */; };
1C7361B3AF46CEB30D3F4FA0 /* KSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736AE5021E3D985FE3402D /* KSettings.swift */; };
1C73620BC7F5A1F35FFFF9FC /* SPhotoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736AD9F0A39AD543FC1176 /* SPhotoView.swift */; };
1C73631EACF56BABD3B2BCFB /* LayoutTools.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736BC4450890C45F8FBC63 /* LayoutTools.swift */; };
1C73633C00C18FDA2E9F0A2F /* KNetworkProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736DCD945ABAE984FF43EF /* KNetworkProtocol.swift */; };
1C73635138BBD2BB480A308F /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C736777456388CA571DA17B /* MediaPlayer.framework */; };
@ -50,6 +51,7 @@
1C736A622876405F3EE2D043 /* EditItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7366C09381DC0052B52B69 /* EditItemView.swift */; };
1C736A7B6221A1D50FB3904C /* ItemType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73631C96E6C860833052CA /* ItemType.swift */; };
1C736B4B0889BD35DC566124 /* nspersistentcontainer-defaults-swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7361F01841F546FA7AFD58 /* nspersistentcontainer-defaults-swift.swift */; };
1C736BEC4C4263EF6A89E9E3 /* SPhotoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */; };
1C736C00693A05747578DF87 /* grabber.js in Sources */ = {isa = PBXBuildFile; fileRef = 1C73619BBFA9295A11C9ACBA /* grabber.js */; };
1C736C8DAD6C2FBB9A2EA625 /* SearchItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C73654AB95A2D629833BEC5 /* SearchItemView.swift */; };
1C736C9821DA743C2E3F3B07 /* kplayer.txt in Resources */ = {isa = PBXBuildFile; fileRef = 1C7360F9649E40B7C2EAB581 /* kplayer.txt */; };
@ -134,6 +136,7 @@
1C7369EC16B19B32B515169E /* NetData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetData.swift; sourceTree = "<group>"; };
1C7369F53095B7A4D65679C2 /* DetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailViewController.swift; sourceTree = "<group>"; };
1C736A6E8396EE306B1AD3A8 /* KSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KSettingsView.swift; sourceTree = "<group>"; };
1C736AD9F0A39AD543FC1176 /* SPhotoView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPhotoView.swift; sourceTree = "<group>"; };
1C736AE5021E3D985FE3402D /* KSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KSettings.swift; sourceTree = "<group>"; };
1C736B17A8E9FB352B90A903 /* DetailViewController+Show.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DetailViewController+Show.swift"; sourceTree = "<group>"; };
1C736B41C6AC33F3FA592C63 /* MediaModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaModel.swift; sourceTree = "<group>"; };
@ -150,6 +153,7 @@
1C736EA15A11AF7D57F85824 /* ThumbnailCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThumbnailCache.swift; sourceTree = "<group>"; };
1C736EEC570C71AAC50F2E95 /* SVideoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVideoModel.swift; sourceTree = "<group>"; };
1C736EF64DE56AD058A4F612 /* KBrowserView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KBrowserView.swift; sourceTree = "<group>"; };
1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SPhotoModel.swift; sourceTree = "<group>"; };
1C736F9338CE36708244D42A /* DataLoadOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataLoadOperation.swift; sourceTree = "<group>"; };
6D522F61736592330F481B4F /* Pods-kplayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-kplayer.debug.xcconfig"; path = "Pods/Target Support Files/Pods-kplayer/Pods-kplayer.debug.xcconfig"; sourceTree = "<group>"; };
8B75159FFCD5A882E6F167FE /* Pods_kplayer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_kplayer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@ -220,6 +224,8 @@
isa = PBXGroup;
children = (
1C73673DC671535E3A049F54 /* PhotoController.swift */,
1C736AD9F0A39AD543FC1176 /* SPhotoView.swift */,
1C736F83C6190A3A0D5BD1F0 /* SPhotoModel.swift */,
);
path = photo;
sourceTree = "<group>";
@ -622,6 +628,8 @@
1C736776CF759CA3DB136F33 /* KBrowserView.swift in Sources */,
1C7369C0A66A8F8CB0E54460 /* WebView.swift in Sources */,
1C736C00693A05747578DF87 /* grabber.js in Sources */,
1C73620BC7F5A1F35FFFF9FC /* SPhotoView.swift in Sources */,
1C736BEC4C4263EF6A89E9E3 /* SPhotoModel.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

8
kplayer/core/DatabaseManager.swift

@ -266,7 +266,12 @@ class DatabaseManager {
for s in snapshots {
let sitem = loadSnapshot(s: s)
sitem.parent = tag
tag.children.append(sitem)
if sitem.name == tag.name {
print(sitem.name)
}
else {
tag.children.append(sitem)
}
}
res.append(tag)
@ -300,6 +305,7 @@ class DatabaseManager {
c.offset.y = CGFloat(s.offy)
c.scale = s.scale
c.rating = Int(s.rating)
c.objectID = s.objectID
if s.thumb != nil {
c.thumbUrl = s.thumb

20
kplayer/detail/DetailViewController+Show.swift

@ -22,6 +22,26 @@ extension DetailViewController {
}
func showPhotos(_ im: [MediaItem]) {
let model = SPhotoModel(allItems: im)
let view = SPhotoView(completionHandler: { saved in
self.collectionView.reloadData()
self.collectionView.collectionViewLayout.invalidateLayout()
self.dismiss(animated: true, completion: nil);
}, model: model)
let pc = UIHostingController(rootView: view)
pc.view.backgroundColor = .black
getWindow().rootViewController!.definesPresentationContext = true
pc.modalPresentationStyle = .overCurrentContext
getWindow().rootViewController!.present(pc, animated: true)
}
func showPhotos2(_ im: [MediaItem]) {
let pc = MediaPhotoController()
pc.items = im

17
kplayer/detail/DetailViewController.swift

@ -240,14 +240,19 @@ class DetailViewController: UIViewController, UICollectionViewDelegateFlowLayout
let items = detail.children[indexPath!.section]
if (items.loaded) {
if items.children.count == 0 {
} else {
if indexPath!.item >= items.children.count {
if (items.root == "/tags") {
//
}
else {
if items.children.count == 0 {
} else {
let c = items.children.remove(at: indexPath!.item)
if indexPath!.item >= items.children.count {
} else {
let c = items.children.remove(at: indexPath!.item)
self.delegate!.deleteThumb(selectedItem: c)
self.collectionView.reloadData()
self.delegate!.deleteThumb(selectedItem: c)
self.collectionView.reloadData()
}
}
}
}

11
kplayer/detail/EditItemView.swift

@ -11,6 +11,7 @@ protocol EditItemDelegate {
func setStart()
func setEnd()
func cancelEdit()
func okEdit()
func seek(_ : Double)
}
@ -72,22 +73,26 @@ struct EditItemView: View {
HStack {
Button(action: delegate.captureZoom, label: {
Text("Zoom")
}).padding(10).buttonStyle(BorderlessButtonStyle());
}).padding(5).buttonStyle(BorderlessButtonStyle());
Button(action: {
item.scale = 1.0
item.offset = CGPoint(x: 0,y: 0)
item.objectWillChange.send()
}, label: {
Text("Reset")
}).padding(10).buttonStyle(BorderlessButtonStyle());
}).padding(5).buttonStyle(BorderlessButtonStyle());
Stepper(value:$item.rating, in: -1...5){
Text("*\(item.rating)").frame(width: 25)
}
Button(action: {
delegate.okEdit()
}, label: {
Text("ok")
}).padding(5).buttonStyle(BorderlessButtonStyle());Button(action: {
delegate.cancelEdit()
}, label: {
Text("cancel")
}).padding(10).buttonStyle(BorderlessButtonStyle());
}).padding(5).buttonStyle(BorderlessButtonStyle());
}
FlexibleView(
data: DatabaseManager.sharedInstance.allTags,

15
kplayer/photo/SPhotoModel.swift

@ -0,0 +1,15 @@
//
// Created by Marco Schmickler on 22.06.22.
// Copyright (c) 2022 Marco Schmickler. All rights reserved.
//
import Foundation
class SPhotoModel : ObservableObject {
@Published var allItems : [MediaItem]
@Published var index = 0
init(allItems: [MediaItem]) {
self.allItems = allItems
}
}

46
kplayer/photo/SPhotoView.swift

@ -0,0 +1,46 @@
//
// Created by Marco Schmickler on 22.06.22.
// Copyright (c) 2022 Marco Schmickler. All rights reserved.
//
import Foundation
import SwiftUI
struct SPhotoView : View {
var completionHandler: ((Bool) -> Void)?
var model: SPhotoModel
var body: some View {
VStack {
HStack {
Group {
Button(action: {
completionHandler!(true)
}, label: {
Text("cancel")
})
.buttonStyle(BorderlessButtonStyle())
}
}.frame(height: 50)
AsyncImage(item: model.allItems[model.index], thumb: false, placeholder: { Text("Loading ...") },
image: { Image(uiImage: $0).resizable() })
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(model.allItems) { item in
Button(action: {
gotoSnapshot(item)
}) {
AsyncImage(item: item, placeholder: { Text("Loading ...") },
image: { Image(uiImage: $0).resizable() })
}
}.frame(height: 70)
}
}
}
}
func gotoSnapshot(_ item: MediaItem) {
}
}

20
kplayer/util/AsyncImage.swift

@ -1,18 +1,22 @@
import SwiftUI
import Haneke
import Alamofire
struct AsyncImage<Placeholder: View>: View {
@StateObject private var item: MediaItem
private let placeholder: Placeholder
private let image: (UIImage) -> Image
private let thumb: Bool
init(
item: MediaItem,
thumb: Bool = true,
@ViewBuilder placeholder: () -> Placeholder,
@ViewBuilder image: @escaping (UIImage) -> Image = Image.init(uiImage:)
) {
self.placeholder = placeholder()
self.image = image
self.thumb = thumb
_item = StateObject(wrappedValue: item)
setImage(newItem: item)
@ -25,7 +29,10 @@ struct AsyncImage<Placeholder: View>: View {
private var content: some View {
Group {
if item.thumbImage != nil {
if item.image != nil {
image(item.image!)
}
else if item.thumbImage != nil {
image(item.thumbImage!)
} else {
placeholder
@ -52,5 +59,16 @@ struct AsyncImage<Placeholder: View>: View {
}
}
}
if !thumb {
let URL = Foundation.URL(string: newItem.imageUrlAbsolute)!
Shared.imageCache.fetch(URL: URL).onSuccess {
i in
newItem.image = i
newItem.thumbImage = newItem.image!.scaleToSize(66.0, height: 44.0)
}
}
}
}

14
kplayer/video/SVideoPlayer.swift

@ -28,6 +28,7 @@ struct SVideoPlayer: View, EditItemDelegate {
@State var upsidedown = false
@State var more = false
@State var tilt = false
@State var slow = false
@State var smoothTime = -1.0
@State var smoothSeekTime = -1.0
@State var timeCounter = 0
@ -197,7 +198,7 @@ struct SVideoPlayer: View, EditItemDelegate {
if model.edit && model.videoDuration != Double.nan && model.videoDuration > 0.0 {
v.overlay(EditItemView(item: model.currentSnapshot, len: model.videoDuration, delegate: self)
.frame(width: 400, alignment: .top).offset(x: 0, y: -50), alignment: .topTrailing)
.frame(width: 420, alignment: .top).offset(x: 0, y: -50), alignment: .topTrailing)
} else {
if more {
v.overlay(VStack {
@ -215,6 +216,7 @@ struct SVideoPlayer: View, EditItemDelegate {
.frame(height: 30)
.foregroundColor(tilt ? Color.yellow : Color.blue).buttonStyle(BorderlessButtonStyle())
KToggleButton(text: "slow", binding: $slow).frame(height: 30)
KToggleButton(text: "zoom", binding: $model.zoomed).frame(height: 30)
KToggleButton(text: "loop", binding: $model.loop).frame(height: 30)
// .fullScreenCover(isPresented: $model.loop) {
@ -487,8 +489,8 @@ struct SVideoPlayer: View, EditItemDelegate {
if let time = getCurrentTime() {
let dragWidth = 20.0
if !model.seeking {
if (start.y < 130) {
if model.scale > 1.0 {
if (start.y < 130 || slow) {
if model.scale > 1.0 && !slow {
return true
}
if dragged.width > dragWidth {
@ -659,6 +661,12 @@ struct SVideoPlayer: View, EditItemDelegate {
model.edit = false
}
func okEdit() {
DatabaseManager.sharedInstance.saveItemMetaData(model.currentSnapshot)
model.edit = false
model.dirty = false
}
func seek(_ v: Double) {
seekTimeSmoothly(v)
}

Loading…
Cancel
Save