1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-12-25 23:02:35 +03:00

GH-339 Use single http server for all windows

- very ugly implementation, will refactor in the next issue
This commit is contained in:
Tae Won Ha 2017-01-13 19:03:56 +01:00
parent 12e64039e7
commit 6fb23f080c
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
4 changed files with 50 additions and 19 deletions

View File

@ -6,6 +6,7 @@
import Cocoa import Cocoa
import PureLayout import PureLayout
import RxSwift import RxSwift
import Swifter
enum MainWindowAction { enum MainWindowAction {
@ -109,6 +110,8 @@ class MainWindowComponent: WindowComponent,
fileprivate let scrollFlow: EmbeddableComponent fileprivate let scrollFlow: EmbeddableComponent
fileprivate let httpServer: HttpServer;
// MARK: - API // MARK: - API
var uuid: String { var uuid: String {
return self.neoVimView.uuid return self.neoVimView.uuid
@ -141,6 +144,7 @@ class MainWindowComponent: WindowComponent,
fileItemService: FileItemService, fileItemService: FileItemService,
cwd: URL, cwd: URL,
urls: [URL] = [], urls: [URL] = [],
httpServer: HttpServer,
initialData: PrefData) initialData: PrefData)
{ {
self.neoVimView = NeoVimView(frame: CGRect.zero, self.neoVimView = NeoVimView(frame: CGRect.zero,
@ -154,6 +158,8 @@ class MainWindowComponent: WindowComponent,
self.scrollFlow = EmbeddableComponent(source: Observable.empty()) self.scrollFlow = EmbeddableComponent(source: Observable.empty())
self.httpServer = httpServer
super.init(source: source, nibName: MainWindowComponent.nibName) super.init(source: source, nibName: MainWindowComponent.nibName)
self.window.delegate = self self.window.delegate = self
@ -213,6 +219,7 @@ class MainWindowComponent: WindowComponent,
let previewData = previewToolData.toolData as? PreviewComponent.PrefData ?? PreviewComponent.PrefData.default let previewData = previewToolData.toolData as? PreviewComponent.PrefData ?? PreviewComponent.PrefData.default
let preview = PreviewComponent(source: self.sink, let preview = PreviewComponent(source: self.sink,
scrollSource: self.scrollFlow.sink, scrollSource: self.scrollFlow.sink,
httpServer: self.httpServer,
initialData: previewData) initialData: previewData)
let previewConfig = WorkspaceTool.Config(title: "Preview", let previewConfig = WorkspaceTool.Config(title: "Preview",
view: preview, view: preview,

View File

@ -5,6 +5,7 @@
import Cocoa import Cocoa
import RxSwift import RxSwift
import Swifter
enum MainWindowManagerAction { enum MainWindowManagerAction {
@ -19,10 +20,20 @@ class MainWindowManager: StandardFlow {
fileprivate let fileItemService: FileItemService fileprivate let fileItemService: FileItemService
fileprivate var data: PrefData fileprivate var data: PrefData
fileprivate let httpServer = HttpServer() // TODO: WRONG: service-ify this!!!
init(source: Observable<Any>, fileItemService: FileItemService, initialData: PrefData) { init(source: Observable<Any>, fileItemService: FileItemService, initialData: PrefData) {
self.fileItemService = fileItemService self.fileItemService = fileItemService
self.data = initialData self.data = initialData
let port = NetUtils.openPort()
NSLog("\(#function): opening a server on port \(port)")
do {
try self.httpServer.start(port)
} catch {
NSLog("ERROR \(#function): could not start the http server on port \(port)")
}
super.init(source: source) super.init(source: source)
} }
@ -31,6 +42,7 @@ class MainWindowManager: StandardFlow {
fileItemService: self.fileItemService, fileItemService: self.fileItemService,
cwd: cwd, cwd: cwd,
urls: urls, urls: urls,
httpServer: self.httpServer,
initialData: self.data) initialData: self.data)
self.mainWindowComponents[mainWindowComponent.uuid] = mainWindowComponent self.mainWindowComponents[mainWindowComponent.uuid] = mainWindowComponent
@ -60,6 +72,10 @@ class MainWindowManager: StandardFlow {
return mainWindowComponent return mainWindowComponent
} }
deinit {
self.httpServer.stop()
}
func close(_ mainWindowComponent: MainWindowComponent, prefData: MainWindowPrefData) { func close(_ mainWindowComponent: MainWindowComponent, prefData: MainWindowPrefData) {
// Save the tools settings of the last closed main window. // Save the tools settings of the last closed main window.
// TODO: Think about a better time to save this. // TODO: Think about a better time to save this.

View File

@ -149,8 +149,8 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
fileprivate var currentPreviewPosition = Position(row: 1, column: 1) fileprivate var currentPreviewPosition = Position(row: 1, column: 1)
fileprivate let uuid = UUID().uuidString fileprivate let uuid = UUID().uuidString
fileprivate var server = HttpServer() fileprivate let httpServer: HttpServer
fileprivate let port: in_port_t fileprivate let port: Int
fileprivate let tempDir = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true) fileprivate let tempDir = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
let identifier: String = MarkdownRenderer.identifier let identifier: String = MarkdownRenderer.identifier
@ -171,7 +171,10 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
let toolbar: NSView? = NSView(forAutoLayout: ()) let toolbar: NSView? = NSView(forAutoLayout: ())
let menuItems: [NSMenuItem]? let menuItems: [NSMenuItem]?
init(source: Observable<Any>, scrollSource: Observable<Any>, initialData: PrefData) { init(source: Observable<Any>, scrollSource: Observable<Any>, httpServer: HttpServer, initialData: PrefData) {
NSLog("\(#function) \(uuid)")
NSLog("\(#function) \(self.tempDir)")
guard let templateUrl = Bundle.main.url(forResource: "template", guard let templateUrl = Bundle.main.url(forResource: "template",
withExtension: "html", withExtension: "html",
subdirectory: "markdown") subdirectory: "markdown")
@ -183,17 +186,11 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
preconditionFailure("ERROR Cannot load markdown template") preconditionFailure("ERROR Cannot load markdown template")
} }
self.server.GET["/\(MarkdownRenderer.serverPath)/github-markdown.css"] = shareFile( self.httpServer = httpServer
self.httpServer.GET["/\(MarkdownRenderer.serverPath)/\(self.uuid)/github-markdown.css"] = shareFile(
self.resourceBaesUrl.appendingPathComponent("github-markdown.css").path self.resourceBaesUrl.appendingPathComponent("github-markdown.css").path
) )
self.port = (try? httpServer.port()) ?? 0
self.port = NetUtils.openPort()
NSLog("\(#function): opening a server on port \(port)")
do {
try self.server.start(port)
} catch {
NSLog("ERROR \(#function): could not start the http server on port \(self.port)")
}
self.template = template self.template = template
@ -257,7 +254,7 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
} }
deinit { deinit {
self.server.stop() try? FileManager.default.removeItem(at: self.htmlFileUrl())
} }
func canRender(fileExtension: String) -> Bool { func canRender(fileExtension: String) -> Bool {
@ -388,7 +385,7 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
} }
let html = filledTemplate(body: body, title: url.lastPathComponent) let html = filledTemplate(body: body, title: url.lastPathComponent)
let htmlFilePath = tempDir.appendingPathComponent("\(MarkdownRenderer.identifier).\(self.uuid).html").path let htmlFilePath = self.htmlFileUrl().path
do { do {
try html.write(toFile: htmlFilePath, atomically: true, encoding: .utf8) try html.write(toFile: htmlFilePath, atomically: true, encoding: .utf8)
} catch { } catch {
@ -397,16 +394,22 @@ class MarkdownRenderer: NSObject, Flow, PreviewRenderer {
return return
} }
self.server["/\(MarkdownRenderer.serverPath)/:path"] = shareFilesFromDirectory(url.deletingLastPathComponent().path) self.httpServer["/\(MarkdownRenderer.serverPath)/\(self.uuid)/:path"] =
self.server.GET["/\(MarkdownRenderer.serverPath)/index.html"] = shareFile(htmlFilePath) shareFilesFromDirectory(url.deletingLastPathComponent().path)
self.httpServer.GET["/\(MarkdownRenderer.serverPath)/\(self.uuid)/index.html"] = shareFile(htmlFilePath)
let urlRequest = URLRequest( let urlRequest = URLRequest(
url: URL(string: "http://localhost:\(self.port)/\(MarkdownRenderer.serverPath)/index.html")! url: URL(string: "http://localhost:\(self.port)/\(MarkdownRenderer.serverPath)/\(self.uuid)/index.html")!
) )
self.webview.load(urlRequest) self.webview.load(urlRequest)
self.flow.publish(event: PreviewRendererAction.view(renderer: self, view: self.webview)) self.flow.publish(event: PreviewRendererAction.view(renderer: self, view: self.webview))
} }
fileprivate func htmlFileUrl() -> URL {
return self.tempDir.appendingPathComponent("\(MarkdownRenderer.identifier).\(self.uuid).html")
}
} }
// MARK: - Actions // MARK: - Actions

View File

@ -7,6 +7,7 @@ import Cocoa
import RxSwift import RxSwift
import PureLayout import PureLayout
import WebKit import WebKit
import Swifter
class PreviewComponent: NSView, ViewComponent, ToolDataHolder, WKNavigationDelegate { class PreviewComponent: NSView, ViewComponent, ToolDataHolder, WKNavigationDelegate {
@ -112,6 +113,8 @@ class PreviewComponent: NSView, ViewComponent, ToolDataHolder, WKNavigationDeleg
} }
} }
fileprivate let httpServer: HttpServer
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
@ -137,14 +140,16 @@ class PreviewComponent: NSView, ViewComponent, ToolDataHolder, WKNavigationDeleg
return self return self
} }
init(source: Observable<Any>, scrollSource: Observable<Any>, initialData: PrefData) { init(source: Observable<Any>, scrollSource: Observable<Any>, httpServer: HttpServer, initialData: PrefData) {
self.flow = EmbeddableComponent(source: source) self.flow = EmbeddableComponent(source: source)
self.httpServer = httpServer
self.baseUrl = self.previewService.baseUrl() self.baseUrl = self.previewService.baseUrl()
let markdownData = initialData.rendererDatas[MarkdownRenderer.identifier] as? MarkdownRenderer.PrefData ?? let markdownData = initialData.rendererDatas[MarkdownRenderer.identifier] as? MarkdownRenderer.PrefData ??
MarkdownRenderer.PrefData.default MarkdownRenderer.PrefData.default
self.markdownRenderer = MarkdownRenderer(source: self.flow.sink, self.markdownRenderer = MarkdownRenderer(source: self.flow.sink,
scrollSource: scrollSource, scrollSource: scrollSource,
httpServer: self.httpServer,
initialData: markdownData) initialData: markdownData)
self.renderers = [ self.renderers = [
@ -231,7 +236,7 @@ class PreviewComponent: NSView, ViewComponent, ToolDataHolder, WKNavigationDeleg
.throttle(1, latest: true, scheduler: self.scheduler) .throttle(1, latest: true, scheduler: self.scheduler)
.filter { $0 is PreviewRendererAction } .filter { $0 is PreviewRendererAction }
.map { $0 as! PreviewRendererAction } .map { $0 as! PreviewRendererAction }
.subscribe(onNext: { action in .subscribe(onNext: { [unowned self] action in
guard self.isOpen else { guard self.isOpen else {
return return
} }