diff --git a/Box42.xcodeproj/project.pbxproj b/Box42.xcodeproj/project.pbxproj index 6ef337a..c4c677f 100644 --- a/Box42.xcodeproj/project.pbxproj +++ b/Box42.xcodeproj/project.pbxproj @@ -22,7 +22,6 @@ DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91622A8E6A5400D1D6F1 /* Constants.swift */; }; DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91662A8E6CA700D1D6F1 /* WebViewManager.swift */; }; DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A916C2A8E7DD700D1D6F1 /* HoverButton.swift */; }; - DE0A91782A8F014F00D1D6F1 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91772A8F014F00D1D6F1 /* WebView.swift */; }; DE0A917B2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */; }; DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A917E2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift */; }; DE0A91832A8F889000D1D6F1 /* GoHomePageViaToolbar().swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */; }; @@ -64,16 +63,33 @@ DE62BE5A2A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */; }; DE62BE672A9BA92E00D97E06 /* QuickSlotButtonViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */; }; DE6332E42A9BB8F800DCFAF6 /* QuickSlotButtonCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */; }; - DE6332E82A9BBEF800DCFAF6 /* NotifConst.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */; }; DE6332F22A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6332F12A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift */; }; DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BA502A82580400713683 /* MenubarViewModel.swift */; }; DE77BA562A82637900713683 /* StateManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BA552A82637900713683 /* StateManager.swift */; }; + DE77BBA22A9DDC40006CC98B /* ScriptsFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBA12A9DDC40006CC98B /* ScriptsFileManager.swift */; }; + DE77BBA62A9DDF2B006CC98B /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE0A91772A8F014F00D1D6F1 /* WebView.swift */; }; + DE77BBCD2A9E0568006CC98B /* ExcuteScripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBCC2A9E0568006CC98B /* ExcuteScripts.swift */; }; + DE77BBD22A9E0AE8006CC98B /* WebViewUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBD12A9E0AE8006CC98B /* WebViewUI.swift */; }; + DE77BBE22A9E0F70006CC98B /* Scripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBE12A9E0F70006CC98B /* Scripts.swift */; }; + DE77BBF02A9E38C6006CC98B /* GetUserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBA92A9DE680006CC98B /* GetUserProfile.swift */; }; + DE77BBF32A9E38DC006CC98B /* UserManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE77BBE92A9E2DDF006CC98B /* UserManager.swift */; }; + DE7886042A9C71CB00FE21DD /* ScriptsTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7886032A9C71CB00FE21DD /* ScriptsTableView.swift */; }; + DE78860C2A9C770300FE21DD /* ScriptsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE78860B2A9C770300FE21DD /* ScriptsViewModel.swift */; }; + DE7886172A9CCB3B00FE21DD /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7886162A9CCB3B00FE21DD /* UserProfile.swift */; }; + DE7886282A9D186700FE21DD /* ScriptsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7886272A9D186700FE21DD /* ScriptsViewController.swift */; }; + DE78862D2A9D1ADE00FE21DD /* PreferencesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE78862C2A9D1ADE00FE21DD /* PreferencesCell.swift */; }; DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */; }; DE7F9D462A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */; }; DE874F4E2A591DEA00FC3B77 /* Hotkey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F4D2A591DEA00FC3B77 /* Hotkey.swift */; }; DE874F542A591F1400FC3B77 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F532A591F1400FC3B77 /* PreferencesView.swift */; }; - DE874F572A591F2500FC3B77 /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F562A591F2500FC3B77 /* Icon.swift */; }; DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE874F5E2A5935CC00FC3B77 /* String.swift */; }; + DE9456F82A9E44FD00B0B768 /* IconController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9456F72A9E44FD00B0B768 /* IconController.swift */; }; + DE9457002A9E5B0900B0B768 /* ScriptCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9456FF2A9E5B0900B0B768 /* ScriptCell.swift */; }; + DE9457062A9E69C100B0B768 /* ScriptNameLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9457052A9E69C100B0B768 /* ScriptNameLabel.swift */; }; + DE9457092A9E69D100B0B768 /* ScriptDescriptionsLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9457082A9E69D100B0B768 /* ScriptDescriptionsLabel.swift */; }; + DE94570C2A9E69EB00B0B768 /* ScriptExcuteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE94570B2A9E69EB00B0B768 /* ScriptExcuteButton.swift */; }; + DE94570F2A9E69F200B0B768 /* ScriptDeleteButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE94570E2A9E69F200B0B768 /* ScriptDeleteButton.swift */; }; + DE9457162A9E6D3000B0B768 /* ScriptQuickSlotButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9457112A9E6A0000B0B768 /* ScriptQuickSlotButton.swift */; }; DE97CA692A9A6364001073DE /* PixelConversion+CGFloat.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA682A9A6364001073DE /* PixelConversion+CGFloat.swift */; }; DE97CA792A9A6F6A001073DE /* QuickSlotHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA782A9A6F6A001073DE /* QuickSlotHeaderView.swift */; }; DE97CA7C2A9A7199001073DE /* QuickSlotGroupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE97CA7B2A9A7199001073DE /* QuickSlotGroupView.swift */; }; @@ -86,7 +102,6 @@ DE9DA8142A97F20E001C0D3B /* ButtonGroupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE9DA8132A97F20E001C0D3B /* ButtonGroupViewController.swift */; }; DEB862D42A85124500278FCD /* cleanCache.sh in Resources */ = {isa = PBXBuildFile; fileRef = DEB862D32A85124500278FCD /* cleanCache.sh */; }; DEB862D92A852C4500278FCD /* brewInGoinfre.sh in Resources */ = {isa = PBXBuildFile; fileRef = DEB862D82A852C4500278FCD /* brewInGoinfre.sh */; }; - DEB862DC2A85347400278FCD /* Scripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEB862DB2A85347400278FCD /* Scripts.swift */; }; DEB862EB2A853F7F00278FCD /* BoxWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEB862E92A853F7F00278FCD /* BoxWindowController.swift */; }; DEE0FA962A9A554F00085A65 /* FunctionButtonUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */; }; DEF749322A85657600D987C8 /* NSScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEF749312A85657600D987C8 /* NSScreen.swift */; }; @@ -151,17 +166,33 @@ DE44081C2A928F760091937A /* Divider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Divider.swift; sourceTree = "<group>"; }; DE62BE312A9B869900D97E06 /* QuickSlotButtonCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonCollectionViewController.swift; sourceTree = "<group>"; }; DE62BE582A9BA31700D97E06 /* QuickSlotButtonCollectionViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickSlotButtonCollectionViewController.xib; sourceTree = "<group>"; }; - DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotifConst.swift; sourceTree = "<group>"; }; DE6332F12A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotScriptsLogicController.swift; sourceTree = "<group>"; }; DE77BA502A82580400713683 /* MenubarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenubarViewModel.swift; sourceTree = "<group>"; }; DE77BA552A82637900713683 /* StateManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateManager.swift; sourceTree = "<group>"; }; + DE77BBA12A9DDC40006CC98B /* ScriptsFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptsFileManager.swift; sourceTree = "<group>"; }; + DE77BBA92A9DE680006CC98B /* GetUserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetUserProfile.swift; sourceTree = "<group>"; }; + DE77BBCC2A9E0568006CC98B /* ExcuteScripts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExcuteScripts.swift; sourceTree = "<group>"; }; + DE77BBD12A9E0AE8006CC98B /* WebViewUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewUI.swift; sourceTree = "<group>"; }; + DE77BBE12A9E0F70006CC98B /* Scripts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scripts.swift; sourceTree = "<group>"; }; + DE77BBE92A9E2DDF006CC98B /* UserManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserManager.swift; sourceTree = "<group>"; }; + DE7886032A9C71CB00FE21DD /* ScriptsTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptsTableView.swift; sourceTree = "<group>"; }; + DE78860B2A9C770300FE21DD /* ScriptsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptsViewModel.swift; sourceTree = "<group>"; }; + DE7886162A9CCB3B00FE21DD /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = "<group>"; }; + DE7886272A9D186700FE21DD /* ScriptsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptsViewController.swift; sourceTree = "<group>"; }; + DE78862C2A9D1ADE00FE21DD /* PreferencesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesCell.swift; sourceTree = "<group>"; }; DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = "<group>"; }; DE7F9D432A9B7A4700F8ACAE /* QuickSlotButtonViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonViewItem.swift; sourceTree = "<group>"; }; DE7F9D442A9B7A4700F8ACAE /* QuickSlotButtonViewItem.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QuickSlotButtonViewItem.xib; sourceTree = "<group>"; }; DE874F4D2A591DEA00FC3B77 /* Hotkey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hotkey.swift; sourceTree = "<group>"; }; DE874F532A591F1400FC3B77 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = "<group>"; }; - DE874F562A591F2500FC3B77 /* Icon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Icon.swift; sourceTree = "<group>"; }; DE874F5E2A5935CC00FC3B77 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; }; + DE9456F72A9E44FD00B0B768 /* IconController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconController.swift; sourceTree = "<group>"; }; + DE9456FF2A9E5B0900B0B768 /* ScriptCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptCell.swift; sourceTree = "<group>"; }; + DE9457052A9E69C100B0B768 /* ScriptNameLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptNameLabel.swift; sourceTree = "<group>"; }; + DE9457082A9E69D100B0B768 /* ScriptDescriptionsLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptDescriptionsLabel.swift; sourceTree = "<group>"; }; + DE94570B2A9E69EB00B0B768 /* ScriptExcuteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptExcuteButton.swift; sourceTree = "<group>"; }; + DE94570E2A9E69F200B0B768 /* ScriptDeleteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptDeleteButton.swift; sourceTree = "<group>"; }; + DE9457112A9E6A0000B0B768 /* ScriptQuickSlotButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScriptQuickSlotButton.swift; sourceTree = "<group>"; }; DE97CA682A9A6364001073DE /* PixelConversion+CGFloat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PixelConversion+CGFloat.swift"; sourceTree = "<group>"; }; DE97CA6E2A9A6EFC001073DE /* QuickSlotViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotViewModel.swift; sourceTree = "<group>"; }; DE97CA712A9A6F0D001073DE /* QuickSlotButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuickSlotButtonModel.swift; sourceTree = "<group>"; }; @@ -174,7 +205,6 @@ DE9DA8132A97F20E001C0D3B /* ButtonGroupViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonGroupViewController.swift; sourceTree = "<group>"; }; DEB862D32A85124500278FCD /* cleanCache.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = cleanCache.sh; sourceTree = "<group>"; }; DEB862D82A852C4500278FCD /* brewInGoinfre.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = brewInGoinfre.sh; sourceTree = "<group>"; }; - DEB862DB2A85347400278FCD /* Scripts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Scripts.swift; path = Box42/Scripts/Scripts.swift; sourceTree = SOURCE_ROOT; }; DEB862E92A853F7F00278FCD /* BoxWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BoxWindowController.swift; sourceTree = "<group>"; }; DEE0FA952A9A554F00085A65 /* FunctionButtonUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionButtonUI.swift; sourceTree = "<group>"; }; DEF7492E2A85603700D987C8 /* nodeInstall.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = nodeInstall.sh; sourceTree = "<group>"; }; @@ -213,13 +243,14 @@ DE018BB12A5099F900FF0AA3 /* Box42 */ = { isa = PBXGroup; children = ( + DE9456F62A9E44F100B0B768 /* Icon */, DE77BA542A82636500713683 /* Shared */, DEF749302A85655E00D987C8 /* Extensions */, DE018C0E2A509C0C00FF0AA3 /* Menubar */, DE9DA8122A97F1E2001C0D3B /* ButtonGroup */, DE1F1A202A8B50CA00A88DD8 /* Main */, - DEB862D22A8511D600278FCD /* Scripts */, DE874F512A591EC600FC3B77 /* Preferences */, + DEB862D22A8511D600278FCD /* Scripts */, DE018C0C2A509BDF00FF0AA3 /* Resources */, DE018C062A509B9000FF0AA3 /* System */, DE018C082A509BB500FF0AA3 /* WebView */, @@ -245,7 +276,7 @@ DE018C082A509BB500FF0AA3 /* WebView */ = { isa = PBXGroup; children = ( - DE018C0B2A509BC100FF0AA3 /* URL */, + DE7886152A9CCB2B00FE21DD /* Model */, DE0A91662A8E6CA700D1D6F1 /* WebViewManager.swift */, DE018BE92A509B2100FF0AA3 /* WebViewModel.swift */, DE018BE62A509B1E00FF0AA3 /* WebViewController.swift */, @@ -254,14 +285,6 @@ path = WebView; sourceTree = "<group>"; }; - DE018C0B2A509BC100FF0AA3 /* URL */ = { - isa = PBXGroup; - children = ( - DE018BEC2A509B2600FF0AA3 /* URLModel.swift */, - ); - path = URL; - sourceTree = "<group>"; - }; DE018C0C2A509BDF00FF0AA3 /* Resources */ = { isa = PBXGroup; children = ( @@ -299,7 +322,7 @@ isa = PBXGroup; children = ( DE0A919E2A8FA15300D1D6F1 /* View */, - DE0A91972A8F977F00D1D6F1 /* ToolbarViewController.swift */, + DE7885FD2A9C60C300FE21DD /* Controller */, ); path = Toolbar; sourceTree = "<group>"; @@ -307,10 +330,9 @@ DE0A919E2A8FA15300D1D6F1 /* View */ = { isa = PBXGroup; children = ( + DE7886122A9C944900FE21DD /* DisplayURL */, DE0A91A62A8FC66600D1D6F1 /* SideBarLeading.swift */, DE0A91822A8F889000D1D6F1 /* GoHomePageViaToolbar().swift */, - DE3FF3A22A97D2A6009C88EF /* DisplayURLTextfield.swift */, - DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */, DE0A918C2A8F88BC00D1D6F1 /* GoBackInToolbar.swift */, DE0A91892A8F88A900D1D6F1 /* GoForwardInToolbar.swift */, DE0A91852A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift */, @@ -393,14 +415,101 @@ DE77BA542A82636500713683 /* Shared */ = { isa = PBXGroup; children = ( + DE9456FB2A9E4DE600B0B768 /* User */, + DE77BBA82A9DE674006CC98B /* API */, DE1F1A282A8B50E200A88DD8 /* BoxSizeManager.swift */, DE77BA552A82637900713683 /* StateManager.swift */, DE0A91622A8E6A5400D1D6F1 /* Constants.swift */, - DE6332E72A9BBEF800DCFAF6 /* NotifConst.swift */, ); path = Shared; sourceTree = "<group>"; }; + DE77BBA82A9DE674006CC98B /* API */ = { + isa = PBXGroup; + children = ( + DE77BBA92A9DE680006CC98B /* GetUserProfile.swift */, + ); + path = API; + sourceTree = "<group>"; + }; + DE7885FD2A9C60C300FE21DD /* Controller */ = { + isa = PBXGroup; + children = ( + DE0A91972A8F977F00D1D6F1 /* ToolbarViewController.swift */, + ); + path = Controller; + sourceTree = "<group>"; + }; + DE7886082A9C741700FE21DD /* View */ = { + isa = PBXGroup; + children = ( + DE9457142A9E6A3300B0B768 /* Table */, + DE9457122A9E6A2D00B0B768 /* Button */, + ); + path = View; + sourceTree = "<group>"; + }; + DE78860A2A9C76F600FE21DD /* ViewModel */ = { + isa = PBXGroup; + children = ( + DE78860B2A9C770300FE21DD /* ScriptsViewModel.swift */, + ); + path = ViewModel; + sourceTree = "<group>"; + }; + DE78860E2A9C771A00FE21DD /* Model */ = { + isa = PBXGroup; + children = ( + DE77BBE12A9E0F70006CC98B /* Scripts.swift */, + ); + path = Model; + sourceTree = "<group>"; + }; + DE7886122A9C944900FE21DD /* DisplayURL */ = { + isa = PBXGroup; + children = ( + DE3FF3A22A97D2A6009C88EF /* DisplayURLTextfield.swift */, + DE0A918F2A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift */, + ); + path = DisplayURL; + sourceTree = "<group>"; + }; + DE7886152A9CCB2B00FE21DD /* Model */ = { + isa = PBXGroup; + children = ( + DE018BEC2A509B2600FF0AA3 /* URLModel.swift */, + DE77BBD12A9E0AE8006CC98B /* WebViewUI.swift */, + ); + path = Model; + sourceTree = "<group>"; + }; + DE7886242A9D10AC00FE21DD /* Controller */ = { + isa = PBXGroup; + children = ( + DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */, + ); + path = Controller; + sourceTree = "<group>"; + }; + DE7886262A9D184900FE21DD /* Controller */ = { + isa = PBXGroup; + children = ( + DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */, + DE77BBA12A9DDC40006CC98B /* ScriptsFileManager.swift */, + DE77BBCC2A9E0568006CC98B /* ExcuteScripts.swift */, + DE7886272A9D186700FE21DD /* ScriptsViewController.swift */, + ); + path = Controller; + sourceTree = "<group>"; + }; + DE78862B2A9D1A9E00FE21DD /* View */ = { + isa = PBXGroup; + children = ( + DE78862C2A9D1ADE00FE21DD /* PreferencesCell.swift */, + ); + path = View; + sourceTree = "<group>"; + }; DE7F9D482A9B7A4E00F8ACAE /* Vertical Item */ = { isa = PBXGroup; children = ( @@ -413,13 +522,52 @@ DE874F512A591EC600FC3B77 /* Preferences */ = { isa = PBXGroup; children = ( - DE7A25792A6D8CA20043225A /* PreferencesViewController.swift */, + DE78862B2A9D1A9E00FE21DD /* View */, + DE7886242A9D10AC00FE21DD /* Controller */, DE874F532A591F1400FC3B77 /* PreferencesView.swift */, - DE874F562A591F2500FC3B77 /* Icon.swift */, DE2AD3282A824EEB00002D51 /* Accessibility.swift */, DE874F4D2A591DEA00FC3B77 /* Hotkey.swift */, ); - path = Preferences; + name = Preferences; + path = QuickSlot/Preferences; + sourceTree = "<group>"; + }; + DE9456F62A9E44F100B0B768 /* Icon */ = { + isa = PBXGroup; + children = ( + DE9456F72A9E44FD00B0B768 /* IconController.swift */, + ); + path = Icon; + sourceTree = "<group>"; + }; + DE9456FB2A9E4DE600B0B768 /* User */ = { + isa = PBXGroup; + children = ( + DE77BBE92A9E2DDF006CC98B /* UserManager.swift */, + DE7886162A9CCB3B00FE21DD /* UserProfile.swift */, + ); + path = User; + sourceTree = "<group>"; + }; + DE9457122A9E6A2D00B0B768 /* Button */ = { + isa = PBXGroup; + children = ( + DE9457052A9E69C100B0B768 /* ScriptNameLabel.swift */, + DE9457082A9E69D100B0B768 /* ScriptDescriptionsLabel.swift */, + DE94570B2A9E69EB00B0B768 /* ScriptExcuteButton.swift */, + DE94570E2A9E69F200B0B768 /* ScriptDeleteButton.swift */, + DE9457112A9E6A0000B0B768 /* ScriptQuickSlotButton.swift */, + ); + path = Button; + sourceTree = "<group>"; + }; + DE9457142A9E6A3300B0B768 /* Table */ = { + isa = PBXGroup; + children = ( + DE7886032A9C71CB00FE21DD /* ScriptsTableView.swift */, + DE9456FF2A9E5B0900B0B768 /* ScriptCell.swift */, + ); + path = Table; sourceTree = "<group>"; }; DE98E8382A98D48700F8744A /* QuickSlot */ = { @@ -481,8 +629,10 @@ DEB862D22A8511D600278FCD /* Scripts */ = { isa = PBXGroup; children = ( - DEB862DB2A85347400278FCD /* Scripts.swift */, - DE0A917A2A8F0CA800D1D6F1 /* AppleScripts+ShowMessage.swift */, + DE78860E2A9C771A00FE21DD /* Model */, + DE78860A2A9C76F600FE21DD /* ViewModel */, + DE7886082A9C741700FE21DD /* View */, + DE7886262A9D184900FE21DD /* Controller */, ); path = Scripts; sourceTree = "<group>"; @@ -635,6 +785,8 @@ DE4408082A9240300091937A /* BoxFunctionButtonView.swift in Sources */, DE3FF3742A978AB8009C88EF /* WindowMaximizeButton.swift in Sources */, DE3FF3A32A97D2A6009C88EF /* DisplayURLTextfield.swift in Sources */, + DE9457002A9E5B0900B0B768 /* ScriptCell.swift in Sources */, + DE7886042A9C71CB00FE21DD /* ScriptsTableView.swift in Sources */, DE97CA872A9A7407001073DE /* QuickSlotButtonModel.swift in Sources */, DE77BA562A82637900713683 /* StateManager.swift in Sources */, DE1F1A1C2A8B50C500A88DD8 /* BoxBaseContainerViewController.swift in Sources */, @@ -643,36 +795,52 @@ DE98E8552A98EA7900F8744A /* WindowButtonUI.swift in Sources */, DE4407FA2A923E860091937A /* BoxFunctionViewController.swift in Sources */, DE4407FE2A923EA90091937A /* PreferenceButtonView.swift in Sources */, - DE6332E82A9BBEF800DCFAF6 /* NotifConst.swift in Sources */, + DE77BBF02A9E38C6006CC98B /* GetUserProfile.swift in Sources */, DEF749322A85657600D987C8 /* NSScreen.swift in Sources */, DE018BF02A509B2F00FF0AA3 /* MenubarViewController.swift in Sources */, DE6332E42A9BB8F800DCFAF6 /* QuickSlotButtonCollectionViewController.swift in Sources */, + DE9457062A9E69C100B0B768 /* ScriptNameLabel.swift in Sources */, DE77BA512A82580400713683 /* MenubarViewModel.swift in Sources */, DE44080C2A924B520091937A /* BoxFunctionViewGroup.swift in Sources */, DE97CA7C2A9A7199001073DE /* QuickSlotGroupView.swift in Sources */, DE018BE42A509B1700FF0AA3 /* CPU.swift in Sources */, + DE77BBA22A9DDC40006CC98B /* ScriptsFileManager.swift in Sources */, DE874F5F2A5935CC00FC3B77 /* String.swift in Sources */, DE0A91862A8F889F00D1D6F1 /* RefreshPageViaToolbar.swift in Sources */, DE874F4E2A591DEA00FC3B77 /* Hotkey.swift in Sources */, + DE77BBA62A9DDF2B006CC98B /* WebView.swift in Sources */, DE0A91832A8F889000D1D6F1 /* GoHomePageViaToolbar().swift in Sources */, DE6332F22A9BCA2C00DCFAF6 /* QuickSlotScriptsLogicController.swift in Sources */, DE018BB32A5099F900FF0AA3 /* AppDelegate.swift in Sources */, + DE78860C2A9C770300FE21DD /* ScriptsViewModel.swift in Sources */, DE0A91632A8E6A5400D1D6F1 /* Constants.swift in Sources */, + DE7886172A9CCB3B00FE21DD /* UserProfile.swift in Sources */, DE0A91902A8F88CA00D1D6F1 /* DisplayURLInToolbar.swift in Sources */, + DE77BBCD2A9E0568006CC98B /* ExcuteScripts.swift in Sources */, + DE9456F82A9E44FD00B0B768 /* IconController.swift in Sources */, DE018BF32A509B3300FF0AA3 /* MenubarModel.swift in Sources */, DE7A257A2A6D8CA20043225A /* PreferencesViewController.swift in Sources */, DE24E63B2A8FE93900E29F5D /* NSImage.swift in Sources */, + DE94570F2A9E69F200B0B768 /* ScriptDeleteButton.swift in Sources */, DE97CA792A9A6F6A001073DE /* QuickSlotHeaderView.swift in Sources */, DE0A916D2A8E7DD700D1D6F1 /* HoverButton.swift in Sources */, DE97CA862A9A7404001073DE /* QuickSlotViewModel.swift in Sources */, DE3FF3762A978AB8009C88EF /* WindowCloseButton.swift in Sources */, + DE9457092A9E69D100B0B768 /* ScriptDescriptionsLabel.swift in Sources */, + DE77BBD22A9E0AE8006CC98B /* WebViewUI.swift in Sources */, DE3FF3772A978AB8009C88EF /* WindowMinimizeButton.swift in Sources */, DE4408022A923EB60091937A /* PinButtonView.swift in Sources */, + DE77BBE22A9E0F70006CC98B /* Scripts.swift in Sources */, + DE78862D2A9D1ADE00FE21DD /* PreferencesCell.swift in Sources */, DE0A91672A8E6CA700D1D6F1 /* WebViewManager.swift in Sources */, + DE77BBF32A9E38DC006CC98B /* UserManager.swift in Sources */, + DE94570C2A9E69EB00B0B768 /* ScriptExcuteButton.swift in Sources */, + DE9457162A9E6D3000B0B768 /* ScriptQuickSlotButton.swift in Sources */, DE97CA7F2A9A73A9001073DE /* QuickSlotUI.swift in Sources */, DE4408152A92750D0091937A /* keyDown+BoxBaseContainerViewController.swift in Sources */, DE018BED2A509B2600FF0AA3 /* URLModel.swift in Sources */, DE97CA692A9A6364001073DE /* PixelConversion+CGFloat.swift in Sources */, + DE7886282A9D186700FE21DD /* ScriptsViewController.swift in Sources */, DE4408052A923EC00091937A /* QuitButtonView.swift in Sources */, DE0A918A2A8F88A900D1D6F1 /* GoForwardInToolbar.swift in Sources */, DE1F1A1E2A8B50C500A88DD8 /* BoxButtonViewGroup.swift in Sources */, @@ -681,7 +849,6 @@ DE018BDD2A509AEB00FF0AA3 /* EventMonitor.swift in Sources */, DE3FF3672A978A37009C88EF /* HexValue+NSColor.swift in Sources */, DE1F1A292A8B50E200A88DD8 /* BoxSizeManager.swift in Sources */, - DEB862DC2A85347400278FCD /* Scripts.swift in Sources */, DE1F1A1D2A8B50C500A88DD8 /* BoxContentsViewGroup.swift in Sources */, DE24E6352A8FE02A00E29F5D /* MovableContainerView.swift in Sources */, DE1F1A362A8BDDDF00A88DD8 /* StorageConfig.swift in Sources */, @@ -689,9 +856,7 @@ DE24E6382A8FE10400E29F5D /* BoxBaseSplitView.swift in Sources */, DE44081D2A928F760091937A /* Divider.swift in Sources */, DE98E8432A98DDFD00F8744A /* QuickSlotViewController.swift in Sources */, - DE874F572A591F2500FC3B77 /* Icon.swift in Sources */, DE1F1A2E2A8BCC9800A88DD8 /* Storage.swift in Sources */, - DE0A91782A8F014F00D1D6F1 /* WebView.swift in Sources */, DE3FF36B2A978A57009C88EF /* WindowButtonViewController.swift in Sources */, DE1F1A312A8BD68F00A88DD8 /* Double.swift in Sources */, DE0A917F2A8F865400D1D6F1 /* BoxToolbarViewGroup.swift in Sources */, diff --git a/Box42/ButtonGroup/ButtonGroupViewController.swift b/Box42/ButtonGroup/ButtonGroupViewController.swift index 2101feb..d2cb6f1 100644 --- a/Box42/ButtonGroup/ButtonGroupViewController.swift +++ b/Box42/ButtonGroup/ButtonGroupViewController.swift @@ -9,7 +9,7 @@ import Cocoa class ButtonGroupViewController: NSViewController { override func loadView() { -// let ButtonViewGroup = BoxButtonViewGroup() +// let ButtonViewGroup = BoxButtonViewGroup(clickAction: clickAction) let ButtonViewGroup = NSView() ButtonViewGroup.wantsLayer = true ButtonViewGroup.layer?.backgroundColor = NSColor.black.cgColor @@ -20,6 +20,10 @@ class ButtonGroupViewController: NSViewController { super.viewDidLoad() } + func clickAction(_ sender: NSButton?) { + print("click Action") + } + func preference() { print("preference") } diff --git a/Box42/Icon/IconController.swift b/Box42/Icon/IconController.swift new file mode 100644 index 0000000..ca64ddf --- /dev/null +++ b/Box42/Icon/IconController.swift @@ -0,0 +1,26 @@ +// +// IconController.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import Foundation + +class IconController { + let icon = MenubarViewController() + + init() { + NotificationCenter.default.addObserver(self, + selector: #selector(handleUserProfileIconUpdate), + name: .didUpdateUserProfile, + object: nil) + } + + @objc private func handleUserProfileIconUpdate() { + DispatchQueue.main.async { + self.icon.buttonImageChange(UserManager.shared.getUserProfile()?.icon ?? "fox") + } + print("Icon Changed") + } +} diff --git a/Box42/Main/BoxBaseContainerViewController.swift b/Box42/Main/BoxBaseContainerViewController.swift index de5f5c0..49bdf4c 100644 --- a/Box42/Main/BoxBaseContainerViewController.swift +++ b/Box42/Main/BoxBaseContainerViewController.swift @@ -9,6 +9,7 @@ import Cocoa import SnapKit class BoxBaseContainerViewController: NSViewController { + // MARK: - LeftContainer var splitView: BoxBaseSplitView = BoxBaseSplitView() var contentGroup: BoxContentsViewGroup = BoxContentsViewGroup() var toolbarGroupVC: ToolbarViewController = ToolbarViewController() @@ -17,6 +18,11 @@ class BoxBaseContainerViewController: NSViewController { let windowViewGroupVC: WindowButtonViewController = WindowButtonViewController() var leftContainer: MovableContainerView = MovableContainerView() var buttonGroupVC: ButtonGroupViewController = ButtonGroupViewController() + + // MARK: - QuickSlot + var preferenceVC: PreferencesViewController = PreferencesViewController() + var scriptsVC: ScriptsViewController = ScriptsViewController() + weak var menubarVCDelegate: MenubarViewControllerDelegate? // extension override func loadView() { @@ -32,8 +38,11 @@ class BoxBaseContainerViewController: NSViewController { override func viewDidLoad() { self.view.wantsLayer = true + // self.view.layer?.backgroundColor = NSColor(hex: "#FF9548").cgColor self.view.layer?.backgroundColor = NSColor(hex: "#E7E7E7").cgColor + + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) } func BoxButtonViewGroupInit() -> BoxButtonViewGroup { @@ -171,3 +180,29 @@ extension BoxBaseContainerViewController: BoxFunctionViewControllerDelegate { clickBtn(sender: "box") } } + +extension BoxBaseContainerViewController { + @objc func handleButtonTapped(notification: NSNotification) { + if let button = notification.object as? NSButton { + if button.title == QuickSlotUI.title.preferences { + print("Button with title \(button.title) was tapped in BaseVC") + contentGroup.showPreferences() + } + + if button.title == QuickSlotUI.title.scripts { + print("Button with title \(button.title) was tapped in BaseVC") + contentGroup.showScripts() + } + + if button.title == QuickSlotUI.title.user { + print("Button with title \(button.title) was tapped in BaseVC") + contentGroup.removeAllSubviews() + print(WebViewManager.shared.hostingWebView!) + contentGroup.addSubview(WebViewManager.shared.hostingWebView!) + WebViewManager.shared.hostingWebView!.snp.makeConstraints { make in + make.top.bottom.left.right.equalToSuperview() + } + } + } + } +} diff --git a/Box42/Menubar/MenubarModel.swift b/Box42/Menubar/MenubarModel.swift index 24a9a73..b3a612f 100644 --- a/Box42/Menubar/MenubarModel.swift +++ b/Box42/Menubar/MenubarModel.swift @@ -16,7 +16,8 @@ class StatusBar { var isRunning: Bool var interval: Double var alertCount: Int - + var version: Int + init() { self.statusItem = NSStatusItem() self.frames = [NSImage]() @@ -24,5 +25,6 @@ class StatusBar { self.isRunning = false self.interval = 1.0 self.alertCount = 0 + self.version = 0 } } diff --git a/Box42/Menubar/MenubarViewController.swift b/Box42/Menubar/MenubarViewController.swift index c62e462..56f60e5 100644 --- a/Box42/Menubar/MenubarViewController.swift +++ b/Box42/Menubar/MenubarViewController.swift @@ -13,7 +13,7 @@ class MenubarViewController: NSViewController { var statusBarVM = StatusBarViewModel() lazy var eventMonitor: EventMonitor = self.setupEventMonitor() var boxWindowController: BoxWindowController? - + func menubarViewControllerInit() { self.buttonInit() } @@ -47,7 +47,9 @@ class MenubarViewController: NSViewController { } func buttonImageChange(_ img: String) { + self.menubarStopRunning() statusBarVM.changeStatusBarIcon(img) + self.menubarStartRunning() } func buttonActionInit() { @@ -122,7 +124,7 @@ extension MenubarViewController: MenubarViewControllerDelegate { } window.level = .floating } - boxWindowController?.showWindow(sender) + boxWindowController?.showWindow(sender) } } } diff --git a/Box42/Menubar/MenubarViewModel.swift b/Box42/Menubar/MenubarViewModel.swift index 9946f07..80e21ea 100644 --- a/Box42/Menubar/MenubarViewModel.swift +++ b/Box42/Menubar/MenubarViewModel.swift @@ -11,6 +11,7 @@ class StatusBarViewModel { let cpu: CPU let statusBar: StatusBar private var currentAnimationWorkItem: DispatchWorkItem? + private let scheduleQueue = DispatchQueue(label: "animation.scheduleQueue") init () { self.statusBar = StatusBar.shared @@ -23,7 +24,13 @@ class StatusBarViewModel { func changeStatusBarIcon(_ imgName: String) { statusBar.frames.removeAll() - + currentAnimationWorkItem?.cancel() + if statusBar.version == Int.max { + statusBar.version = 0 + } else { + statusBar.version += 1 + } + switch imgName { case "cat": for i in (0...4) {statusBar.frames.append(NSImage(imageLiteralResourceName: "cat_page\(i)"))} case "gon": for i in (1...5) {statusBar.frames.append(NSImage(imageLiteralResourceName: "gon_\(i)"))} @@ -52,25 +59,34 @@ class StatusBarViewModel { self.animate() } } - - func scheduleAnimation() { - currentAnimationWorkItem?.cancel() - let workItem = DispatchWorkItem { [weak self] in - self?.statusBar.statusItem.button?.image = self?.statusBar.frames[self?.statusBar.cnt ?? 0] - self?.statusBar.cnt = ((self?.statusBar.cnt)! + 1) % (self?.statusBar.frames.count ?? 1) + func scheduleAnimation() { + scheduleQueue.sync { + currentAnimationWorkItem?.cancel() - if self?.statusBar.isRunning ?? false { - self?.scheduleAnimation() + let currentVersion = statusBar.version + + let workItem = DispatchWorkItem { [weak self] in + guard self?.statusBar.version == currentVersion else { return } + + self?.statusBar.statusItem.button?.image = self?.statusBar.frames[self?.statusBar.cnt ?? 0] + + if let cnt = self?.statusBar.cnt, let framesCount = self?.statusBar.frames.count { + self?.statusBar.cnt = (cnt + 1) % framesCount + } + + if self?.statusBar.isRunning ?? false { + self?.scheduleAnimation() + } } + + currentAnimationWorkItem = workItem + DispatchQueue.main.asyncAfter(deadline: .now() + statusBar.interval, execute: workItem) } - - currentAnimationWorkItem = workItem - DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + statusBar.interval, execute: workItem) } - + func stopRunning() { - statusBar.isRunning = cpu.StopCPU() + statusBar.isRunning = cpu.stopCPU() currentAnimationWorkItem?.cancel() statusBar.cnt = 0 } diff --git a/Box42/Preferences/Icon.swift b/Box42/Preferences/Icon.swift deleted file mode 100644 index d256436..0000000 --- a/Box42/Preferences/Icon.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// Icon.swift -// Box42 -// -// Created by Chanhee Kim on 7/8/23. -// - -struct iconModel { - var icon: [String] = [ - "Cat", - "gam", - "gon", - "gun", - "lee", - "Box", - "box_oc", - "42" - ] -} diff --git a/Box42/Preferences/PreferencesViewController.swift b/Box42/Preferences/PreferencesViewController.swift index 5a6c36d..e132672 100644 --- a/Box42/Preferences/PreferencesViewController.swift +++ b/Box42/Preferences/PreferencesViewController.swift @@ -48,10 +48,6 @@ class PreferencesViewController: NSViewController { var stackBox: [NSView] = [] - let icons = iconModel().icon - icons.forEach { (icon) in - stackBox.append(NSButton(title: "Change \(icon) Icon", target: self, action: #selector(changeIconButtonPressed))) - } let scripts = Scripts().info scripts.forEach { (script) in diff --git a/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift index 1038e76..41bc732 100644 --- a/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift +++ b/Box42/QuickSlot/Controller/QuickSlotScriptsLogicController.swift @@ -12,16 +12,16 @@ class ScriptsLogicController { static let shared = ScriptsLogicController() private init() { - NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) } @objc func handleButtonTapped(notification: NSNotification) { if let button = notification.object as? NSButton { - let buttonTitle = button.title // 메인 스레드에서 타이틀을 캡쳐 + let buttonTitle = button.title print("Button with title \(buttonTitle) was tapped") DispatchQueue.global(qos: .background).async { [weak self] in - if buttonTitle == "clean" { + if buttonTitle == QuickSlotUI.title.clean { self?.executeCleanScript() } } @@ -53,5 +53,4 @@ class ScriptsLogicController { } } } - } diff --git a/Box42/QuickSlot/Controller/QuickSlotViewController.swift b/Box42/QuickSlot/Controller/QuickSlotViewController.swift index 177b5f9..e60f49a 100644 --- a/Box42/QuickSlot/Controller/QuickSlotViewController.swift +++ b/Box42/QuickSlot/Controller/QuickSlotViewController.swift @@ -15,7 +15,7 @@ class QuickSlotViewController: NSViewController { let quickSlotViewGroup = QuickSlotGroupView() quickSlotViewGroup.headerAction = headerAction - NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handleButtonTapped), name: .collectionButtonTapped, object: nil) self.view = quickSlotViewGroup } @@ -26,7 +26,7 @@ class QuickSlotViewController: NSViewController { @objc func handleButtonTapped(notification: NSNotification) { if let button = notification.object as? NSButton { - print("Button with title \(button.title) was tapped") + print("Button with title \(button.title) was tapped in QuickSlotView") } } } diff --git a/Box42/QuickSlot/Model/QuickSlotButtonModel.swift b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift index 8049fc7..2929b82 100644 --- a/Box42/QuickSlot/Model/QuickSlotButtonModel.swift +++ b/Box42/QuickSlot/Model/QuickSlotButtonModel.swift @@ -12,8 +12,8 @@ struct QuickSlotButtonModel { let id: UUID var title: String - init(title: String = "Default") { - self.id = UUID() + init(id: UUID = UUID(), title: String = "Default") { + self.id = id self.title = title } } diff --git a/Box42/QuickSlot/Model/QuickSlotUI.swift b/Box42/QuickSlot/Model/QuickSlotUI.swift index c61c2cf..096bcbc 100644 --- a/Box42/QuickSlot/Model/QuickSlotUI.swift +++ b/Box42/QuickSlot/Model/QuickSlotUI.swift @@ -21,4 +21,11 @@ enum QuickSlotUI { enum color { // static let pinText = NSColor(hex: "#696969") } + + enum title { + static let clean = "Clean" + static let preferences = "Preferences" + static let scripts = "Scripts" + static let user = "User" + } } diff --git a/Box42/Preferences/Accessibility.swift b/Box42/QuickSlot/Preferences/Accessibility.swift similarity index 100% rename from Box42/Preferences/Accessibility.swift rename to Box42/QuickSlot/Preferences/Accessibility.swift diff --git a/Box42/QuickSlot/Preferences/Controller/PreferencesViewController.swift b/Box42/QuickSlot/Preferences/Controller/PreferencesViewController.swift new file mode 100644 index 0000000..1fede64 --- /dev/null +++ b/Box42/QuickSlot/Preferences/Controller/PreferencesViewController.swift @@ -0,0 +1,61 @@ +// +// PreferencesViewController.swift +// Box42 +// +// Created by Chanhee Kim on 7/24/23. +// + +import Cocoa +import SnapKit + +class PreferencesViewController: NSViewController { + var prefTableView : NSTableView? + + override func loadView() { + self.view = NSView() + self.view.wantsLayer = true + self.view.layer?.backgroundColor = NSColor.blue.cgColor + + prefTableView = NSTableView(frame: .zero) + // Column 추가 + let column1 = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("Column1")) + column1.width = 100.0 + column1.title = "Column 1" + prefTableView?.addTableColumn(column1) + + // delegate와 dataSource 설정 + prefTableView?.delegate = self + prefTableView?.dataSource = self + + // TableView를 스크롤 뷰에 추가 (일반적으로 NSTableView는 NSScrollView 안에 위치합니다) + let scrollView = NSScrollView() + scrollView.documentView = prefTableView + self.view.addSubview(scrollView) + + + scrollView.snp.makeConstraints({ make in + make.edges.equalToSuperview() + }) + + prefTableView?.snp.makeConstraints({ make in + make.edges.equalToSuperview() + }) + } +} + +extension PreferencesViewController: NSTableViewDelegate, NSTableViewDataSource { + func numberOfRows(in tableView: NSTableView) -> Int { + return 10 // 총 로우 수 + } + + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier("MyCell"), owner: self) as? NSTableCellView ?? NSTableCellView() + cell.textField?.stringValue = "Row \(row), Column \(tableColumn?.identifier ?? NSUserInterfaceItemIdentifier(""))" + return cell + } + + func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { + return 44.0 // 셀 높이를 44로 설정 + } +} + diff --git a/Box42/Preferences/Hotkey.swift b/Box42/QuickSlot/Preferences/Hotkey.swift similarity index 100% rename from Box42/Preferences/Hotkey.swift rename to Box42/QuickSlot/Preferences/Hotkey.swift diff --git a/Box42/Preferences/PreferencesView.swift b/Box42/QuickSlot/Preferences/PreferencesView.swift similarity index 100% rename from Box42/Preferences/PreferencesView.swift rename to Box42/QuickSlot/Preferences/PreferencesView.swift diff --git a/Box42/QuickSlot/Preferences/View/PreferencesCell.swift b/Box42/QuickSlot/Preferences/View/PreferencesCell.swift new file mode 100644 index 0000000..f9dfadb --- /dev/null +++ b/Box42/QuickSlot/Preferences/View/PreferencesCell.swift @@ -0,0 +1,31 @@ +// +// PreferencesCell.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Cocoa +import SnapKit + +class PreferencesCell: NSTableCellView { + + var baseContainerView: NSView = { + let baseView = NSView() + baseView.wantsLayer = true + baseView.layer?.backgroundColor = NSColor.yellow.cgColor + return baseView + }() + + override func awakeFromNib() { + super.awakeFromNib() + self.setupViews() + } + + private func setupViews() { + self.addSubview(baseContainerView) + baseContainerView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} diff --git a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift index edfaf7f..52b2697 100644 --- a/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift +++ b/Box42/QuickSlot/View/ButtonCollectionView/QuickSlotButtonCollectionViewController.swift @@ -10,7 +10,7 @@ import Combine class QuickSlotButtonCollectionViewController: NSViewController { @IBOutlet weak var quickSlotButtonCollectionView: NSCollectionView! - var viewModel: QuickSlotViewModel = QuickSlotViewModel() + var viewModel = QuickSlotViewModel.shared var cancellables: Set<AnyCancellable> = [] override func viewDidLoad() { @@ -60,10 +60,10 @@ class QuickSlotButtonCollectionViewController: NSViewController { quickSlotButtonCollectionView.layer?.borderWidth = 0 quickSlotButtonCollectionView.layer?.borderColor = NSColor.clear.cgColor quickSlotButtonCollectionView.backgroundColors = [NSColor.clear] - + if let scrollView = quickSlotButtonCollectionView.enclosingScrollView { -// scrollView.hasVerticalScroller = false -// scrollView.hasHorizontalScroller = false + // scrollView.hasVerticalScroller = false + // scrollView.hasHorizontalScroller = false scrollView.backgroundColor = NSColor.clear scrollView.drawsBackground = false } @@ -86,11 +86,10 @@ extension QuickSlotButtonCollectionViewController: NSCollectionViewDelegate, NSC func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { 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 = "\(indexPath)" btn.title = buttonModel.title btn.action = #selector(collectionButtonTapped) btn.target = self @@ -105,6 +104,11 @@ extension QuickSlotButtonCollectionViewController: NSCollectionViewDelegate, NSC extension QuickSlotButtonCollectionViewController { @objc func collectionButtonTapped(_ sender: NSButton) { - NotificationCenter.default.post(name: NSNotification.Name(NotifConst.object.collectionButtonTapped), object: sender) + NotificationCenter.default.post(name: .collectionButtonTapped, object: sender) } } + +// MARK: - Notification Name collectionButtonTapped +extension Notification.Name { + static let collectionButtonTapped = Notification.Name("collectionButtonTapped") +} diff --git a/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift index fe3e1da..0d16006 100644 --- a/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift +++ b/Box42/QuickSlot/ViewModel/QuickSlotViewModel.swift @@ -9,21 +9,26 @@ import AppKit import Combine class QuickSlotViewModel { + static let shared = QuickSlotViewModel() @Published var buttons: [QuickSlotButtonModel] = [] - init() { - let button1 = QuickSlotButtonModel(title: "clean") - let button2 = QuickSlotButtonModel(title: "icons") - let button3 = QuickSlotButtonModel(title: "scripts") + private init() { + let button1 = QuickSlotButtonModel(title: QuickSlotUI.title.clean) + let button2 = QuickSlotButtonModel(title: QuickSlotUI.title.preferences) + let button3 = QuickSlotButtonModel(title: QuickSlotUI.title.scripts) + let button4 = QuickSlotButtonModel(title: QuickSlotUI.title.user) - buttons = [button1, button2, button3] + buttons = [button1, button2, button3, button4] } - + func addButton(_ button: QuickSlotButtonModel) { - buttons.append(button) + if buttons.count > 7 { return } + if !buttons.contains(where: { $0.id == button.id }) { + buttons.append(button) + } } - func removeButton(id: UUID) { + func removeButton(_ id: UUID) { buttons.removeAll { $0.id == id } } diff --git a/Box42/Resources/AppDelegate.swift b/Box42/Resources/AppDelegate.swift index 65fb651..5555c9b 100644 --- a/Box42/Resources/AppDelegate.swift +++ b/Box42/Resources/AppDelegate.swift @@ -10,6 +10,7 @@ import Cocoa @main class AppDelegate: NSObject, NSApplicationDelegate { var menubarController = MenubarViewController() + var iconController: IconController? lazy var storage = Storage() func applicationWillFinishLaunching(_ notification: Notification) { @@ -18,12 +19,18 @@ class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { menubarController.menubarViewControllerStart() + iconController = IconController() // alertAccessibility() // hotkey() // storage.storageTimerEvent() + _ = UserManager.shared _ = ScriptsLogicController.shared + // MARK: - 유저데이터 동기화 +// WebViewManager.shared.getCookie() +// API.getUserProfile(WebViewManager.shared.getCookieWebKit) + _ = QuickSlotViewModel.shared } func applicationWillTerminate(_ aNotification: Notification) { diff --git a/Box42/Scripts/AppleScripts+ShowMessage.swift b/Box42/Scripts/Controller/AppleScripts+ShowMessage.swift similarity index 100% rename from Box42/Scripts/AppleScripts+ShowMessage.swift rename to Box42/Scripts/Controller/AppleScripts+ShowMessage.swift diff --git a/Box42/Scripts/Controller/ExcuteScripts.swift b/Box42/Scripts/Controller/ExcuteScripts.swift new file mode 100644 index 0000000..cf36f28 --- /dev/null +++ b/Box42/Scripts/Controller/ExcuteScripts.swift @@ -0,0 +1,17 @@ +// +// ExcuteScripts.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Foundation + +class ExcuteScripts { + static func executeShellScript(path: String) { + let task = Process() + task.launchPath = "/bin/sh" + task.arguments = [path] + task.launch() + } +} diff --git a/Box42/Scripts/Controller/ScriptsFileManager.swift b/Box42/Scripts/Controller/ScriptsFileManager.swift new file mode 100644 index 0000000..5b4c69f --- /dev/null +++ b/Box42/Scripts/Controller/ScriptsFileManager.swift @@ -0,0 +1,49 @@ +// +// ScriptsFileManager.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Foundation + +class ScriptsFileManager { + static func downloadFile(from URLString: String) { + let fileManager = FileManager.default + let pathComponent = URLString.split(separator: "/").map { String($0) }.last ?? "" + let documentsURL = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) + let savedURL = documentsURL?.appendingPathComponent(pathComponent) + + if let savedURL = savedURL, fileManager.fileExists(atPath: savedURL.path) { + print("File already exists, executing...") + ExcuteScripts.executeShellScript(path: savedURL.path) + return + } + + guard let url = URL(string: URLString) else { + print("Invalid URL: \(URLString)") + return + } + + let task = URLSession.shared.downloadTask(with: url) { (location, _, error) in + guard let location = location else { + print("Download failed: \(error?.localizedDescription ?? "Unknown error")") + return + } + + do { + let documentsURL = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) + let savedURL = documentsURL.appendingPathComponent(pathComponent) + try fileManager.moveItem(at: location, to: savedURL) + + print("Saved URL: ", savedURL) + + ExcuteScripts.executeShellScript(path: savedURL.path) + + } catch { + print("File error: \(error)") + } + } + task.resume() + } +} diff --git a/Box42/Scripts/Controller/ScriptsViewController.swift b/Box42/Scripts/Controller/ScriptsViewController.swift new file mode 100644 index 0000000..ed12375 --- /dev/null +++ b/Box42/Scripts/Controller/ScriptsViewController.swift @@ -0,0 +1,40 @@ +// +// ScriptsViewController.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Cocoa +import Foundation + +class ScriptsViewController: NSViewController { + var scriptsTableView: ScriptsTableView? + var viewModel: ScriptViewModel? = ScriptViewModel() { + didSet { + scriptsTableView?.viewModel = viewModel + } + } + + override func loadView() { + self.view = NSView() + self.view.wantsLayer = true + self.view.layer?.backgroundColor = NSColor.blue.cgColor + + scriptsTableView = ScriptsTableView(frame: .zero) + scriptsTableView?.setup() + scriptsTableView?.viewModel = viewModel + + let scrollView = NSScrollView() + scrollView.documentView = scriptsTableView + self.view.addSubview(scrollView) + + scrollView.snp.makeConstraints({ make in + make.edges.equalToSuperview() + }) + + scriptsTableView?.snp.makeConstraints({ make in + make.edges.equalToSuperview() + }) + } +} diff --git a/Box42/Scripts/Scripts.swift b/Box42/Scripts/Model/Scripts.swift similarity index 58% rename from Box42/Scripts/Scripts.swift rename to Box42/Scripts/Model/Scripts.swift index 2feac26..7671c3d 100644 --- a/Box42/Scripts/Scripts.swift +++ b/Box42/Scripts/Model/Scripts.swift @@ -7,12 +7,11 @@ import Foundation -struct Scripts { - var info: [(name: String, description: String)] = [("cleanCache", "cleaning cache"), - ("brewInGoinfre", "brew download in goinfre")] +struct Scripts: Codable { + var info: [Script] } -struct Script { +struct Script: Codable { var id: UUID var name: String var description: String diff --git a/Box42/Scripts/View/Button/ScriptDeleteButton.swift b/Box42/Scripts/View/Button/ScriptDeleteButton.swift new file mode 100644 index 0000000..3d592c8 --- /dev/null +++ b/Box42/Scripts/View/Button/ScriptDeleteButton.swift @@ -0,0 +1,68 @@ +// +// ScriptDeleteButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import AppKit + +class ScriptDeleteButton: NSButton { + + init() { + super.init(frame: NSRect(x: 0, y: 0, width: 53, height: 40)) + + self.title = "삭제" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.toValue = WindowButtonUI.color.close + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.close + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius / 2 + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.close + bgColorAnimation.toValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + } +} diff --git a/Box42/Scripts/View/Button/ScriptDescriptionsLabel.swift b/Box42/Scripts/View/Button/ScriptDescriptionsLabel.swift new file mode 100644 index 0000000..9ed8826 --- /dev/null +++ b/Box42/Scripts/View/Button/ScriptDescriptionsLabel.swift @@ -0,0 +1,8 @@ +// +// ScriptDescriptionsLabel.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import Foundation diff --git a/Box42/Scripts/View/Button/ScriptExcuteButton.swift b/Box42/Scripts/View/Button/ScriptExcuteButton.swift new file mode 100644 index 0000000..e6d3b0c --- /dev/null +++ b/Box42/Scripts/View/Button/ScriptExcuteButton.swift @@ -0,0 +1,68 @@ +// +// ScriptExcuteButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import AppKit + +class ScriptExcuteButton: NSButton { + + init() { + super.init(frame: NSRect(x: 0, y: 0, width: 70, height: 40)) + + self.title = "실행하기" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.toValue = WindowButtonUI.color.maximize + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.maximize + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius / 2 + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.maximize + bgColorAnimation.toValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + } +} diff --git a/Box42/Scripts/View/Button/ScriptNameLabel.swift b/Box42/Scripts/View/Button/ScriptNameLabel.swift new file mode 100644 index 0000000..e4a9af7 --- /dev/null +++ b/Box42/Scripts/View/Button/ScriptNameLabel.swift @@ -0,0 +1,8 @@ +// +// ScriptNameLabel.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import Foundation diff --git a/Box42/Scripts/View/Button/ScriptQuickSlotButton.swift b/Box42/Scripts/View/Button/ScriptQuickSlotButton.swift new file mode 100644 index 0000000..a8d2420 --- /dev/null +++ b/Box42/Scripts/View/Button/ScriptQuickSlotButton.swift @@ -0,0 +1,94 @@ +// +// ScriptQuickSlotButton.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import AppKit + +class ScriptQuickSlotButton: NSButton { + + init() { + super.init(frame: NSRect(x: 0, y: 0, width: 53, height: 40)) + + self.title = "퀵슬롯" + self.isBordered = false + self.wantsLayer = true + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + + let trackingArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil) + self.addTrackingArea(trackingArea) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func mouseEntered(with event: NSEvent) { + super.mouseEntered(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.toValue = WindowButtonUI.color.minimize + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.minimize + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius / 2 + } + + override func mouseExited(with event: NSEvent) { + super.mouseExited(with: event) + + let bgColorAnimation = CABasicAnimation(keyPath: "backgroundColor") + bgColorAnimation.fromValue = WindowButtonUI.color.minimize + bgColorAnimation.toValue = WindowButtonUI.color.opacityWhite + bgColorAnimation.duration = WindowButtonUI.animation.duration + + let cornerAnimation = CABasicAnimation(keyPath: "cornerRadius") + cornerAnimation.fromValue = WindowButtonUI.size.cornerRadius / 2 + cornerAnimation.toValue = WindowButtonUI.size.cornerRadius + cornerAnimation.duration = WindowButtonUI.animation.duration + + self.layer?.add(bgColorAnimation, forKey: "backgroundColorAnimation") + self.layer?.add(cornerAnimation, forKey: "cornerRadiusAnimation") + + self.layer?.backgroundColor = WindowButtonUI.color.opacityWhite + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + } + + override func mouseDown(with event: NSEvent) { + super.mouseDown(with: event) + + // 윈도우의 크기와 위치 정보를 가져옴 + guard self.window != nil else { + return + } + + // 현재 버튼의 위치를 윈도우 기준으로 변환 + let initialLocation = self.frame.origin + + // 윈도우의 왼쪽 아래 모서리를 최종 목표 위치로 설정 + let finalLocation = NSPoint(x: 0, y: 0) + + // 애니메이션 블록 + NSAnimationContext.runAnimationGroup({ context in + context.duration = 1 // 애니메이션 지속 시간 + + // 애니메이션 적용 + self.animator().setFrameOrigin(finalLocation) + }, completionHandler: { + // 애니메이션 완료 후, 버튼을 원래 위치로 되돌림 + self.setFrameOrigin(initialLocation) + }) + } +} diff --git a/Box42/Scripts/View/Table/ScriptCell.swift b/Box42/Scripts/View/Table/ScriptCell.swift new file mode 100644 index 0000000..bf75e4d --- /dev/null +++ b/Box42/Scripts/View/Table/ScriptCell.swift @@ -0,0 +1,108 @@ +// +// ScriptCell.swift +// Box42 +// +// Created by Chanhee Kim on 8/30/23. +// + +import AppKit +import SnapKit + +class ScriptCell: NSTableCellView { + var nameLabel: NSTextField = NSTextField() + var descriptionLabel: NSTextField = NSTextField() + var excuteButton: ScriptExcuteButton = ScriptExcuteButton() + var deleteButton: ScriptDeleteButton = ScriptDeleteButton() + var quickSlotButton: ScriptQuickSlotButton = ScriptQuickSlotButton() + + var viewModel: ScriptViewModel? + var script: Script? + + override init(frame frameRect: NSRect) { + super.init(frame: frameRect) + setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func setupUI() { + addSubview(nameLabel) + addSubview(descriptionLabel) + addSubview(quickSlotButton) + addSubview(excuteButton) + addSubview(deleteButton) + + nameLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(16) + make.width.lessThanOrEqualTo(200).priority(.high) // 최대 너비와 우선순위 설정 + } + + deleteButton.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-16) + make.width.equalTo(53) + make.height.equalTo(40) + } + + excuteButton.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalTo(deleteButton.snp.left).offset(-8) + make.width.equalTo(70) + make.height.equalTo(40) + } + + quickSlotButton.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalTo(excuteButton.snp.left).offset(-8) + make.width.equalTo(53) + make.height.equalTo(40) + } + + descriptionLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalTo(nameLabel.snp.right).offset(8) + make.right.lessThanOrEqualTo(quickSlotButton.snp.left).offset(-8) + make.width.greaterThanOrEqualTo(100).priority(.low) // 최소 너비와 낮은 우선순위 설정 + } + } + + + + func configure(with script: Script, viewModel: ScriptViewModel?) { + self.script = script + self.viewModel = viewModel + nameLabel.stringValue = script.name + descriptionLabel.stringValue = script.description + + deleteButton.target = self + deleteButton.action = #selector(deleteButtonClicked) + + excuteButton.target = self + excuteButton.action = #selector(excuteButtonClicked) + + quickSlotButton.target = self + quickSlotButton.action = #selector(quickSlotButtonclicked) + + } + + @objc func deleteButtonClicked() { + if let id = script?.id { + viewModel?.deleteScript(id: id) + } + } + + @objc func excuteButtonClicked() { + if let id = script?.id { + viewModel?.excuteScript(id: id) + } + } + + @objc func quickSlotButtonclicked() { + if let id = script?.id { + viewModel?.quickSlotScript(id: id) + } + } +} diff --git a/Box42/Scripts/View/Table/ScriptsTableView.swift b/Box42/Scripts/View/Table/ScriptsTableView.swift new file mode 100644 index 0000000..44c155c --- /dev/null +++ b/Box42/Scripts/View/Table/ScriptsTableView.swift @@ -0,0 +1,57 @@ +// +// ScriptsTableView.swift +// Box42 +// +// Created by Chanhee Kim on 8/28/23. +// + +import AppKit +import SnapKit +import Combine + +class ScriptsTableView: NSTableView { + var viewModel: ScriptViewModel? { + didSet { + setupBindings() + } + } + + var cancellables: Set<AnyCancellable> = [] + + private func setupBindings() { + viewModel?.$scripts.sink(receiveValue: { [weak self] _ in + DispatchQueue.main.async { + self?.reloadData() + } + }).store(in: &cancellables) + } + + func setup() { + self.delegate = self + self.dataSource = self + + let column1 = NSTableColumn(identifier: NSUserInterfaceItemIdentifier("Column1")) + column1.width = 100.0 + column1.title = "Column 1" + self.addTableColumn(column1) + } +} + +extension ScriptsTableView: NSTableViewDelegate, NSTableViewDataSource { + + func numberOfRows(in tableView: NSTableView) -> Int { + return viewModel?.scripts.count ?? 0 + } + + func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? { + let cell = ScriptCell(frame: .zero) // 또는 원하는 frame 값을 설정 + if let script = viewModel?.scripts[row] { + cell.configure(with: script, viewModel: viewModel) + } + return cell // 이 줄을 추가 + } + + func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat { + return 44.0 // 셀 높이를 44로 설정 + } +} diff --git a/Box42/Scripts/ViewModel/ScriptsViewModel.swift b/Box42/Scripts/ViewModel/ScriptsViewModel.swift new file mode 100644 index 0000000..75955fd --- /dev/null +++ b/Box42/Scripts/ViewModel/ScriptsViewModel.swift @@ -0,0 +1,55 @@ +// +// ScriptViewModel.swift +// Box42 +// +// Created by Chanhee Kim on 8/28/23. +// + +import AppKit +import Combine + +class ScriptViewModel: NSObject { + @Published var scripts: [Script] = [] + + override init() { + self.scripts = [ + Script(name: "cleanCache", description: "Cleaning cache"), + Script(name: "brewInGoinfre", description: "Brew download in goinfre") + ] + } + + // Create + func addScript(name: String, description: String) { + let newScript = Script(name: name, description: description) + scripts.append(newScript) + } + + // Read + func excuteScript(id: UUID) { + if let index = scripts.firstIndex(where: { $0.id == id }) { + ExcuteScripts.executeShellScript(path: scripts[index].name) + } + } + + // Update + func updateScript(id: UUID, newName: String, newDescription: String) { + if let index = scripts.firstIndex(where: { $0.id == id }) { + scripts[index].name = newName + scripts[index].description = newDescription + } + } + + // Delete + func deleteScript(id: UUID) { + scripts.removeAll(where: { $0.id == id }) + QuickSlotViewModel.shared.removeButton(id) + } + + func quickSlotScript(id: UUID) { + if let index = scripts.firstIndex(where: { $0.id == id }) { + let button = QuickSlotButtonModel(id: id, title: scripts[index].name) + QuickSlotViewModel.shared.addButton(button) + } + } + +} diff --git a/Box42/Shared/API/GetUserProfile.swift b/Box42/Shared/API/GetUserProfile.swift new file mode 100644 index 0000000..8fa41d1 --- /dev/null +++ b/Box42/Shared/API/GetUserProfile.swift @@ -0,0 +1,51 @@ +// +// UserProfile.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import WebKit + +class API { + // MARK: - 유저 정보 (Back) GET: https://api.42box.site/user-service/users/me + // return : 실패 nil 반환 + // : 성공 UserProfile() + static func getUserProfile(_ webView: WKWebView) { + var userProfile: UserProfile? + + webView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in + let cookieStorage = HTTPCookieStorage.shared + + for cookie in cookies { +// print("\(cookie.name) = \(cookie.value)") + cookieStorage.setCookie(cookie) + } + + var request = URLRequest(url: URL(string: "https://api.42box.site/user-service/users/me")!) + request.httpShouldHandleCookies = true + let task = URLSession.shared.dataTask(with: request) { (data, response, error) in + if let error = error { + print("Error: \(error)") + return + } + + guard let data = data else { + print("No data received.") + return + } + + do { + userProfile = try JSONDecoder().decode(UserProfile.self, from: data) + + print(">> MacOS Get", userProfile) + UserManager.shared.updateUserProfile(newProfile: userProfile) + + } catch let jsonError { + print("JSON Parsing Error: \(jsonError)") + } + } + task.resume() + } + } +} diff --git a/Box42/Shared/Constants.swift b/Box42/Shared/Constants.swift index e0af4fc..ffc3f1f 100644 --- a/Box42/Shared/Constants.swift +++ b/Box42/Shared/Constants.swift @@ -8,8 +8,8 @@ enum Constants { enum url { static let initialName = "home" -// static let initialPage = "https://42box.kr" - static let initialPage = "https://profile.intra.42.fr/" + static let initialPage = "https://42box.kr" +// static let initialPage = "https://profile.intra.42.fr/" } enum UI { diff --git a/Box42/Shared/NotifConst.swift b/Box42/Shared/NotifConst.swift deleted file mode 100644 index fb42e6a..0000000 --- a/Box42/Shared/NotifConst.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// ConstantsNotificationCenter.swift -// Box42 -// -// Created by Chanhee Kim on 8/28/23. -// - -enum NotifConst { // NotificationCenter Constants - enum object { - static let collectionButtonTapped = "collectionButtonTapped" - } - - enum userInfo { - - } -} diff --git a/Box42/Shared/User/UserManager.swift b/Box42/Shared/User/UserManager.swift new file mode 100644 index 0000000..ec61323 --- /dev/null +++ b/Box42/Shared/User/UserManager.swift @@ -0,0 +1,86 @@ +// +// UserManager.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Foundation + +class UserManager { + static let shared = UserManager() + private var userProfile: UserProfile? { + didSet { + NotificationCenter.default.post(name: .didUpdateUserProfile, object: nil) + } + } + private let fileBookmarkKey = "myFileAppSandBox" + + private init() {} + + // Create + func createUserProfile(_ createProfile: UserProfile) { + self.userProfile = createProfile + } + + // Read + func getUserProfile() -> UserProfile? { + return self.userProfile + } + + // Update + func updateUserProfile(newProfile: UserProfile?) { + if let new = newProfile { + self.userProfile = new + } else { + self.userProfile = UserProfile.defaultProfile() + } + } + + // Delete + func deleteUserProfile() { + self.userProfile = nil + } + + func userDefaults() { + let fileURL = URL(fileURLWithPath: "~") + + do { + let bookmarkData = try fileURL.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil) + UserDefaults.standard.set(bookmarkData, forKey: fileBookmarkKey) + } catch { + print("Failed to create bookmark data for file: \(error)") + // TODO: Handle this error appropriately in your app. + } + } + + func userDefaultsRestore() { + if let bookmarkData = UserDefaults.standard.data(forKey: fileBookmarkKey) { + var isStale = false + + do { + let restoredURL = try URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, + relativeTo:nil, + bookmarkDataIsStale:&isStale) + + if isStale { + // Refresh the bookmark data and save it. + userDefaults() + } + + if restoredURL.startAccessingSecurityScopedResource() { + restoredURL.stopAccessingSecurityScopedResource() + } + + } catch { + print("Failed to resolve bookmark data: \(error)") + // TODO : Handle this error appropriately in your app. + } + } + } +} + +// MARK: - Notification Name didUpdateUserProfile +extension Notification.Name { + static let didUpdateUserProfile = Notification.Name("didUpdateUserProfile") +} diff --git a/Box42/Shared/User/UserProfile.swift b/Box42/Shared/User/UserProfile.swift new file mode 100644 index 0000000..839b5c7 --- /dev/null +++ b/Box42/Shared/User/UserProfile.swift @@ -0,0 +1,48 @@ +// +// UserProfile.swift +// Box42 +// +// Created by Chanhee Kim on 8/28/23. +// + +struct UserProfile: Codable { + let uuid: String + let nickname: String + let theme: Int + let icon: String + let urlList: [URLItem] + let statusMessage: String + let profileImageUrl: String + let profileImagePath: String +} + +struct URLItem: Codable { + let name: String + let url: String +} + +extension UserProfile { + static func defaultProfile() -> UserProfile { + return UserProfile( + uuid: "fox", + nickname: "fox", + theme: 0, + icon: "fox", + urlList: [URLItem(name: "home", url: "https://42box.kr/"), + URLItem(name: "23Coaltheme", url: "https://42box.github.io/front-end/"), + URLItem(name: "loopback", url: "http://127.0.0.1:3000/"), + URLItem(name: "Box 42", url: "https://42box.github.io/front-end/#/box"), + URLItem(name: "Intra 42", url: "https://intra.42.fr"), + URLItem(name: "Jiphyeonjeon", url: "https://42library.kr"), + URLItem(name: "42STAT", url: "https://stat.42seoul.kr/home"), + URLItem(name: "24Hane", url: "https://24hoursarenotenough.42seoul.kr"), + URLItem(name: "80kCoding", url: "https://80000coding.oopy.io"), + URLItem(name: "where42", url: "https://www.where42.kr"), + URLItem(name: "cabi", url: "https://cabi.42seoul.io/"), + URLItem(name: "42gg", url: "https://42gg.kr/")], + 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" + ) + } +} diff --git a/Box42/System/CPU.swift b/Box42/System/CPU.swift index 9f70003..f11c010 100644 --- a/Box42/System/CPU.swift +++ b/Box42/System/CPU.swift @@ -58,7 +58,7 @@ class CPU { return true } - func StopCPU() -> Bool { + func stopCPU() -> Bool { self.cpuTimer?.invalidate() return false } diff --git a/Box42/Toolbar/ToolbarViewController.swift b/Box42/Toolbar/Controller/ToolbarViewController.swift similarity index 100% rename from Box42/Toolbar/ToolbarViewController.swift rename to Box42/Toolbar/Controller/ToolbarViewController.swift diff --git a/Box42/Toolbar/View/DisplayURLInToolbar.swift b/Box42/Toolbar/View/DisplayURL/DisplayURLInToolbar.swift similarity index 98% rename from Box42/Toolbar/View/DisplayURLInToolbar.swift rename to Box42/Toolbar/View/DisplayURL/DisplayURLInToolbar.swift index 59ff65b..f6b942a 100644 --- a/Box42/Toolbar/View/DisplayURLInToolbar.swift +++ b/Box42/Toolbar/View/DisplayURL/DisplayURLInToolbar.swift @@ -87,6 +87,7 @@ extension DisplayURLInToolbar: WKNavigationDelegate { if showURLString.count > 1 { URLTextfield.stringValue = (showURLString[1] ?? "") } + print(originalString) } } } diff --git a/Box42/Toolbar/View/DisplayURLTextfield.swift b/Box42/Toolbar/View/DisplayURL/DisplayURLTextfield.swift similarity index 100% rename from Box42/Toolbar/View/DisplayURLTextfield.swift rename to Box42/Toolbar/View/DisplayURL/DisplayURLTextfield.swift diff --git a/Box42/View/BoxContentsViewGroup.swift b/Box42/View/BoxContentsViewGroup.swift index 1eb1ee5..959fb80 100644 --- a/Box42/View/BoxContentsViewGroup.swift +++ b/Box42/View/BoxContentsViewGroup.swift @@ -11,19 +11,15 @@ import SnapKit class BoxContentsViewGroup: NSView { var webVC: WebViewController? var preferencesVC = PreferencesViewController() + var scriptsVC = ScriptsViewController() init() { + super.init(frame: .zero) webVC = WebViewController(nibName: nil, bundle: nil) - - super.init(frame: NSRect(x: 0, y: 0, width: BoxSizeManager.shared.size.width - BoxSizeManager.shared.buttonGroupSize.width, height: BoxSizeManager.shared.buttonGroupSize.height)) - - self.frame.size.width = BoxSizeManager.shared.size.width - BoxSizeManager.shared.buttonGroupSize.width - self.frame.size.height = BoxSizeManager.shared.size.height - self.wantsLayer = true + self.layer?.cornerRadius = 20 + self.layer?.masksToBounds = true self.addSubview(webVC!.view) - - webVC?.view.translatesAutoresizingMaskIntoConstraints = false webVC?.view.snp.makeConstraints { make in make.edges.equalTo(self) } @@ -32,12 +28,7 @@ class BoxContentsViewGroup: NSView { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - - override func draw(_ dirtyRect: NSRect) { - super.draw(dirtyRect) - // Drawing code here. - } - + func removeAllSubviews() { for subview in self.subviews { subview.removeFromSuperview() @@ -45,8 +36,19 @@ class BoxContentsViewGroup: NSView { } func showPreferences() { + self.removeAllSubviews() self.addSubview(preferencesVC.view) - preferencesVC.viewDidAppear() + preferencesVC.view.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } + + func showScripts() { + self.removeAllSubviews() + self.addSubview(scriptsVC.view) + scriptsVC.view.snp.makeConstraints { make in + make.edges.equalToSuperview() + } } func showWebviews(_ sender: NSButton) { diff --git a/Box42/WebView/Model/URLModel.swift b/Box42/WebView/Model/URLModel.swift new file mode 100644 index 0000000..4dee7c6 --- /dev/null +++ b/Box42/WebView/Model/URLModel.swift @@ -0,0 +1,42 @@ +// +// URLModel.swift +// Box42 +// +// Created by Chan on 2023/03/16. +// + +import Foundation + +typealias nameUrl = (name: String, url: String) + +struct URLModel { + var id: UUID + var name: String + var url: String + + init(name: String, url: String) { + self.id = UUID() + self.name = name + self.url = url + } +} + +struct URLModels { + var info: [URLModel] + + // Network logic api call 날려서 받아올 것. + let URLstring: [nameUrl] = [ + ("home", "https://42box.kr/"), + ("23Coaltheme", "https://42box.github.io/front-end/"), + ("Box 42", "https://42box.github.io/front-end/#/box"), + ("Intra 42", "https://intra.42.fr"), + ("Jiphyeonjeon", "https://42library.kr"), + ("42STAT", "https://stat.42seoul.kr/home"), + ("24Hane", "https://24hoursarenotenough.42seoul.kr"), + ("80kCoding", "https://80000coding.oopy.io"), + ("where42", "https://www.where42.kr"), + ("cabi", "https://cabi.42seoul.io/"), + ("42gg", "https://42gg.kr/"), + ("textart", "https://textart.sh/"), + ] +} diff --git a/Box42/WebView/Model/WebViewUI.swift b/Box42/WebView/Model/WebViewUI.swift new file mode 100644 index 0000000..50679a9 --- /dev/null +++ b/Box42/WebView/Model/WebViewUI.swift @@ -0,0 +1,16 @@ +// +// WebViewUI.swift +// Box42 +// +// Created by Chanhee Kim on 8/29/23. +// + +import Foundation + +enum WebViewUI { + enum transfer { + static let download = "download" + static let icon = "icon" + static let userProfile = "userProfile" + } +} diff --git a/Box42/WebView/URL/URLModel.swift b/Box42/WebView/URL/URLModel.swift deleted file mode 100644 index a7a0ff6..0000000 --- a/Box42/WebView/URL/URLModel.swift +++ /dev/null @@ -1,107 +0,0 @@ -// -// URLModel.swift -// Box42 -// -// Created by Chan on 2023/03/16. -// - -import Foundation - -typealias nameUrl = (name: String, url: String) - -struct URLModel { - var id: UUID - var name: String - var url: String - - init(name: String, url: String) { - self.id = UUID() - self.name = name - self.url = url - } -} - -struct UserDataA: Codable { - var uuid: String - var nickname: String - var theme: Int - var icon: String - var urlList: [_URLModel] - var profileImage: String -} - -struct _URLModel: Codable { - var name: String - var url: String -} - -struct URLModels { - var info: [URLModel] - let strData = """ - { - \"uuid\":\"8a8b9d71-3c10-4cbc-8b3a-ae1b5c215f40\", - \"nickname\":\"sechung\", - \"theme\":0, - \"icon\":\"fox\", - \"urlList\":[ - {\"name\":\"home\",\"url\":\"https://42box.kr/\"}, - {\"name\":\"23Coaltheme\",\"url\":\"https://42box.github.io/front-end/\"}, - {\"name\":\"loopback\",\"url\":\"http://127.0.0.1:3000/\"}, - {\"name\":\"Box42\",\"url\":\"https://42box.github.io/front-end/#/box\"}, - {\"name\":\"Intra 42\",\"url\":\"https://intra.42.fr\"}, - {\"name\":\"Jiphyeonjeon\",\"url\":\"https://42library.kr\"}, - {\"name\":\"42STAT\",\"url\":\"https://stat.42seoul.kr/home\"}, - {\"name\":\"24Hane\",\"url\":\"https://24hoursarenotenough.42seoul.kr\"}, - {\"name\":\"80kCoding\",\"url\":\"https://80000coding.oopy.io\"}, - {\"name\":\"where42\",\"url\":\"https://www.where42.kr\"}, - {\"name\":\"cabi\",\"url\":\"https://cabi.42seoul.io/\"}, - {\"name\":\"42gg\",\"url\":\"https://42gg.kr/\"} - ], - \"profileImage\":\"dummy-images.png\" - } - """ - // Network logic api call 날려서 받아올 것. - let URLstring: [nameUrl] = [ - ("home", "https://42box.kr/"), - ("23Coaltheme", "https://42box.github.io/front-end/"), - ("Box 42", "https://42box.github.io/front-end/#/box"), - ("Intra 42", "https://intra.42.fr"), - ("Jiphyeonjeon", "https://42library.kr"), - ("42STAT", "https://stat.42seoul.kr/home"), - ("24Hane", "https://24hoursarenotenough.42seoul.kr"), - ("80kCoding", "https://80000coding.oopy.io"), - ("where42", "https://www.where42.kr"), - ("cabi", "https://cabi.42seoul.io/"), - ("42gg", "https://42gg.kr/"), - ("textart", "https://textart.sh/"), - ] - - -// let a = URLModel(name: "name", url: "url") -// var m = URLModels(info: [a]) -// var strData = m.strData -// var dicData : Dictionary<String, Any> = [String: String]() -// do { -// dicData = try JSONSerialization.jsonObject(with: Data(strData.utf8), options: []) as! Dictionary<String, Any> -// } catch { -// print(error.localizedDescription) -// } -// print(dicData["home"]) -// print(dicData) -// -// -// let jsonData = Data(strData.utf8) -// do { -// let userData = try JSONDecoder().decode(UserDataA.self, from: jsonData) -// for urlModel in userData.urlList { -// print(urlModel.name, urlModel.url) -// } -// -// -// if let homeURLModel = userData.urlList.first(where: { $0.name == "home" }) { -// print(homeURLModel.url) -// } -// } catch { -// print(error.localizedDescription) -// } -} diff --git a/Box42/WebView/WebView.swift b/Box42/WebView/WebView.swift index e12930e..8e3e12e 100644 --- a/Box42/WebView/WebView.swift +++ b/Box42/WebView/WebView.swift @@ -7,31 +7,28 @@ import WebKit -class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate { - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - print("userContentController") - } - +class WebView: WKWebView, WKScriptMessageHandler { + var icon = MenubarViewController() init() { let preferences = WKPreferences() preferences.javaScriptEnabled = true preferences.javaScriptCanOpenWindowsAutomatically = true - + let contentController = WKUserContentController() let configuration = WKWebViewConfiguration() configuration.preferences = preferences configuration.userContentController = contentController - super.init(frame: .zero, configuration: configuration) - - contentController.add(self, name: "box") - + + contentController.add(self, name: WebViewUI.transfer.download) + contentController.add(self, name: WebViewUI.transfer.icon) + contentController.add(self, name: WebViewUI.transfer.userProfile) + self.configuration.preferences.javaScriptCanOpenWindowsAutomatically = true self.configuration.preferences.javaScriptEnabled = true self.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs") - self.uiDelegate = self self.becomeFirstResponder() } @@ -39,3 +36,34 @@ class WebView: WKWebView, WKScriptMessageHandler, WKUIDelegate { fatalError("init(coder:) has not been implemented") } } + +// MARK: - Front Client 통신 +extension WebView { + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + // 스크립트 다운로드 + if message.name == WebViewUI.transfer.download, let downloadURLString = message.body as? String { + ScriptsFileManager.downloadFile(from: downloadURLString) + } + // 아이콘 정보 PUT: + if message.name == WebViewUI.transfer.icon, let imgIconString = message.body as? String { + icon.buttonImageChange(imgIconString) + } + // 유저 정보 (Front)GET: https://api.42box.site/user-service/users/me + if message.name == WebViewUI.transfer.userProfile, let userProfileString = message.body as? String { + let userProfileJson = userProfileString.data(using: .utf8) + + print(">>> FrontEnd Get", userProfileString) + + do { + let decoder = JSONDecoder() + let userProfile = try decoder.decode(UserProfile.self, from: userProfileJson!) + print(userProfile.icon) + + UserManager.shared.updateUserProfile(newProfile: userProfile) + + } catch { + print("JSON decoding failed: \(error)") + } + } + } +} diff --git a/Box42/WebView/WebViewController.swift b/Box42/WebView/WebViewController.swift index e0d1f02..cb4b4c9 100644 --- a/Box42/WebView/WebViewController.swift +++ b/Box42/WebView/WebViewController.swift @@ -62,10 +62,6 @@ class WebViewController: NSViewController { super.viewDidLoad() } - func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { - print(message.name) - } - func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? { if let url = navigationAction.request.url { webView.load(URLRequest(url: url)) diff --git a/Box42/WebView/WebViewManager.swift b/Box42/WebView/WebViewManager.swift index bdf0fe1..18f0905 100644 --- a/Box42/WebView/WebViewManager.swift +++ b/Box42/WebView/WebViewManager.swift @@ -9,15 +9,55 @@ import WebKit typealias WebViewMapping = [String : WKWebView] -class WebViewManager { +class WebViewManager: NSObject { static let shared = WebViewManager() - + + var icon = MenubarViewController() + + var getCookieWebKit: WKWebView { + didSet { + getCookieWebKit.navigationDelegate = self + getCookieWebKit.isHidden = true + print(getCookie) + } + } + var hostingname: String? - var hostingWebView: WKWebView? - + var hostingWebView: WKWebView? { + didSet { + hostingWebView?.navigationDelegate = self + print("didSet") + } + } + var list: WebViewMapping! - private init() { + private override init() { list = [:] + + let webConfiguration = WKWebViewConfiguration() + getCookieWebKit = WKWebView(frame: .zero, configuration: webConfiguration) + } + + func getCookie() { + if let url = URL(string: "https://api.42box.site") { + let request = URLRequest(url: url) + getCookieWebKit.load(request) + } + } +} + +extension WebViewManager: WKNavigationDelegate { + // WKNavigationDelegate methods + func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { + print("Did start navigation") + } + + func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { + print("Did fail navigation with error: \(error.localizedDescription)") + } + + func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { + print("Did receive server redirect") } } diff --git a/Box42/WindowButton/View/WindowMinimizeButton.swift b/Box42/WindowButton/View/WindowMinimizeButton.swift index 4d6537c..3596dd4 100644 --- a/Box42/WindowButton/View/WindowMinimizeButton.swift +++ b/Box42/WindowButton/View/WindowMinimizeButton.swift @@ -17,7 +17,7 @@ class WindowMinimizeButton: NSButton { self.title = "" self.isBordered = false self.wantsLayer = true - self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius + self.layer?.cornerRadius = WindowButtonUI.size.cornerRadius / 2 self.layer?.backgroundColor = WindowButtonUI.color.minimize self.target = self self.action = #selector(minimizeAction)