diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 229e011..ebb8da7 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -58,7 +58,7 @@ DE4408052A923EC00091937A /* QuitButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408042A923EC00091937A /* QuitButtonView.swift */; }; DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408072A9240300091937A /* BoxFunctionButtonView.swift */; }; DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */; }; - DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */; }; + DE4408152A92750D0091937A /* keyDown+Appdelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE4408142A92750D0091937A /* keyDown+Appdelegate.swift */; }; DE44081D2A928F760091937A /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE44081C2A928F760091937A /* Divider.swift */; }; DE62BE5A2A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */; }; DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */; }; @@ -120,6 +120,10 @@ DEB862EB2A853F7F00278FCD /* BoxWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEB862E92A853F7F00278FCD /* BoxWindowController.swift */; }; DEE0FA962A9A554F00085A65 /* FunctionButtonUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */; }; DEF0761B2AA33671005700E5 /* DeleteUserMeScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF0761A2AA33671005700E5 /* DeleteUserMeScript.swift */; }; + DEF076262AA3B0C1005700E5 /* QuickSlotItemButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF076252AA3B0C1005700E5 /* QuickSlotItemButton.swift */; }; + DEF0762A2AA3B955005700E5 /* PutUserMeQuickSlot.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF076292AA3B955005700E5 /* PutUserMeQuickSlot.swift */; }; + DEF0762D2AA3C34C005700E5 /* GetUserMeQuickSlot.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF0762C2AA3C34C005700E5 /* GetUserMeQuickSlot.swift */; }; + DEF076302AA3CF8A005700E5 /* QuickSlotItemLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF0762F2AA3CF8A005700E5 /* QuickSlotItemLabel.swift */; }; DEF749322A85657600D987C8 /* NSScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF749312A85657600D987C8 /* NSScreen.swift */; }; /* End PBXBuildFile section */ @@ -178,7 +182,7 @@ DE4408042A923EC00091937A /* QuitButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuitButtonView.swift; sourceTree = ""; }; DE4408072A9240300091937A /* BoxFunctionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxFunctionButtonView.swift; sourceTree = ""; }; DE44080B2A924B520091937A /* BoxFunctionViewGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxFunctionViewGroup.swift; sourceTree = ""; }; - DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "keyDown+BoxBaseContainerViewController.swift"; path = "Main/keyDown+BoxBaseContainerViewController.swift"; sourceTree = ""; }; + DE4408142A92750D0091937A /* keyDown+Appdelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "keyDown+Appdelegate.swift"; sourceTree = ""; }; DE44081C2A928F760091937A /* Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Divider.swift; sourceTree = ""; }; DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonCollectionViewController.swift; sourceTree = ""; }; DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickSlotButtonCollectionViewController.xib; sourceTree = ""; }; @@ -239,6 +243,10 @@ DEB862E92A853F7F00278FCD /* BoxWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxWindowController.swift; sourceTree = ""; }; DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionButtonUI.swift; sourceTree = ""; }; DEF0761A2AA33671005700E5 /* DeleteUserMeScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteUserMeScript.swift; sourceTree = ""; }; + DEF076252AA3B0C1005700E5 /* QuickSlotItemButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotItemButton.swift; sourceTree = ""; }; + DEF076292AA3B955005700E5 /* PutUserMeQuickSlot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PutUserMeQuickSlot.swift; sourceTree = ""; }; + DEF0762C2AA3C34C005700E5 /* GetUserMeQuickSlot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetUserMeQuickSlot.swift; sourceTree = ""; }; + DEF0762F2AA3CF8A005700E5 /* QuickSlotItemLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotItemLabel.swift; sourceTree = ""; }; DEF7492E2A85603700D987C8 /* nodeInstall.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = nodeInstall.sh; sourceTree = ""; }; DEF749312A85657600D987C8 /* NSScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSScreen.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -386,7 +394,6 @@ DE0A916B2A8E7DC700D1D6F1 /* UI */, DE4408202A9297EE0091937A /* View */, DE1F1A192A8B50C500A88DD8 /* BoxBaseContainerViewController.swift */, - DE4408142A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift */, DEB862E92A853F7F00278FCD /* BoxWindowController.swift */, ); name = Main; @@ -464,6 +471,8 @@ DE9457272A9F6E4400B0B768 /* GetUserMeScripts.swift */, DE94572B2A9F75D500B0B768 /* API.swift */, DEF0761A2AA33671005700E5 /* DeleteUserMeScript.swift */, + DEF076292AA3B955005700E5 /* PutUserMeQuickSlot.swift */, + DEF0762C2AA3C34C005700E5 /* GetUserMeQuickSlot.swift */, ); path = API; sourceTree = ""; @@ -552,6 +561,8 @@ children = ( DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */, DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */, + DEF076252AA3B0C1005700E5 /* QuickSlotItemButton.swift */, + DEF0762F2AA3CF8A005700E5 /* QuickSlotItemLabel.swift */, ); path = "Vertical Item"; sourceTree = ""; @@ -750,6 +761,7 @@ DE98E83A2A98DB6000F8744A /* RotateImage+NSImage.swift */, DE97CA682A9A6364001073DE /* PixelConversion+CGFloat.swift */, DE94571B2A9EFB7800B0B768 /* Associated+NSButton.swift */, + DE4408142A92750D0091937A /* keyDown+Appdelegate.swift */, ); path = Extensions; sourceTree = ""; @@ -842,6 +854,7 @@ DE018BB82A5099F900FF0AA3 /* Box42.xcdatamodeld in Sources */, DEF0761B2AA33671005700E5 /* DeleteUserMeScript.swift in Sources */, DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */, + DEF076302AA3CF8A005700E5 /* QuickSlotItemLabel.swift in Sources */, DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */, DE98E83B2A98DB6000F8744A /* RotateImage+NSImage.swift in Sources */, DE0A91982A8F977F00D1D6F1 /* ToolbarViewController.swift in Sources */, @@ -872,6 +885,7 @@ DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */, DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */, DE97CA7C2A9A7199001073DE /* QuickSlotGroupView.swift in Sources */, + DEF0762A2AA3B955005700E5 /* PutUserMeQuickSlot.swift in Sources */, DE018BE42A509B1700FF0AA3 /* CPU.swift in Sources */, DE77BBA22A9DDC40006CC98B /* ScriptsFileManager.swift in Sources */, DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */, @@ -914,7 +928,7 @@ DE94570C2A9E69EB00B0B768 /* ScriptExcuteButton.swift in Sources */, DE9457162A9E6D3000B0B768 /* ScriptQuickSlotButton.swift in Sources */, DE97CA7F2A9A73A9001073DE /* QuickSlotUI.swift in Sources */, - DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */, + DE4408152A92750D0091937A /* keyDown+Appdelegate.swift in Sources */, DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */, DE97CA692A9A6364001073DE /* PixelConversion+CGFloat.swift in Sources */, DE7886282A9D186700FE21DD /* ScriptsViewController.swift in Sources */, @@ -934,10 +948,12 @@ DE24E6382A8FE10400E29F5D /* BoxBaseSplitView.swift in Sources */, DE44081D2A928F760091937A /* Divider.swift in Sources */, DE98E8432A98DDFD00F8744A /* QuickSlotViewController.swift in Sources */, + DEF0762D2AA3C34C005700E5 /* GetUserMeQuickSlot.swift in Sources */, DE94574B2AA0A70500B0B768 /* NetworkView.swift in Sources */, DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */, DE3FF36B2A978A57009C88EF /* WindowButtonViewController.swift in Sources */, DE1F1A312A8BD68F00A88DD8 /* Double.swift in Sources */, + DEF076262AA3B0C1005700E5 /* QuickSlotItemButton.swift in Sources */, DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */, DE018BEA2A509B2100FF0AA3 /* WebViewModel.swift in Sources */, ); diff --git a/Box42/Extensions/keyDown+Appdelegate.swift b/Box42/Extensions/keyDown+Appdelegate.swift new file mode 100644 index 0000000..75bf2e4 --- /dev/null +++ b/Box42/Extensions/keyDown+Appdelegate.swift @@ -0,0 +1,105 @@ +// +// keyDown+AppDelegate.swift +// Box42 +// +// Created by Chanhee Kim on 8/21/23. +// + +import AppKit + +extension AppDelegate { + func eventMonitoring() { + NSEvent.addLocalMonitorForEvents(matching: .keyUp) { (event) -> NSEvent? in + print("Key Up: \(event.keyCode)") + + if event.modifierFlags.contains(.control) { + switch event.keyCode { + case 12: // 'Q' 키의 keyCode + print("Control + Q pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(0) + case 13: // 'W' 키의 keyCode + print("Control + W pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(2) + case 14: // 'E' 키의 keyCode + print("Control + E pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(4) + case 15: // 'R' 키의 keyCode + print("Control + R pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(6) + case 0: // 'A' 키의 keyCode + print("Control + A pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(1) + case 1: // 'S' 키의 keyCode + print("Control + S pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(3) + case 2: // 'D' 키의 keyCode + print("Control + D pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(5) + case 3: // 'F' 키의 keyCode + print("Control + F pressed") + QuickSlotScriptsLogicController.shared.shortCutKeyUP(7) + case 6: // 'Z' 키의 keyCode + print("Control + Z pressed") + StateManager.shared.togglePin() // pin 처리 + case 7: // 'X' 키의 keyCode + print("Control + X pressed") + default: + break + } + } else if event.modifierFlags.contains(.command) { + switch event.keyCode { + case 12: // 'Q' 키의 keyCode + print("command + Q pressed") + case 13: // 'W' 키의 keyCode + print("command + W pressed") + case 14: // 'E' 키의 keyCode + print("command + E pressed") + case 15: // 'R' 키의 keyCode + print("command + R pressed") + WebViewManager.shared.hostingWebView?.reload() + case 0: // 'A' 키의 keyCode + print("command + A pressed") + case 1: // 'S' 키의 keyCode + print("command + S pressed") + case 2: // 'D' 키의 keyCode + print("command + D pressed") + case 3: // 'F' 키의 keyCode + print("command + F pressed") + default: + break + } + } else { + switch event.keyCode { + case 12: // 'Q' 키의 keyCode + print("Q pressed") + case 13: // 'W' 키의 keyCode + print("W pressed") + case 14: // 'E' 키의 keyCode + print("E pressed") + case 15: // 'R' 키의 keyCode + print("R pressed") + case 0: // 'A' 키의 keyCode + print("A pressed") + case 1: // 'S' 키의 keyCode + print("S pressed") + StorageConfig.shared.setThreshold(.percentage50) + StorageConfig.shared.setPeriod(.period10s) + case 2: // 'D' 키의 keyCode + print("D pressed") + DispatchQueue.main.async { + StorageConfig.shared.setThreshold(.percentage30) + } + StorageConfig.shared.setPeriod(.period1s) + case 3: // 'F' 키의 keyCode + print("F pressed") + case 53: // Escape 키 + print("escape") +// menubarVCDelegate?.toggleWindow(sender: nil) + default: + break + } + } + return event + } + } +} diff --git a/Box42/Main/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift index 49bdf4c..e217f74 100644 --- a/Box42/Main/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -25,6 +25,10 @@ class BoxBaseContainerViewController: NSViewController { weak var menubarVCDelegate: MenubarViewControllerDelegate? // extension + + var quickSlotButtonCollectionVC: QuickSlotButtonCollectionViewController = QuickSlotButtonCollectionViewController() + + override func loadView() { self.view = NSView() self.view.addSubview(splitView) diff --git a/Box42/Main/keyDown+BoxBaseContainerViewController.swift b/Box42/Main/keyDown+BoxBaseContainerViewController.swift deleted file mode 100644 index f73306a..0000000 --- a/Box42/Main/keyDown+BoxBaseContainerViewController.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// keyDown+BoxViewController.swift -// Box42 -// -// Created by Chanhee Kim on 8/21/23. -// - -import AppKit - -extension BoxBaseContainerViewController { - override func keyDown(with event: NSEvent) { - print(event.keyCode) - if event.keyCode == 1 { - StorageConfig.shared.setThreshold(.percentage50) - StorageConfig.shared.setPeriod(.period10s) - } - if event.keyCode == 2 { - // SdtorageConfig.shared.setThreshold(.percentage30) - DispatchQueue.main.async { - StorageConfig.shared.setThreshold(.percentage30) - } - StorageConfig.shared.setPeriod(.period1s) - } - - if event.modifierFlags.contains(.command) && event.keyCode == 15 { - print("Cmd + R pressed, reloading...") - WebViewManager.shared.hostingWebView?.reload() - } - - if event.keyCode == 53 { // Escape 키의 keyCode는 53입니다. - print("escape") - menubarVCDelegate?.toggleWindow(sender: nil) - } else { - super.keyDown(with: event) // 기타 키를 처리하기 위해 상위 클래스에게 전달 - } - } -} diff --git a/Box42/Preferences/View/Funtion/ShortcutSettingView.swift b/Box42/Preferences/View/Funtion/ShortcutSettingView.swift index b5e215d..f626c65 100644 --- a/Box42/Preferences/View/Funtion/ShortcutSettingView.swift +++ b/Box42/Preferences/View/Funtion/ShortcutSettingView.swift @@ -22,15 +22,15 @@ class ShortcutSettingView: NSView { // Create an array of labels and text fields for various shortcut settings let shortcutSettings: [(label: String, defaultKey: String)] = [ ("앱 Show 단축키 설정", "Middle Mouse"), - ("Pin Box 단축키 설정", "P"), - ("퀵슬롯 1 설정", "Q"), - ("퀵슬롯 2 설정", "W"), - ("퀵슬롯 3 설정", "E"), - ("퀵슬롯 4 설정", "R"), - ("퀵슬롯 5 설정", "A"), - ("퀵슬롯 6 설정", "S"), - ("퀵슬롯 7 설정", "D"), - ("퀵슬롯 8 설정", "F") + ("Pin Box 단축키 설정", "^B"), + ("퀵슬롯 1 설정", "^Q"), + ("퀵슬롯 2 설정", "^W"), + ("퀵슬롯 3 설정", "^E"), + ("퀵슬롯 4 설정", "^R"), + ("퀵슬롯 5 설정", "^A"), + ("퀵슬롯 6 설정", "^S"), + ("퀵슬롯 7 설정", "^D"), + ("퀵슬롯 8 설정", "^F") ] lazy var stackView: NSStackView = { diff --git a/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift index 6c2ada1..0d24603 100644 --- a/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift +++ b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift @@ -7,9 +7,8 @@ import AppKit -class ScriptsLogicController { - - static let shared = ScriptsLogicController() +class QuickSlotScriptsLogicController { + static let shared = QuickSlotScriptsLogicController() private init() { NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) @@ -17,32 +16,22 @@ class ScriptsLogicController { @objc func handleButtonTapped(notification: NSNotification) { if let button = notification.object as? NSButton { - SecurityScopedResourceAccess.accessResourceExecuteShellScript(scriptPath: button.associatedString ?? "") + if let associatedString = button.associatedString { + if let lastThreeCharacters = button.associatedString?.suffix(3) { + if lastThreeCharacters == ".sh" { + ScriptsFileManager.downloadFile(from: "https://42box.kr/" + associatedString) + } + } + } } } - private func executeCleanScript() { - if let scriptPath = Bundle.main.path(forResource: "cleanCache", ofType: "sh") { - let task = Process() - task.launchPath = "/bin/sh" - task.arguments = [scriptPath] - - let outputPipe = Pipe() - task.standardOutput = outputPipe - task.standardError = outputPipe - - task.launch() - task.waitUntilExit() - - let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile() - let output = String(data: outputData, encoding: .utf8) ?? "" - - DispatchQueue.main.async { - print("Output: \(output)") - } - } else { - DispatchQueue.main.async { - print("Script not found") + func shortCutKeyUP(_ keyCode: Int) { + if QuickSlotViewModel.shared.buttons.count > keyCode { + if let lastThreeCharacters = QuickSlotViewModel.shared.buttons[keyCode].path?.suffix(3) { + if lastThreeCharacters == ".sh" { + ScriptsFileManager.downloadFile(from: "https://42box.kr/" + QuickSlotViewModel.shared.buttons[keyCode].path!) + } } } } diff --git a/Box42/QuickSlot/Model/QuickSlotButtonModel.swift b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift index 9a55e20..2665c32 100644 --- a/Box42/QuickSlot/Model/QuickSlotButtonModel.swift +++ b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift @@ -7,15 +7,21 @@ import Foundation +struct QuickSlotModels: Codable { + let quickSlotList : [QuickSlotButtonModel] +} + // Model struct QuickSlotButtonModel: Codable { - let id: UUID + let scriptUuid: UUID var title: String var path: String? + var type: String? - init(id: UUID = UUID(), title: String = "Default", path: String? = nil) { - self.id = id + init(id: UUID = UUID(), title: String = "Default", path: String? = "none", type: String = "sh") { + self.scriptUuid = id self.title = title self.path = path + self.type = type } } diff --git a/Box42/QuickSlot/Model/QuickSlotUI.swift b/Box42/QuickSlot/Model/QuickSlotUI.swift index 096bcbc..f026d00 100644 --- a/Box42/QuickSlot/Model/QuickSlotUI.swift +++ b/Box42/QuickSlot/Model/QuickSlotUI.swift @@ -23,7 +23,7 @@ enum QuickSlotUI { } enum title { - static let clean = "Clean" + static let clean = "CleanCache" static let preferences = "Preferences" static let scripts = "Scripts" static let user = "User" diff --git a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift index b1b31be..5e1c9f1 100644 --- a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift +++ b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift @@ -90,16 +90,25 @@ extension QuickSlotButtonCollectionViewController: NSCollectionViewDelegate, NSC let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "QuickSlotButtonViewItem"), for: indexPath) if let customItem = item as? QuickSlotButtonViewItem { - let buttonModel = viewModel.buttons[indexPath.item] - let btn = NSButton() - btn.title = buttonModel.title - btn.action = #selector(collectionButtonTapped) - btn.target = self - btn.wantsLayer = true - btn.layer?.backgroundColor = NSColor.red.cgColor - customItem.view.addSubview(btn) - btn.frame = CGRect(x: 0, y: 0, width: QuickSlotUI.size.button, height: QuickSlotUI.size.button) - btn.associatedString = buttonModel.path + if customItem.view.subviews.isEmpty { + let btn = QuickSlotItemButton(indexPath.item) + btn.action = #selector(collectionButtonTapped) + btn.target = self + + let label = QuickSlotItemLabel(indexPath.item) + + customItem.view.addSubview(btn) + customItem.view.addSubview(label) + + btn.snp.makeConstraints { make in + make.left.top.right.equalToSuperview() + } + + label.snp.makeConstraints { make in + make.top.equalTo(btn.snp.bottom) + make.left.right.bottom.equalToSuperview() + } + } } return item } diff --git a/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemButton.swift b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemButton.swift new file mode 100644 index 0000000..6d0f349 --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemButton.swift @@ -0,0 +1,35 @@ +// +// QuickSlotItemButton.swift +// Box42 +// +// Created by Chanhee Kim on 9/3/23. +// + +import AppKit + +class QuickSlotItemButton: NSButton { + + var viewModel = QuickSlotViewModel.shared + + init(_ item: Int) { + super.init(frame: .zero) + self.frame = CGRect(x: 0, y: 0, width: QuickSlotUI.size.button, height: QuickSlotUI.size.button) + let buttonModel = viewModel.buttons[item] + self.title = buttonModel.title + if buttonModel.title == "CleanCache" { + self.image = NSImage(imageLiteralResourceName: "trash") + } else if buttonModel.type == "sh" { + self.image = NSImage(imageLiteralResourceName: "document-text") + } else if buttonModel.type == "pref" { + self.image = NSImage(imageLiteralResourceName: "setting") + } + self.isBordered = false + self.wantsLayer = true + self.layer?.backgroundColor = NSColor.clear.cgColor + self.associatedString = buttonModel.path + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemLabel.swift b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemLabel.swift new file mode 100644 index 0000000..0177e76 --- /dev/null +++ b/Box42/QuickSlot/View/ButtonCollectionView/Vertical Item/QuickSlotItemLabel.swift @@ -0,0 +1,32 @@ +// +// QuickSlotItemLabel.swift +// Box42 +// +// Created by Chanhee Kim on 9/3/23. +// + +import AppKit + +class QuickSlotItemLabel: NSTextField { + + var viewModel = QuickSlotViewModel.shared + + init(_ item: Int) { + super.init(frame: .zero) + let buttonModel = viewModel.buttons[item] + + self.stringValue = buttonModel.title + self.font = NSFont(name: "Inter", size: QuickSlotUI.size.font) + self.textColor = NSColor(hex: "#696969") + self.backgroundColor = NSColor.clear + self.isBordered = false + self.alignment = .center + self.isSelectable = false + self.isEditable = false + self.lineBreakMode = .byTruncatingTail + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Box42/QuickSlot/View/QuickSlotGroupView.swift b/Box42/QuickSlot/View/QuickSlotGroupView.swift index 228c26b..e436c86 100644 --- a/Box42/QuickSlot/View/QuickSlotGroupView.swift +++ b/Box42/QuickSlot/View/QuickSlotGroupView.swift @@ -33,7 +33,6 @@ class QuickSlotGroupView: NSView { self.addSubview(divider) self.addSubview(headerView) self.addSubview(buttonCollectionView.view) - } private func setupConstraints() { diff --git a/Box42/QuickSlot/View/QuickSlotHeaderView.swift b/Box42/QuickSlot/View/QuickSlotHeaderView.swift index 443ed69..3638225 100644 --- a/Box42/QuickSlot/View/QuickSlotHeaderView.swift +++ b/Box42/QuickSlot/View/QuickSlotHeaderView.swift @@ -17,7 +17,7 @@ class QuickSlotHeaderView: NSView { init(image: NSImage, completion: @escaping () -> Void) { super.init(frame: .zero) - QuickSlotHeaderButton = NSButton(image: image, target: self, action: #selector(pin)) + QuickSlotHeaderButton = NSButton(image: image, target: self, action: #selector(btnAction)) QuickSlotHeaderButton.isBordered = false QuickSlotHeaderButton.wantsLayer = true QuickSlotHeaderButton.layer?.backgroundColor = NSColor.clear.cgColor @@ -49,7 +49,7 @@ class QuickSlotHeaderView: NSView { fatalError("init(coder:) has not been implemented") } - @objc func pin() { + @objc func btnAction() { callback?() } } diff --git a/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift index 568168d..ca43f68 100644 --- a/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift +++ b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift @@ -13,30 +13,57 @@ class QuickSlotViewModel { @Published var buttons: [QuickSlotButtonModel] = [] private init() { - let button1 = QuickSlotButtonModel(id: UUID(uuidString: "550e8400-e29b-41d4-a716-446655440000")!, + let button1 = QuickSlotButtonModel(id: UUID(uuidString: "37a56076-e72c-4efe-ba7f-de0effe7f4c3")!, title: QuickSlotUI.title.clean, - path: Bundle.main.path(forResource: "cleanCache", ofType: "sh")) - let button2 = QuickSlotButtonModel(title: QuickSlotUI.title.preferences) + path: Bundle.main.path(forResource: "cleanCache", ofType: "sh"), + type: "sh" + ) + let button2 = QuickSlotButtonModel(title: QuickSlotUI.title.preferences, type: "pref") let button3 = QuickSlotButtonModel(title: QuickSlotUI.title.scripts) - let button4 = QuickSlotButtonModel(title: QuickSlotUI.title.user) + let button4 = QuickSlotButtonModel(title: QuickSlotUI.title.user, type: "pref") buttons = [button1, button2, button3, button4] } + func setUpQuickSlot() { + if let newButtons = UserManager.shared.userProfile?.quickSlotList { + replaceQuickSlot(with: newButtons) + } + } + + // 새로운 스크립트 배열로 교체하는 메소드 + func replaceQuickSlot(with newQuickSlot: [QuickSlotButtonModel]) { + self.buttons = newQuickSlot + } + // 퀵슬롯 안에 해당 버튼이 없으면 추가 func addButton(_ button: QuickSlotButtonModel) { - if !buttons.contains(where: { $0.id == button.id }) { + if !buttons.contains(where: { $0.scriptUuid == button.scriptUuid }) { buttons.append(button) + updateMeQuickSlot() } } func removeButton(_ id: UUID) { - buttons.removeAll { $0.id == id } + buttons.removeAll { $0.scriptUuid == id } + updateMeQuickSlot() } func updateButton(id: UUID, newTitle: String) { - if let index = buttons.firstIndex(where: { $0.id == id }) { + if let index = buttons.firstIndex(where: { $0.scriptUuid == id }) { buttons[index].title = newTitle } } + + func updateMeQuickSlot() { + let body = QuickSlotModels(quickSlotList: buttons) + API.putUserMeQuickSlot(quickSlots: body) { result in + switch result { + case .success(_): + print("Successfully updated the scripts.") // 혹은 사용자에게 보여줄 알림 추가 + case .failure(let error): + print("Failed to update scripts: \(error.localizedDescription)") // 혹은 사용자에게 보여줄 알림 추가 + } + } + } } diff --git a/Box42/Resources/AppDelegate.swift b/Box42/Resources/AppDelegate.swift index 7d2ae45..bc8ce90 100644 --- a/Box42/Resources/AppDelegate.swift +++ b/Box42/Resources/AppDelegate.swift @@ -22,22 +22,22 @@ class AppDelegate: NSObject, NSApplicationDelegate { iconController = IconController() // alertAccessibility() // hotkey() + self.eventMonitoring() // storage.storageTimerEvent() _ = UserManager.shared - _ = ScriptsLogicController.shared + _ = QuickSlotScriptsLogicController.shared // MARK: - 유저데이터 동기화 WebViewManager.shared.getCookie() API.getUserProfile(WebViewManager.shared.getCookieWebKit) - _ = QuickSlotViewModel.shared - _ = ScriptViewModel.shared // 초기화와 동시에 + _ = ScriptViewModel.shared } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } - + func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } diff --git a/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/Contents.json new file mode 100644 index 0000000..2072db0 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "document-text.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/document-text.png b/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/document-text.png new file mode 100644 index 0000000..ac603c5 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/document-text.imageset/document-text.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/document-text.png b/Box42/Resources/Assets.xcassets/uibuttons/document-text.png new file mode 100644 index 0000000..ac603c5 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/document-text.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/Contents.json new file mode 100644 index 0000000..c7225a3 --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "setting.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/setting.png b/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/setting.png new file mode 100644 index 0000000..5ede7c6 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/setting.imageset/setting.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/setting.png b/Box42/Resources/Assets.xcassets/uibuttons/setting.png new file mode 100644 index 0000000..5ede7c6 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/setting.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/Contents.json b/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/Contents.json new file mode 100644 index 0000000..2a3e98a --- /dev/null +++ b/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "trash.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/trash.png b/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/trash.png new file mode 100644 index 0000000..f361bf2 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/trash.imageset/trash.png differ diff --git a/Box42/Resources/Assets.xcassets/uibuttons/trash.png b/Box42/Resources/Assets.xcassets/uibuttons/trash.png new file mode 100644 index 0000000..f361bf2 Binary files /dev/null and b/Box42/Resources/Assets.xcassets/uibuttons/trash.png differ diff --git a/Box42/Resources/Info.plist b/Box42/Resources/Info.plist index 4187051..e470c4d 100644 --- a/Box42/Resources/Info.plist +++ b/Box42/Resources/Info.plist @@ -2,8 +2,8 @@ - NSAppleEventsUsageDescription - This app needs access to control System Preferences. + NSAppleEventsUsageDescription + This app needs access to control System Preferences. NSDocumentsFolderUsageDescription 원활한 앱 구동을 위해 유저 디렉토리의 권한을 요청합니다. NSAppTransportSecurity diff --git a/Box42/Scripts/Model/Scripts.swift b/Box42/Scripts/Model/Scripts.swift index 40d59fa..d22fc03 100644 --- a/Box42/Scripts/Model/Scripts.swift +++ b/Box42/Scripts/Model/Scripts.swift @@ -12,15 +12,15 @@ struct Scripts: Codable { } struct Script: Codable { - var id: UUID? + var scriptUuid: UUID? var name: String - var description: String + var description: String? var path: String var savedId: Int? var userUuid: String? - init(id: UUID = UUID(), name: String, description: String, path: String, savedId: Int, userUuid: String?) { - self.id = id + init(id: UUID?, name: String, description: String?, path: String, savedId: Int?, userUuid: String?) { + self.scriptUuid = id self.name = name self.description = description self.path = path diff --git a/Box42/Scripts/View/Table/ScriptCell.swift b/Box42/Scripts/View/Table/ScriptCell.swift index 57d421b..c8be376 100644 --- a/Box42/Scripts/View/Table/ScriptCell.swift +++ b/Box42/Scripts/View/Table/ScriptCell.swift @@ -75,7 +75,7 @@ class ScriptCell: NSTableCellView { self.script = script self.viewModel = viewModel nameLabel.stringValue = script.name - descriptionLabel.stringValue = script.description + descriptionLabel.stringValue = script.description ?? "description" deleteButton.target = self deleteButton.action = #selector(deleteButtonClicked) @@ -89,25 +89,23 @@ class ScriptCell: NSTableCellView { } @objc func deleteButtonClicked() { - if let id = script?.id { + if let id = script?.scriptUuid { viewModel?.deleteScript(id: id) } } @objc func excuteButtonClicked() { - if let id = script?.id { + if let id = script?.scriptUuid { viewModel?.excuteScript(id: id) } } - // script 내부 클릭시 1차 실행 - // 있는거면 지우고 없는거면 추가 @objc func quickSlotButtonclicked() { - guard let id = script?.id else { + guard let id = script?.scriptUuid else { return } - let alreadyExists = QuickSlotViewModel.shared.buttons.contains { $0.id == id } + let alreadyExists = QuickSlotViewModel.shared.buttons.contains { $0.scriptUuid == id } if alreadyExists { QuickSlotViewModel.shared.removeButton(id) diff --git a/Box42/Scripts/View/Table/ScriptCellManager.swift b/Box42/Scripts/View/Table/ScriptCellManager.swift index b471493..a7567ae 100644 --- a/Box42/Scripts/View/Table/ScriptCellManager.swift +++ b/Box42/Scripts/View/Table/ScriptCellManager.swift @@ -76,7 +76,7 @@ class ScriptCellManager: NSTableCellView { self.script = script self.viewModel = viewModel nameLabel.stringValue = script.name - descriptionLabel.stringValue = script.description + descriptionLabel.stringValue = script.description ?? "description" deleteButton.target = self deleteButton.action = #selector(deleteButtonClicked) @@ -90,19 +90,19 @@ class ScriptCellManager: NSTableCellView { } @objc func deleteButtonClicked() { - if let id = script?.id { + if let id = script?.scriptUuid { viewModel?.deleteScript(id: id) } } @objc func excuteButtonClicked() { - if let id = script?.id { + if let id = script?.scriptUuid { viewModel?.excuteScript(id: id) } } @objc func quickSlotButtonclicked() { - if let id = script?.id { + if let id = script?.scriptUuid { viewModel?.quickSlotScript(id: id) } } diff --git a/Box42/Scripts/ViewModel/ScriptsViewModel.swift b/Box42/Scripts/ViewModel/ScriptsViewModel.swift index 04a0a37..9abc40e 100644 --- a/Box42/Scripts/ViewModel/ScriptsViewModel.swift +++ b/Box42/Scripts/ViewModel/ScriptsViewModel.swift @@ -15,24 +15,25 @@ class ScriptViewModel: NSObject { private override init() { self.scripts = [ - Script(name: "cleanCache", + Script(id: UUID(uuidString: "37a56076-e72c-4efe-ba7f-de0effe7f4c3"), + name: "CleanCache", description: "Cleaning cache", path: Bundle.main.path(forResource: "cleanCache", ofType: "sh") ?? "", savedId: -1 , userUuid: nil), -// Script(name: "brewInGoinfre", -// description: "Brew download in goinfre", -// path: Bundle.main.path(forResource: "brewInGoinfre", ofType: "sh") ?? "", savedId: -1, userUuid: nil), -// Script(name: "exportMacOSInfo", -// description: "export setting MacOS Info", -// path: Bundle.main.path(forResource: "exportMacOSInfo", ofType: "sh") ?? "", savedId: -1, userUuid: nil), -// Script(name: "importMacOSInfo", -// description: "import MacOS Info", -// path: Bundle.main.path(forResource: "importMacOSInfo", ofType: "sh") ?? "", savedId: -1, userUuid: nil), -// Script(name: "key Mapping", -// description: "key Mapping", -// path: Bundle.main.path(forResource: "keyMapping", ofType: "sh") ?? "", savedId: -1, userUuid: nil), -// Script(name: "nodeInstall", -// description: "node Install", -// path: Bundle.main.path(forResource: "nodeInstall", ofType: "sh") ?? "", savedId: -1, userUuid: nil) + // Script(name: "brewInGoinfre", + // description: "Brew download in goinfre", + // path: Bundle.main.path(forResource: "brewInGoinfre", ofType: "sh") ?? "", savedId: -1, userUuid: nil), + // Script(name: "exportMacOSInfo", + // description: "export setting MacOS Info", + // path: Bundle.main.path(forResource: "exportMacOSInfo", ofType: "sh") ?? "", savedId: -1, userUuid: nil), + // Script(name: "importMacOSInfo", + // description: "import MacOS Info", + // path: Bundle.main.path(forResource: "importMacOSInfo", ofType: "sh") ?? "", savedId: -1, userUuid: nil), + // Script(name: "key Mapping", + // description: "key Mapping", + // path: Bundle.main.path(forResource: "keyMapping", ofType: "sh") ?? "", savedId: -1, userUuid: nil), + // Script(name: "nodeInstall", + // description: "node Install", + // path: Bundle.main.path(forResource: "nodeInstall", ofType: "sh") ?? "", savedId: -1, userUuid: nil) ] API.initializeUserMeScripts(WebViewManager.shared.getCookieWebKit) } @@ -45,16 +46,18 @@ class ScriptViewModel: NSObject { // Read func excuteScript(id: UUID) { - if let index = scripts.firstIndex(where: { $0.id == id }) { -// ExecuteScripts.executeShellScript(path: scripts[index].name) + if let index = scripts.firstIndex(where: { $0.scriptUuid == id }) { + // ExecuteScripts.executeShellScript(path: scripts[index].name) // MARK: - 파일스크립트 매니저에서 권한을 얻은 실행으로 실행합니다. - SecurityScopedResourceAccess.accessResourceExecuteShellScript(scriptPath: scripts[index].path) + ScriptsFileManager.downloadFile(from: "https://42box.kr/" + scripts[index].path) + + // SecurityScopedResourceAccess.accessResourceExecuteShellScript(scriptPath: scripts[index].path) } } // Update func updateScript(id: UUID, newName: String, newDescription: String) { - if let index = scripts.firstIndex(where: { $0.id == id }) { + if let index = scripts.firstIndex(where: { $0.scriptUuid == id }) { scripts[index].name = newName scripts[index].description = newDescription } @@ -62,11 +65,11 @@ class ScriptViewModel: NSObject { // Delete func deleteScript(id: UUID) { - if let script = scripts.first(where: { $0.id == id }) { + if let script = scripts.first(where: { $0.scriptUuid == id }) { API.deleteUserMeScripts(WebViewManager.shared.getCookieWebKit, savedId: script.savedId!) { result in switch result { case .success(_): - self.scripts.removeAll(where: { $0.id == id }) + self.scripts.removeAll(where: { $0.scriptUuid == id }) QuickSlotViewModel.shared.removeButton(id) case .failure(let error): @@ -83,12 +86,12 @@ class ScriptViewModel: NSObject { // VM class 시작시 최초 1회 실행되는 메소드 func setupScripts(with newScripts: [Script]) { - self.scripts += newScripts + self.scripts = newScripts } // 스크립트안에서 해당하는 스크립트를 찾아서 quickslotVM에 추가 func quickSlotScript(id: UUID) { - if let index = scripts.firstIndex(where: { $0.id == id }) { + if let index = scripts.firstIndex(where: { $0.scriptUuid == id }) { let button = QuickSlotButtonModel(id: id, title: scripts[index].name, path: scripts[index].path) QuickSlotViewModel.shared.addButton(button) } diff --git a/Box42/Shared/API/API.swift b/Box42/Shared/API/API.swift index 5d709ef..c4fbde4 100644 --- a/Box42/Shared/API/API.swift +++ b/Box42/Shared/API/API.swift @@ -67,4 +67,28 @@ class API { task.resume() } + // PUT + static func putDataFromAPI(withURL urlString: String, completion: @escaping (Result) -> Void) { + + let url = URL(string: urlString)! + var request = URLRequest(url: url) + request.httpMethod = "PUT" + request.httpShouldHandleCookies = true + + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + if let error = error { + completion(.failure(error)) + return + } + + if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 { + completion(.failure(NSError(domain: "InvalidStatusCode", code: httpResponse.statusCode, userInfo: nil))) + return + } + completion(.success(data)) + } + task.resume() + } + + } diff --git a/Box42/Shared/API/GetUserMeQuickSlot.swift b/Box42/Shared/API/GetUserMeQuickSlot.swift new file mode 100644 index 0000000..c4481bc --- /dev/null +++ b/Box42/Shared/API/GetUserMeQuickSlot.swift @@ -0,0 +1,8 @@ +// +// GetUserMeQuickSlot.swift +// Box42 +// +// Created by Chanhee Kim on 9/3/23. +// + +import Foundation diff --git a/Box42/Shared/API/GetUserMeScripts.swift b/Box42/Shared/API/GetUserMeScripts.swift index cd09521..05e1348 100644 --- a/Box42/Shared/API/GetUserMeScripts.swift +++ b/Box42/Shared/API/GetUserMeScripts.swift @@ -42,7 +42,7 @@ extension API { fetchDataFromAPI(withURL: "https://api.42box.kr/user-service/users/me/scripts", forType: [Script].self) { (result: Result<[Script], Error>) in switch result { case .success(let scripts): - print(">> MacOS Get :", scripts) + print(">> Initalize Script MacOS Get :", scripts) DispatchQueue.main.async { ScriptViewModel.shared.setupScripts(with: scripts) } diff --git a/Box42/Shared/API/GetUserProfile.swift b/Box42/Shared/API/GetUserProfile.swift index f029f45..a631e2d 100644 --- a/Box42/Shared/API/GetUserProfile.swift +++ b/Box42/Shared/API/GetUserProfile.swift @@ -21,8 +21,9 @@ extension API { fetchDataFromAPI(withURL: "https://api.42box.kr/user-service/users/me", forType: UserProfile.self) { (result: Result) in switch result { case .success(let userProfile): - print(">> MacOS Get :", userProfile) + print(">> User MacOS Get :", userProfile) UserManager.shared.updateUserProfile(newProfile: userProfile) + QuickSlotViewModel.shared.setUpQuickSlot() case .failure(let error): print("Error: \(error)") } diff --git a/Box42/Shared/API/PutUserMeQuickSlot.swift b/Box42/Shared/API/PutUserMeQuickSlot.swift new file mode 100644 index 0000000..f672f42 --- /dev/null +++ b/Box42/Shared/API/PutUserMeQuickSlot.swift @@ -0,0 +1,55 @@ +// +// PutUserMeQuickSlot.swift +// Box42 +// +// Created by Chanhee Kim on 9/3/23. +// + +import WebKit + +extension API { + // MARK: - Scripts PUT: https://api.42box.kr/user-service/users/me/quick-slot + // TODO: refactoring 필수 + static func putUserMeQuickSlot(quickSlots: QuickSlotModels, completion: @escaping (Result) -> Void) { + + WebViewManager.shared.hostingWebView?.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in + let cookieStorage = HTTPCookieStorage.shared + for cookie in cookies { + cookieStorage.setCookie(cookie) + } + + let url = "https://api.42box.kr/user-service/users/me/quick-slot" + + var request = URLRequest(url: URL(string: url)!) + request.httpMethod = "PUT" + request.httpShouldHandleCookies = true + request.addValue("application/json", forHTTPHeaderField: "Content-Type") + + // Scripts 객체를 JSON 데이터로 인코딩 + print(quickSlots) + do { + let jsonData = try JSONEncoder().encode(quickSlots) + request.httpBody = jsonData + print(request.httpBody!) + } catch { + print("Failed to encode scripts: \(error)") + completion(.failure(error)) + return + } + + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + if let error = error { + completion(.failure(error)) + return + } + + if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode != 200 { + completion(.failure(NSError(domain: "InvalidStatusCode", code: httpResponse.statusCode, userInfo: nil))) + return + } + completion(.success(())) + } + task.resume() + } + } +} diff --git a/Box42/Shared/User/UserManager.swift b/Box42/Shared/User/UserManager.swift index ec61323..18e4677 100644 --- a/Box42/Shared/User/UserManager.swift +++ b/Box42/Shared/User/UserManager.swift @@ -9,7 +9,7 @@ import Foundation class UserManager { static let shared = UserManager() - private var userProfile: UserProfile? { + var userProfile: UserProfile? { didSet { NotificationCenter.default.post(name: .didUpdateUserProfile, object: nil) } diff --git a/Box42/Shared/User/UserProfile.swift b/Box42/Shared/User/UserProfile.swift index ce4e8a8..fdeafcf 100644 --- a/Box42/Shared/User/UserProfile.swift +++ b/Box42/Shared/User/UserProfile.swift @@ -46,7 +46,7 @@ extension UserProfile { statusMessage: "hello 42Box!", profileImageUrl: "https://42box.kr/user_profile_image/a52671f9-fca9-43ad-b0c0-1c5360831cf2.png", profileImagePath: "user_profile_image/a52671f9-fca9-43ad-b0c0-1c5360831cf2.png", - quickSlotList: [ QuickSlotButtonModel(id: UUID(uuidString: "550e8400-e29b-41d4-a716-446655440000")!, title: "cleanCache", path: Bundle.main.path(forResource: "cleanCache", ofType: "sh")), + quickSlotList: [ QuickSlotButtonModel(id: UUID(uuidString: "37a56076-e72c-4efe-ba7f-de0effe7f4c3")!, title: "cleanCache", path: Bundle.main.path(forResource: "cleanCache", ofType: "sh")), ] ) } diff --git a/Box42/WebView/WebView.swift b/Box42/WebView/WebView.swift index 8521d2a..ac76554 100644 --- a/Box42/WebView/WebView.swift +++ b/Box42/WebView/WebView.swift @@ -63,16 +63,17 @@ extension WebView { print("JSON decoding failed: \(error)") } } + // 스크립트 다운로드 if message.name == WebViewUI.transfer.downloadScript, let downloadScriptString = message.body as? String { let scriptJson = downloadScriptString.data(using: .utf8) - print(String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") + print("스크립트 다운로드", String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") do { let decoder = JSONDecoder() let downloadString = try decoder.decode(Script.self, from: scriptJson!) - ScriptViewModel.shared.addScript(id: UUID(), name: downloadString.name, description: downloadString.description, path: downloadString.path, savedId: Int(downloadString.savedId ?? 0), userUuid: downloadString.userUuid!) + ScriptViewModel.shared.addScript(id: UUID(), name: downloadString.name, description: downloadString.description ?? "description", path: downloadString.path, savedId: Int(downloadString.savedId ?? 0), userUuid: downloadString.userUuid!) print(downloadString) @@ -84,7 +85,7 @@ extension WebView { // 스크립트 실행 if message.name == WebViewUI.transfer.executeScript, let executeScriptString = message.body as? String { let scriptJson = executeScriptString.data(using: .utf8) - print(String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") + print("스크립트 실행", String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") do { let decoder = JSONDecoder() @@ -102,7 +103,7 @@ extension WebView { // 스크립트 삭제 if message.name == WebViewUI.transfer.deleteScript, let deleteScriptString = message.body as? String { let scriptJson = deleteScriptString.data(using: .utf8) - print(String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") + print("스크립트 삭제", String(data: scriptJson!, encoding: .utf8) ?? "Invalid JSON data") do { let decoder = JSONDecoder() @@ -111,7 +112,7 @@ extension WebView { print(deleteScript) - ScriptViewModel.shared.deleteScript(id: deleteScript.id!) + ScriptViewModel.shared.deleteScript(id: deleteScript.scriptUuid!) } catch { print("JSON decoding failed: \(error)") }