Fully remove ExyteGrid and URLImage

This commit is contained in:
Aiden Vigue 2021-05-24 16:42:42 -04:00
parent b06cbfe926
commit 92acfab287
6 changed files with 219 additions and 259 deletions

View File

@ -18,7 +18,6 @@
535BAE9F2649E569005FA86D /* ItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535BAE9E2649E569005FA86D /* ItemView.swift */; };
535BAEA5264A151C005FA86D /* VLCPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535BAEA4264A151C005FA86D /* VLCPlayer.swift */; };
535BAEA7264A18AA005FA86D /* VideoPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 535BAEA6264A18AA005FA86D /* VideoPlayerView.swift */; };
53773D88265C2466000809AA /* ExyteGrid in Frameworks */ = {isa = PBXBuildFile; productRef = 53773D87265C2466000809AA /* ExyteGrid */; };
5377CBF5263B596A003A4E83 /* JellyfinPlayerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5377CBF4263B596A003A4E83 /* JellyfinPlayerApp.swift */; };
5377CBF7263B596A003A4E83 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5377CBF6263B596A003A4E83 /* ContentView.swift */; };
5377CBF9263B596B003A4E83 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5377CBF8263B596B003A4E83 /* Assets.xcassets */; };
@ -31,7 +30,6 @@
53892777263CBB000035E14B /* JellyApiTypings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53892776263CBB000035E14B /* JellyApiTypings.swift */; };
5389277A263CBFE70035E14B /* SwiftyJSON in Frameworks */ = {isa = PBXBuildFile; productRef = 53892779263CBFE70035E14B /* SwiftyJSON */; };
5389277C263CC3DB0035E14B /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5389277B263CC3DB0035E14B /* BlurHashDecode.swift */; };
53892782263CC8770035E14B /* URLImage in Frameworks */ = {isa = PBXBuildFile; productRef = 53892781263CC8770035E14B /* URLImage */; };
538CD954263E3DC100BB5AF0 /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 538CD953263E3DC100BB5AF0 /* SDWebImageSwiftUI */; };
53987CA426572C1300E7EA70 /* SeasonItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53987CA326572C1300E7EA70 /* SeasonItemView.swift */; };
53987CA626572F0700E7EA70 /* SeriesItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53987CA526572F0700E7EA70 /* SeriesItemView.swift */; };
@ -113,13 +111,11 @@
files = (
538CD954263E3DC100BB5AF0 /* SDWebImageSwiftUI in Frameworks */,
5302F82C2658B5FE00647A2E /* Dynatrace.framework in Frameworks */,
53773D88265C2466000809AA /* ExyteGrid in Frameworks */,
5338F757263B7E2E0014BF09 /* KeychainSwift in Frameworks */,
53D5E3DD264B47EE00BADDC8 /* MobileVLCKit.xcframework in Frameworks */,
5338F754263B65E10014BF09 /* SwiftyRequest in Frameworks */,
5302F82A2658791C00647A2E /* Sentry in Frameworks */,
5302F82F2658B60900647A2E /* DynatraceSessionReplay.framework in Frameworks */,
53892782263CC8770035E14B /* URLImage in Frameworks */,
53D2F74A264C69F6005792BB /* Introspect in Frameworks */,
5389277A263CBFE70035E14B /* SwiftyJSON in Frameworks */,
5338F751263B62E80014BF09 /* HidingViews in Frameworks */,
@ -223,11 +219,9 @@
5338F753263B65E10014BF09 /* SwiftyRequest */,
5338F756263B7E2E0014BF09 /* KeychainSwift */,
53892779263CBFE70035E14B /* SwiftyJSON */,
53892781263CC8770035E14B /* URLImage */,
538CD953263E3DC100BB5AF0 /* SDWebImageSwiftUI */,
53D2F749264C69F6005792BB /* Introspect */,
5302F8292658791C00647A2E /* Sentry */,
53773D87265C2466000809AA /* ExyteGrid */,
);
productName = JellyfinPlayer;
productReference = 5377CBF1263B596A003A4E83 /* JellyfinPlayer.app */;
@ -264,11 +258,9 @@
5338F752263B65E10014BF09 /* XCRemoteSwiftPackageReference "SwiftyRequest" */,
5338F755263B7E2E0014BF09 /* XCRemoteSwiftPackageReference "keychain-swift" */,
53892778263CBFE70035E14B /* XCRemoteSwiftPackageReference "SwiftyJSON" */,
53892780263CC8770035E14B /* XCRemoteSwiftPackageReference "url-image" */,
538CD952263E3DC100BB5AF0 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */,
53D2F748264C69F6005792BB /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */,
5302F8282658791C00647A2E /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
53773D86265C2466000809AA /* XCRemoteSwiftPackageReference "Grid" */,
);
productRefGroup = 5377CBF2263B596A003A4E83 /* Products */;
projectDirPath = "";
@ -579,14 +571,6 @@
minimumVersion = 19.0.0;
};
};
53773D86265C2466000809AA /* XCRemoteSwiftPackageReference "Grid" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/exyte/Grid";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 1.4.0;
};
};
53892778263CBFE70035E14B /* XCRemoteSwiftPackageReference "SwiftyJSON" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SwiftyJSON/SwiftyJSON";
@ -595,14 +579,6 @@
minimumVersion = 5.0.1;
};
};
53892780263CC8770035E14B /* XCRemoteSwiftPackageReference "url-image" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/dmytro-anokhin/url-image";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.2.5;
};
};
538CD952263E3DC100BB5AF0 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/SDWebImage/SDWebImageSwiftUI";
@ -642,21 +618,11 @@
package = 5338F755263B7E2E0014BF09 /* XCRemoteSwiftPackageReference "keychain-swift" */;
productName = KeychainSwift;
};
53773D87265C2466000809AA /* ExyteGrid */ = {
isa = XCSwiftPackageProductDependency;
package = 53773D86265C2466000809AA /* XCRemoteSwiftPackageReference "Grid" */;
productName = ExyteGrid;
};
53892779263CBFE70035E14B /* SwiftyJSON */ = {
isa = XCSwiftPackageProductDependency;
package = 53892778263CBFE70035E14B /* XCRemoteSwiftPackageReference "SwiftyJSON" */;
productName = SwiftyJSON;
};
53892781263CC8770035E14B /* URLImage */ = {
isa = XCSwiftPackageProductDependency;
package = 53892780263CC8770035E14B /* XCRemoteSwiftPackageReference "url-image" */;
productName = URLImage;
};
538CD953263E3DC100BB5AF0 /* SDWebImageSwiftUI */ = {
isa = XCSwiftPackageProductDependency;
package = 538CD952263E3DC100BB5AF0 /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */;

View File

@ -19,15 +19,6 @@
"version": "5.0.200"
}
},
{
"package": "ExyteGrid",
"repositoryURL": "https://github.com/exyte/Grid",
"state": {
"branch": null,
"revision": "585dc249126fda6ae675d78175b0c52a311f10c9",
"version": "1.4.0"
}
},
{
"package": "HidingViews",
"repositoryURL": "https://github.com/GeorgeElsham/HidingViews",
@ -144,15 +135,6 @@
"revision": "2c543777a5088bed811503a68551a4b4eceac198",
"version": "3.2.200"
}
},
{
"package": "URLImage",
"repositoryURL": "https://github.com/dmytro-anokhin/url-image",
"state": {
"branch": null,
"revision": "ccab89ad1cedb04f25dd4df1776dd8c8583b914a",
"version": "2.2.5"
}
}
]
},

View File

@ -8,7 +8,6 @@
import SwiftUI
import SwiftyJSON
import SwiftyRequest
import ExyteGrid
import SDWebImageSwiftUI
struct LibrarySearchView: View {
@ -30,6 +29,7 @@ struct LibrarySearchView: View {
};
func onAppear() {
recalcTracks()
_isLoading.wrappedValue = true;
_items.wrappedValue = [];
let request = RestRequest(method: .get, url: (globalData.server?.baseURI ?? "") + _url.wrappedValue + "&searchTerm=" + searchQuery.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + (_url.wrappedValue.contains("SortBy") ? "" : "&SortBy=Name&SortOrder=Descending"))
@ -99,10 +99,17 @@ struct LibrarySearchView: View {
return result
}
var tracks: [GridTrack] {
self.isPortrait ? 3 : 6
func recalcTracks() {
let trkCnt: Int = Int(floor(UIScreen.main.bounds.size.width / 125));
_tracks.wrappedValue = []
for _ in (0..<trkCnt)
{
_tracks.wrappedValue.append(GridItem.init(.flexible()))
}
}
@State private var tracks: [GridItem] = []
var body: some View {
VStack() {
NavigationLink(destination: ItemView(item: linkedItem), isActive: $open) {
@ -118,70 +125,70 @@ struct LibrarySearchView: View {
.foregroundColor(Color.secondary)
.textFieldStyle(RoundedBorderTextFieldStyle())
LoadingView(isShowing: $isLoading) {
GeometryReader { geometry in
Grid(tracks: self.tracks, spacing: GridSpacing(horizontal: 0, vertical: 20)) {
ForEach(items, id: \.Id) { item in
Button() {
_linkedItem.wrappedValue = item;
_close.wrappedValue = false;
_open.wrappedValue = true;
} label: {
VStack(alignment: .leading) {
if(item.Type == "Movie") {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}
.frame(width:100, height: 150)
.cornerRadius(10)
.shadow(radius: 5)
} else {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}
.frame(width:100, height: 150)
.cornerRadius(10).overlay(
ZStack {
if(item.ItemBadge == 0) {
Image(systemName: "checkmark")
.font(.caption)
.padding(3)
.foregroundColor(.white)
} else {
Text("\(String(item.ItemBadge ?? 0))")
.font(.caption)
.padding(3)
.foregroundColor(.white)
}
}.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
.padding(3), alignment: .topTrailing
)
.shadow(radius: 5)
}
Text(item.Name)
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(1)
Text(String(item.ProductionYear))
.foregroundColor(.secondary)
.font(.caption)
.fontWeight(.medium)
}.frame(width: 100)
}
LazyVGrid(columns: tracks) {
ForEach(items, id: \.Id) { item in
Button() {
_linkedItem.wrappedValue = item;
_close.wrappedValue = false;
_open.wrappedValue = true;
} label: {
VStack(alignment: .leading) {
if(item.Type == "Movie") {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}
.frame(width:100, height: 150)
.cornerRadius(10)
.shadow(radius: 5)
} else {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?fillWidth=300&fillHeight=450&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}
.frame(width:100, height: 150)
.cornerRadius(10).overlay(
ZStack {
if(item.ItemBadge == 0) {
Image(systemName: "checkmark")
.font(.caption)
.padding(3)
.foregroundColor(.white)
} else {
Text("\(String(item.ItemBadge ?? 0))")
.font(.caption)
.padding(3)
.foregroundColor(.white)
}
}.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
.padding(3), alignment: .topTrailing
)
.shadow(radius: 5)
}
Text(item.Name)
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(1)
Text(String(item.ProductionYear))
.foregroundColor(.secondary)
.font(.caption)
.fontWeight(.medium)
}.frame(width: 100)
}
}.gridContentMode(.scroll)
}
}.onChange(of: isPortrait) { ip in
recalcTracks()
}
}
}.onAppear(perform: onAppear)

View File

@ -8,9 +8,7 @@
import SwiftUI
import SwiftyRequest
import SwiftyJSON
import ExyteGrid
import SDWebImageSwiftUI
import URLImage
struct LibraryView: View {
@Environment(\.managedObjectContext) private var viewContext

View File

@ -8,7 +8,6 @@
import SwiftUI
import SwiftyRequest
import SwiftyJSON
import ExyteGrid
import SDWebImageSwiftUI
struct SeriesItemView: View {
@ -18,6 +17,7 @@ struct SeriesItemView: View {
@State private var items: [ResumeItem] = [];
@State private var hasAppearedOnce: Bool = false;
func onAppear() {
recalcTracks()
if(hasAppearedOnce) {
return;
}
@ -78,61 +78,68 @@ struct SeriesItemView: View {
return result
}
var tracks: [GridTrack] {
self.isPortrait ? 3 : 6
func recalcTracks() {
let trkCnt: Int = Int(floor(UIScreen.main.bounds.size.width / 125));
_tracks.wrappedValue = []
for _ in (0..<trkCnt)
{
_tracks.wrappedValue.append(GridItem.init(.flexible()))
}
}
@State private var tracks: [GridItem] = []
var body: some View {
LoadingView(isShowing: $isLoading) {
GeometryReader { geometry in
Grid(tracks: tracks, spacing: GridSpacing(horizontal: 0, vertical: 20)) {
ForEach(items, id: \.Id) { item in
NavigationLink(destination: ItemView(item: item )) {
VStack(alignment: .leading) {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=250&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}.overlay(
ZStack {
if(item.ItemBadge == 0) {
Image(systemName: "checkmark")
.font(.caption)
.padding(3)
.foregroundColor(.white)
} else {
Text("\(String(item.ItemBadge ?? 0))")
.font(.caption)
.padding(3)
.foregroundColor(.white)
}
}.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
.padding(3), alignment: .topTrailing
)
.frame(width:100, height: 150)
.cornerRadius(10)
.shadow(radius: 5)
Text(item.Name)
LazyVGrid(columns: tracks) {
ForEach(items, id: \.Id) { item in
NavigationLink(destination: ItemView(item: item )) {
VStack(alignment: .leading) {
WebImage(url: URL(string: "\(globalData.server?.baseURI ?? "")/Items/\(item.Id)/Images/\(item.ImageType)?maxWidth=250&quality=90&tag=\(item.Image)"))
.resizable()
.placeholder {
Image(uiImage: UIImage(blurHash: (item.BlurHash == "" ? "W$H.4}D%bdo#a#xbtpxVW?W?jXWsXVt7Rjf5axWqxbWXnhada{s-" : item.BlurHash), size: CGSize(width: 32, height: 32))!)
.resizable()
.frame(width: 100, height: 150)
.cornerRadius(10)
}.overlay(
ZStack {
if(item.ItemBadge == 0) {
Image(systemName: "checkmark")
.font(.caption)
.padding(3)
.foregroundColor(.white)
} else {
Text("\(String(item.ItemBadge ?? 0))")
.font(.caption)
.padding(3)
.foregroundColor(.white)
}
}.background(Color.black)
.opacity(0.8)
.cornerRadius(10.0)
.padding(3), alignment: .topTrailing
)
.frame(width:100, height: 150)
.cornerRadius(10)
.shadow(radius: 5)
Text(item.Name)
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(1)
if(item.ProductionYear != 0) {
Text(String(item.ProductionYear))
.foregroundColor(.secondary)
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.primary)
.lineLimit(1)
if(item.ProductionYear != 0) {
Text(String(item.ProductionYear))
.foregroundColor(.secondary)
.font(.caption)
.fontWeight(.medium)
}
}.frame(width: 100)
}
.fontWeight(.medium)
}
}.frame(width: 100)
}
Spacer().frame(height: 2).gridSpan(column: isPortrait ? 3 : 6)
}.gridContentMode(.scroll)
}
Spacer().frame(height: 2)
}.onChange(of: isPortrait) { ip in
recalcTracks()
}
}
.overrideViewPreference(.unspecified)

View File

@ -368,100 +368,100 @@ struct VideoPlayerView: View {
var body: some View {
LoadingView(isShowing: ($streamLoading)) {
ZStack() {
VLCPlayer(url: $pbitem, player: $vlcplayer, startTime: Int(item.Progress)).onDisappear(perform: {
_isPlaying.wrappedValue = false;
vlcplayer.stop()
})
VStack() {
VLCPlayer(url: $pbitem, player: $vlcplayer, startTime: Int(item.Progress)).onDisappear(perform: {
_isPlaying.wrappedValue = false;
vlcplayer.stop()
})
}.overlay(
VStack() {
HStack() {
HStack() {
HStack() {
Button() {
sendStopReport()
self.playing.wrappedValue = false;
} label: {
HStack() {
Image(systemName: "chevron.left").font(.system(size: 20)).foregroundColor(.white)
}
}.frame(width: 20)
Spacer()
Text(item.Name).font(.headline).fontWeight(.semibold).foregroundColor(.white).offset(x:-4)
Spacer()
Button() {
vlcplayer.pause()
self.captionConfiguration = true;
} label: {
HStack() {
Image(systemName: "captions.bubble").font(.system(size: 20)).foregroundColor(.white)
}
}.frame(width: 20)
Button() {
sendStopReport()
self.playing.wrappedValue = false;
} label: {
HStack() {
Image(systemName: "chevron.left").font(.system(size: 20)).foregroundColor(.white)
}
}.frame(width: 20)
Spacer()
Text(item.Name).font(.headline).fontWeight(.semibold).foregroundColor(.white).offset(x:-4)
Spacer()
Button() {
vlcplayer.pause()
self.captionConfiguration = true;
} label: {
HStack() {
Image(systemName: "captions.bubble").font(.system(size: 20)).foregroundColor(.white)
}
}.frame(width: 20)
}
Spacer()
}.padding(EdgeInsets(top: 55, leading: 40, bottom: 0, trailing: 40))
Spacer()
HStack() {
Spacer()
Button() {
vlcplayer.jumpBackward(15)
} label: {
Image(systemName: "gobackward.15").font(.system(size: 40)).foregroundColor(.white)
}.padding(20)
Spacer()
Button() {
if(vlcplayer.state != VLCMediaPlayerState.paused) {
vlcplayer.pause()
playPauseButtonSystemName = "play"
sendProgressReport(eventName: "pause")
} else {
vlcplayer.play()
playPauseButtonSystemName = "pause"
sendProgressReport(eventName: "unpause")
}
Spacer()
}.padding(EdgeInsets(top: 55, leading: 40, bottom: 0, trailing: 40))
} label: {
Image(systemName: playPauseButtonSystemName).font(.system(size: 55)).foregroundColor(.white)
}.padding(20)
Spacer()
HStack() {
Spacer()
Button() {
vlcplayer.jumpBackward(15)
} label: {
Image(systemName: "gobackward.15").font(.system(size: 40)).foregroundColor(.white)
}.padding(20)
Spacer()
Button() {
if(vlcplayer.state != VLCMediaPlayerState.paused) {
vlcplayer.pause()
playPauseButtonSystemName = "play"
sendProgressReport(eventName: "pause")
} else {
vlcplayer.play()
playPauseButtonSystemName = "pause"
sendProgressReport(eventName: "unpause")
}
} label: {
Image(systemName: playPauseButtonSystemName).font(.system(size: 55)).foregroundColor(.white)
}.padding(20)
Spacer()
Button() {
vlcplayer.jumpForward(15)
} label: {
Image(systemName: "goforward.15").font(.system(size: 40)).foregroundColor(.white)
}.padding(20)
Spacer()
}.padding(.leading, -20)
Button() {
vlcplayer.jumpForward(15)
} label: {
Image(systemName: "goforward.15").font(.system(size: 40)).foregroundColor(.white)
}.padding(20)
Spacer()
HStack() {
Slider(value: $scrub, onEditingChanged: { bool in
let videoPosition = Double(vlcplayer.time.intValue)
let videoDuration = Double(vlcplayer.time.intValue + abs(vlcplayer.remainingTime.intValue))
if(bool == true) {
vlcplayer.pause()
sendProgressReport(eventName: "pause")
DispatchQueue.global(qos: .utility).async { [self] in
self.processScrubbingState()
}
} else {
//Scrub is value from 0..1 - find position in video and add / or remove.
let secondsScrubbedTo = round(_scrub.wrappedValue * videoDuration);
let offset = secondsScrubbedTo - videoPosition;
sendProgressReport(eventName: "unpause")
vlcplayer.play()
if(offset > 0) {
vlcplayer.jumpForward(Int32(offset)/1000);
} else {
vlcplayer.jumpBackward(Int32(abs(offset))/1000);
}
}.padding(.leading, -20)
Spacer()
HStack() {
Slider(value: $scrub, onEditingChanged: { bool in
let videoPosition = Double(vlcplayer.time.intValue)
let videoDuration = Double(vlcplayer.time.intValue + abs(vlcplayer.remainingTime.intValue))
if(bool == true) {
vlcplayer.pause()
sendProgressReport(eventName: "pause")
DispatchQueue.global(qos: .utility).async { [self] in
self.processScrubbingState()
}
})
.accentColor(Color(red: 172/255, green: 92/255, blue: 195/255))
Text(timeText).fontWeight(.semibold).frame(width: 80).foregroundColor(.white)
}.padding(EdgeInsets(top: -20, leading: 44, bottom: 42, trailing: 40))
}
.padding(EdgeInsets(top: 0, leading: UIDevice.current.hasNotch ? -30 : 0, bottom: 0, trailing: UIDevice.current.hasNotch ? -30 : 0))
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.black).opacity(0.4))
.isHidden(inactivity)
}.padding(EdgeInsets(top: 0, leading: UIDevice.current.hasNotch ? 34 : 0, bottom: 0, trailing: UIDevice.current.hasNotch ? 34 : 0))
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
} else {
//Scrub is value from 0..1 - find position in video and add / or remove.
let secondsScrubbedTo = round(_scrub.wrappedValue * videoDuration);
let offset = secondsScrubbedTo - videoPosition;
sendProgressReport(eventName: "unpause")
vlcplayer.play()
if(offset > 0) {
vlcplayer.jumpForward(Int32(offset)/1000);
} else {
vlcplayer.jumpBackward(Int32(abs(offset))/1000);
}
}
})
.accentColor(Color(red: 172/255, green: 92/255, blue: 195/255))
Text(timeText).fontWeight(.semibold).frame(width: 80).foregroundColor(.white)
}.padding(EdgeInsets(top: -20, leading: 44, bottom: 42, trailing: 40))
}
.padding(EdgeInsets(top: 0, leading: UIDevice.current.hasNotch ? -30 : 0, bottom: 0, trailing: UIDevice.current.hasNotch ? -30 : 0))
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.black).opacity(0.4))
.isHidden(inactivity)
, alignment: .topLeading)
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.onAppear(perform: startStream)
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)