Skip to content

Commit

Permalink
Merge pull request #170 from kishikawakatsumi/examples
Browse files Browse the repository at this point in the history
Update example apps
  • Loading branch information
kishikawakatsumi authored Nov 29, 2024
2 parents 8a2ed05 + 78b0170 commit d35507d
Show file tree
Hide file tree
Showing 20 changed files with 230 additions and 704 deletions.
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

0 comments on commit d35507d

Please sign in to comment.