Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update example apps #170

Merged
merged 1 commit into from
Nov 29, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import SMBClient
class DocumentViewController: UIViewController {
private let path: String
private let treeAccessor: TreeAccessor
private let fileReader: FileReader
private var fileReader: FileReader?

private let server: HTTPServer
private let port: UInt16
Expand All @@ -21,7 +21,6 @@ class DocumentViewController: UIViewController {
init(accessor: TreeAccessor, path: String) {
treeAccessor = accessor
self.path = path
fileReader = accessor.fileReader(path: path)

port = UInt16(42000)
server = HTTPServer(port: port, logger: .disabled)
Expand Down Expand Up @@ -74,13 +73,20 @@ class DocumentViewController: UIViewController {
])

let semaphore = self.semaphore
let fileReader = self.fileReader
let treeAccessor = self.treeAccessor
let path = self.path
var fileReader = self.fileReader

task = Task {
await server.appendRoute("*") { (request) in
await semaphore.wait()
defer { Task { await semaphore.signal() } }

if fileReader == nil {
fileReader = try await treeAccessor.fileReader(path: path)
}
guard let fileReader else { return HTTPResponse(statusCode: .internalServerError) }

let bufferedResponse = BufferedResponse(fileReader: fileReader)
let mimeType = mimeTypeForPath(path: request.path)

Expand Down Expand Up @@ -142,8 +148,10 @@ class DocumentViewController: UIViewController {
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)

Task {
try await fileReader.close()
if let fileReader {
Task {
try await fileReader.close()
}
}
task?.cancel()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,25 @@ import SMBClient
private let storyboardID = "DocumentWindowController"

class DocumentWindowController: NSWindowController, NSWindowDelegate {
private let treeAccessor: TreeAccessor
private let path: String
private let fileReader: FileReader
private var fileReader: FileReader?

private let server: HTTPServer
private let port: UInt16
private var task: Task<(), any Error>?
private let semaphore = Semaphore(value: 1)

static func instantiate(path: String, accessor: TreeAccessor) -> Self {
static func instantiate(accessor: TreeAccessor, path: String) -> Self {
let storyboard = NSStoryboard(name: storyboardID, bundle: nil)
return storyboard.instantiateController(identifier: storyboardID) { (coder) in
Self(coder: coder, path: path, accessor: accessor)
Self(coder: coder, accessor: accessor, path: path)
}
}

required init?(coder: NSCoder, path: String, accessor: TreeAccessor) {
required init?(coder: NSCoder, accessor: TreeAccessor, path: String) {
treeAccessor = accessor
self.path = path
fileReader = accessor.fileReader(path: path)

port = UInt16(42000 + NSApp.windows.count)
server = HTTPServer(port: port, logger: .disabled)
Expand All @@ -43,13 +44,20 @@ class DocumentWindowController: NSWindowController, NSWindowDelegate {
window?.delegate = self

let semaphore = self.semaphore
let fileReader = self.fileReader
let treeAccessor = self.treeAccessor
let path = self.path
var fileReader = self.fileReader

task = Task {
await server.appendRoute("*") { (request) in
await semaphore.wait()
defer { Task { await semaphore.signal() } }

if fileReader == nil {
fileReader = try await treeAccessor.fileReader(path: path)
}
guard let fileReader else { return HTTPResponse(statusCode: .internalServerError) }

let bufferedResponse = BufferedResponse(fileReader: fileReader)
let mimeType = mimeTypeForPath(path: request.path)

Expand Down Expand Up @@ -99,7 +107,7 @@ class DocumentWindowController: NSWindowController, NSWindowDelegate {
)
}

try await server.start()
try await server.run()
}

Task { @MainActor in
Expand All @@ -111,8 +119,10 @@ class DocumentWindowController: NSWindowController, NSWindowDelegate {
}

func windowWillClose(_ notification: Notification) {
Task {
try await fileReader.close()
if let fileReader {
Task {
try await fileReader.close()
}
}
task?.cancel()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class FilesViewController: NSViewController {
}()
Task {
do {
try await treeAccessor.createDirectory(share: share, path: join(path, filename))
try await treeAccessor.createDirectory(path: join(path, filename))
try await dirTree.reload(directory: path, outlineView)
updateItemCount()
} catch {
Expand Down Expand Up @@ -290,7 +290,7 @@ class FilesViewController: NSViewController {
windowController = MediaPlayerWindowController.instantiate(path: path, accessor: treeAccessor)
windowController.showWindow(nil)
} else {
windowController = DocumentWindowController.instantiate(path: path, accessor: treeAccessor)
windowController = DocumentWindowController.instantiate(accessor: treeAccessor, path: path)
windowController.showWindow(nil)
}
}
Expand Down Expand Up @@ -340,9 +340,9 @@ class FilesViewController: NSViewController {
let path = fileNode.path

if fileNode.isDirectory {
try await treeAccessor.deleteDirectory(share: share, path: path)
try await treeAccessor.deleteDirectory(path: path)
} else {
try await treeAccessor.deleteFile(share: share, path: path)
try await treeAccessor.deleteFile(path: path)
}

reloadPaths.insert(dirname(path))
Expand Down Expand Up @@ -525,7 +525,7 @@ extension FilesViewController: NSOutlineViewDataSource {

func moveFile(from: String, to: String) async {
do {
try await treeAccessor.move(share: share, from: from, to: to)
try await treeAccessor.move(from: from, to: to)

try await dirTree.reload(directory: dirname(from), outlineView)
try await dirTree.reload(directory: dirname(to), outlineView)
Expand Down Expand Up @@ -716,7 +716,7 @@ extension FilesViewController: NSTextFieldDelegate {

Task { @MainActor in
do {
try await treeAccessor.rename(share: share, from: node.path, to: join(dirname(node.path), textField.stringValue))
try await treeAccessor.rename(from: node.path, to: join(dirname(node.path), textField.stringValue))
try await dirTree.reload(directory: dirname(node.path), outlineView)
} catch {
textField.stringValue = node.name
Expand Down
31 changes: 30 additions & 1 deletion Examples/FileBrowser/FileBrowser (visionOS)/FileBrowserApp.swift
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import SwiftUI
import SMBClient
import Translation

@main
struct FileBrowserApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
@UIApplicationDelegateAdaptor(AppDelegate.self)
private var appDelegate
@State
private var sessionManager = SessionManager()

var body: some Scene {
WindowGroup {
FileBrowserView()
}
.environment(\.sessionManager, sessionManager)

WindowGroup("Video Player", id: "videoPlayer", for: SessionContext.self) { ($context) in
if let context, let client = sessionManager.sessions[ID(context.domain)] {
VideoPlayerView(client: client, sessionContext: context)
}
}
.environment(\.sessionManager, sessionManager)
}
}

Expand All @@ -20,3 +33,19 @@ class AppDelegate: NSObject, UIApplicationDelegate {
return true
}
}


@Observable
class SessionManager {
var sessions = [ID: SMBClient]()
}

extension EnvironmentValues {
@Entry var sessionManager = SessionManager()
}

struct SessionContext: Hashable, Codable {
let domain: String
let share: String
let path: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ struct FileBrowserView: View {
private var services = [Service]()
@State
private var selection: Service?
@State
private var sessions = [ID: SMBClient]()
// @State
// private var sessions = [ID: SMBClient]()
@State
private var showingLoginSheet: Bool = false

@Environment(\.sessionManager) var sessionManager: SessionManager

let publisher = NotificationCenter.default.publisher(for: ServiceDiscovery.serviceDidDiscover)

var body: some View {
Expand All @@ -22,7 +24,7 @@ struct FileBrowserView: View {
}
}
.onChange(of: selection, initial: false) { (oldValue, newValue) in
if let selection, sessions[selection.id] == nil {
if let selection, sessionManager.sessions[selection.id] == nil {
showingLoginSheet = true
}
}
Expand All @@ -32,8 +34,8 @@ struct FileBrowserView: View {
.navigationTitle("Services")
} detail: {
if let selection {
if let client = sessions[selection.id] {
SharesView(client: client)
if let client = sessionManager.sessions[selection.id] {
SharesView(domain: selection.id.rawValue, client: client)
.id(selection)
}
}
Expand Down Expand Up @@ -71,7 +73,7 @@ struct FileBrowserView: View {
let store = CredentialStore.shared
store.save(server: server, securityDomain: securityDomain, username: username, password: password)

sessions[ID(securityDomain)] = client
sessionManager.sessions[ID(securityDomain)] = client
}
}

Expand Down
24 changes: 17 additions & 7 deletions Examples/FileBrowser/FileBrowser (visionOS)/FilesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ struct FilesView: View {
@State private var isLoading = false
@State private var errorMessage: String?

@Environment(\.openWindow) private var openWindow

private let domain: String
private let treeAccessor: TreeAccessor
private let path: String

init(accessor: TreeAccessor, path: String) {
init(domain: String, accessor: TreeAccessor, path: String) {
self.domain = domain
treeAccessor = accessor
self.path = path
}
Expand All @@ -34,18 +38,24 @@ struct FilesView: View {
Label(file.name, systemImage: file.isDirectory ? "folder" : "doc")
}
}
.navigationDestination(for: Route.self) { (route) in
if route.isDirectory {
FilesView(accessor: treeAccessor, path: route.path)
} else {
let path = URL(fileURLWithPath: route.path)
.onChange(of: selection, initial: false) { (oldValue, newValue) in
if let selection {
let subpath = path.isEmpty ? selection.name : "\(path)/\(selection.name)"
let path = URL(fileURLWithPath: subpath)
if VideoPlayerView.supportedExtensions.contains(path.pathExtension) {
VideoPlayerView(accessor: treeAccessor, path: route.path)
openWindow(id: "videoPlayer", value: SessionContext(domain: domain, share: treeAccessor.share, path: subpath))
} else {

}
}
}
.navigationDestination(for: Route.self) { (route) in
if route.isDirectory {
FilesView(domain: domain, accessor: treeAccessor, path: route.path)
} else {

}
}
.foregroundStyle(.primary)
}
}
Expand Down
9 changes: 5 additions & 4 deletions Examples/FileBrowser/FileBrowser (visionOS)/SharesView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ struct SharesView: View {
@State private var isLoading = false
@State private var errorMessage: String?

private let domain: String
private let client: SMBClient
private var host: String
private let id = UUID()
private let host: String

init(client: SMBClient) {
init(domain: String, client: SMBClient) {
self.domain = domain
self.client = client
host = client.host
}
Expand All @@ -31,7 +32,7 @@ struct SharesView: View {
}
}
.navigationDestination(for: String.self) { (share) in
FilesView(accessor: client.treeAccessor(share: share), path: "")
FilesView(domain: domain, accessor: client.treeAccessor(share: share), path: "")
}
}
.foregroundStyle(.primary)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ struct VideoPlayerView: View {
private let player: AVPlayer
private let treeAccessor: TreeAccessor

init(accessor: TreeAccessor, path: String) {
treeAccessor = accessor
player = AVPlayer(playerItem: AVPlayerItem(asset: SMBAVAsset(accessor: accessor, path: path)))
init(client: SMBClient, sessionContext: SessionContext) {
treeAccessor = client.treeAccessor(share: sessionContext.share)
player = AVPlayer(playerItem: AVPlayerItem(asset: SMBAVAsset(accessor: treeAccessor, path: sessionContext.path)))
}

var body: some View {
Expand Down
Loading
Loading