Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1f382c648 | |||
| f491ca18c7 | |||
| 7f21e32853 | |||
| 7acbc6b10c | |||
| 8f30d7c158 | |||
| cdb1b5f9a1 | |||
| 5a8283b4e6 | |||
| f3b560c926 | |||
| 2352378f67 | |||
| 6cbd185ef6 | |||
| 1df2878063 | |||
| e6b7e7c834 | |||
| 15468adaa4 | |||
| 9750d92e7c | |||
| b52c216a3d | |||
| d350acae64 | |||
| 2cb2afa611 | |||
| d10ddf680d | |||
| a618bae9f0 | |||
| e702acf897 | |||
| 99754523c7 | |||
| 9eb0f916e0 |
@@ -5,8 +5,8 @@
|
||||
<img src="https://img.shields.io/badge/CocoaPods-compatible-4BC51D.svg?style=flat" /></a>
|
||||
<a href="https://github.com/Carthage/Carthage" alt="Carthage">
|
||||
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat" /></a>
|
||||
<a href="https://github.com/yagiz/Bagel/releases/tag/1.3.1" alt="Version">
|
||||
<img src="https://img.shields.io/badge/version-1.3.1-blue.svg?style=flat" /></a>
|
||||
<a href="https://github.com/yagiz/Bagel/releases" alt="Version">
|
||||
<img src="https://img.shields.io/github/release/yagiz/Bagel.svg" /></a>
|
||||
</p>
|
||||
|
||||
Bagel is a little native iOS network debugger. It's not a proxy debugger so you don't have to mess around with certificates, proxy settings etc. As long as your iOS devices and your Mac are in the same network, you can view the network traffic of your apps seperated by the devices or simulators.
|
||||
@@ -20,7 +20,7 @@ Bagel is a little native iOS network debugger. It's not a proxy debugger so you
|
||||
- Build and archive the project.
|
||||
#### Install iOS Client
|
||||
#### CocoaPods
|
||||
```sh
|
||||
```shhttps://img.shields.io/badge/version-1.3.1-blue.svg?style=flat
|
||||
pod 'Bagel', '~> 1.3.2'
|
||||
```
|
||||
##### Carthage
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
3760A47321F1383F004D1E07 /* BagelURLConnectionInjector.m in Sources */ = {isa = PBXBuildFile; fileRef = 3760A45921F1383F004D1E07 /* BagelURLConnectionInjector.m */; };
|
||||
3760A47421F1383F004D1E07 /* BagelBaseModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 3760A45A21F1383F004D1E07 /* BagelBaseModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
3760A47B21F13A47004D1E07 /* CocoaAsyncSocket.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3760A47A21F13A47004D1E07 /* CocoaAsyncSocket.framework */; };
|
||||
51102CE2220B87290067EB63 /* BagelCarrierDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@@ -66,6 +67,7 @@
|
||||
3760A45A21F1383F004D1E07 /* BagelBaseModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BagelBaseModel.h; sourceTree = "<group>"; };
|
||||
3760A47521F13872004D1E07 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
3760A47A21F13A47004D1E07 /* CocoaAsyncSocket.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CocoaAsyncSocket.framework; path = Carthage/Build/iOS/CocoaAsyncSocket.framework; sourceTree = SOURCE_ROOT; };
|
||||
51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BagelCarrierDelegate.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -107,6 +109,7 @@
|
||||
3760A44A21F1383F004D1E07 /* BagelBaseModel.m */,
|
||||
3760A45821F1383F004D1E07 /* BagelBrowser.h */,
|
||||
3760A44C21F1383F004D1E07 /* BagelBrowser.m */,
|
||||
51102CE1220B857E0067EB63 /* BagelCarrierDelegate.h */,
|
||||
3760A44621F1383F004D1E07 /* BagelConfiguration.h */,
|
||||
3760A45621F1383F004D1E07 /* BagelConfiguration.m */,
|
||||
3760A44321F1383F004D1E07 /* BagelController.h */,
|
||||
@@ -147,6 +150,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3760A46F21F1383F004D1E07 /* Bagel.h in Headers */,
|
||||
51102CE2220B87290067EB63 /* BagelCarrierDelegate.h in Headers */,
|
||||
3760A45D21F1383F004D1E07 /* BagelController.h in Headers */,
|
||||
3760A47221F1383F004D1E07 /* BagelBrowser.h in Headers */,
|
||||
3760A46021F1383F004D1E07 /* BagelConfiguration.h in Headers */,
|
||||
@@ -364,6 +368,7 @@
|
||||
3760A43E21F13817004D1E07 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -394,6 +399,7 @@
|
||||
3760A43F21F13817004D1E07 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
APPLICATION_EXTENSION_API_ONLY = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Copyright (c) 2018 Bagel (https://github.com/yagiz/Bagel)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import "BagelRequestPacket.h"
|
||||
|
||||
@protocol BagelCarrierDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/**
|
||||
Called right before Bagel sends a request packet to the Mac app.
|
||||
Allows your delegate to modify the packet on the fly, or abort the operation.
|
||||
|
||||
Return a modified request packet, or nil if you want to filter it out.
|
||||
*/
|
||||
- (nullable BagelRequestPacket*)bagelCarrierWillSendRequest:(nonnull BagelRequestPacket*)request;
|
||||
|
||||
@end
|
||||
@@ -20,6 +20,7 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "BagelCarrierDelegate.h"
|
||||
#import "BagelProjectModel.h"
|
||||
#import "BagelDeviceModel.h"
|
||||
#import "BagelUtility.h"
|
||||
@@ -29,6 +30,8 @@
|
||||
@property (nonatomic, strong) BagelProjectModel* project;
|
||||
@property (nonatomic, strong) BagelDeviceModel* device;
|
||||
|
||||
@property (nonatomic, weak) id<BagelCarrierDelegate> carrierDelegate;
|
||||
|
||||
@property (nonatomic) uint16_t netservicePort;
|
||||
@property (nonatomic, strong) NSString* netserviceType;
|
||||
@property (nonatomic, strong) NSString* netserviceDomain;
|
||||
|
||||
@@ -214,6 +214,15 @@ static NSString* queueId = @"com.yagiz.bagel.injectController";
|
||||
packet.project = self.configuration.project;
|
||||
packet.device = self.configuration.device;
|
||||
|
||||
id<BagelCarrierDelegate> carrierDelegate = self.configuration.carrierDelegate;
|
||||
if ([carrierDelegate respondsToSelector:@selector(bagelCarrierWillSendRequest:)]) {
|
||||
packet = [carrierDelegate bagelCarrierWillSendRequest:packet];
|
||||
|
||||
if (packet == nil) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[self.browser sendPacket:packet];
|
||||
}
|
||||
|
||||
|
||||
@@ -86,14 +86,14 @@
|
||||
if (self.urlSessionTask) {
|
||||
|
||||
requestInfo.url = self.urlSessionTask.originalRequest.URL;
|
||||
requestInfo.requestHeaders = self.self.urlSessionTask.originalRequest.allHTTPHeaderFields;
|
||||
requestInfo.requestHeaders = self.self.urlSessionTask.currentRequest.allHTTPHeaderFields;
|
||||
requestInfo.requestBody = self.self.urlSessionTask.originalRequest.HTTPBody;
|
||||
requestInfo.requestMethod = self.self.urlSessionTask.originalRequest.HTTPMethod;
|
||||
|
||||
}else if (self.urlConnection) {
|
||||
|
||||
requestInfo.url = self.urlConnection.originalRequest.URL;
|
||||
requestInfo.requestHeaders = self.self.urlConnection.originalRequest.allHTTPHeaderFields;
|
||||
requestInfo.requestHeaders = self.self.urlConnection.currentRequest.allHTTPHeaderFields;
|
||||
requestInfo.requestBody = self.self.urlConnection.originalRequest.HTTPBody;
|
||||
requestInfo.requestMethod = self.self.urlConnection.originalRequest.HTTPMethod;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */; };
|
||||
9AAA3A9C54B46F8D2C8DD674 /* Pods_Bagel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */; };
|
||||
BC1F5B37216746D30045C871 /* FontManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC1F5B36216746D30045C871 /* FontManager.swift */; };
|
||||
BC32643621738AF0006452FE /* KeyValueRepresentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC32643521738AF0006452FE /* KeyValueRepresentation.swift */; };
|
||||
@@ -114,6 +115,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
00E3BE2EECB0984D92EFCA30 /* Pods_Bagel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Bagel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CURLRepresentation.swift; sourceTree = "<group>"; };
|
||||
BC1F5B36216746D30045C871 /* FontManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontManager.swift; sourceTree = "<group>"; };
|
||||
BC32643521738AF0006452FE /* KeyValueRepresentation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyValueRepresentation.swift; sourceTree = "<group>"; };
|
||||
BC5E76C8216A64DB000F658D /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = "<group>"; };
|
||||
@@ -236,6 +238,14 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
1191142821F8B9AB00BFCA48 /* CURLRepresentation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1191142921F8B9CB00BFCA48 /* CURLRepresentation.swift */,
|
||||
);
|
||||
path = CURLRepresentation;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
659EF5768D424A8F8EEB1541 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -489,6 +499,7 @@
|
||||
BCEB9AA4217C951C008BBF3C /* ContentRepresentation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1191142821F8B9AB00BFCA48 /* CURLRepresentation */,
|
||||
BCEB9AA5217C9532008BBF3C /* ContentRepresentation.swift */,
|
||||
BCEB9AA9217CB0BB008BBF3C /* OverviewRepresentation */,
|
||||
BC32643421738AB5006452FE /* ParameterRepresentation */,
|
||||
@@ -857,6 +868,7 @@
|
||||
BCFC853021383267001EC6D7 /* ProjectsViewController.swift in Sources */,
|
||||
BCA60B442162395000B9DCAD /* DevicesViewModel.swift in Sources */,
|
||||
BC73DFAE215BFB18002E533B /* BagelPublisher.swift in Sources */,
|
||||
1191142A21F8B9CB00BFCA48 /* CURLRepresentation.swift in Sources */,
|
||||
BCA60B41216201B900B9DCAD /* BagelConfiguration.swift in Sources */,
|
||||
BC61DA752162B976000F6D2F /* DetailViewModel.swift in Sources */,
|
||||
BC9C77B22163897600E8ADE8 /* DataTextViewModel.swift in Sources */,
|
||||
|
||||
@@ -11,7 +11,7 @@ import Cocoa
|
||||
extension Date {
|
||||
|
||||
private static let readableFormat = "dd/MM/yyyy HH:mm:ss"
|
||||
var readble: String {
|
||||
var readable: String {
|
||||
return self.format(dateFormat: Date.readableFormat)
|
||||
}
|
||||
|
||||
|
||||
+21
-3
@@ -13,9 +13,11 @@ class OverviewViewController: BaseViewController {
|
||||
|
||||
@IBOutlet var overviewTextView: NSTextView!
|
||||
|
||||
@IBOutlet weak var curlButton: NSButton!
|
||||
@IBOutlet weak var copyToClipboardButton: NSButton!
|
||||
|
||||
var viewModel: OverviewViewModel?
|
||||
private var isCurl: Bool = false
|
||||
|
||||
override func setup() {
|
||||
|
||||
@@ -32,11 +34,27 @@ class OverviewViewController: BaseViewController {
|
||||
|
||||
func refresh() {
|
||||
|
||||
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? ""))
|
||||
if isCurl {
|
||||
|
||||
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.curlRepresentation?.rawString ?? ""))
|
||||
curlButton.state = .on
|
||||
} else {
|
||||
|
||||
self.overviewTextView.textStorage?.setAttributedString(TextStyles.codeAttributedString(string: self.viewModel?.overviewRepresentation?.rawString ?? ""))
|
||||
curlButton.state = .off
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func curlButtonAction(_ sender: Any) {
|
||||
self.isCurl.toggle()
|
||||
self.refresh()
|
||||
}
|
||||
|
||||
@IBAction func copyButtonAction(_ sender: Any) {
|
||||
|
||||
self.viewModel?.copyToClipboard()
|
||||
if isCurl {
|
||||
self.viewModel?.copyCURLToClipboard()
|
||||
} else {
|
||||
self.viewModel?.copyTextToClipboard()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -12,6 +12,7 @@ class OverviewViewModel: BaseViewModel {
|
||||
|
||||
var packet: BagelPacket?
|
||||
var overviewRepresentation: OverviewRepresentation?
|
||||
var curlRepresentation: CURLRepresentation?
|
||||
|
||||
func register() {
|
||||
|
||||
@@ -26,12 +27,17 @@ class OverviewViewModel: BaseViewModel {
|
||||
if let requestInfo = self.packet?.requestInfo {
|
||||
|
||||
self.overviewRepresentation = OverviewRepresentation(requestInfo: requestInfo)
|
||||
self.curlRepresentation = CURLRepresentation(requestInfo: requestInfo)
|
||||
}
|
||||
|
||||
self.onChange?()
|
||||
}
|
||||
|
||||
func copyToClipboard() {
|
||||
func copyTextToClipboard() {
|
||||
self.overviewRepresentation?.copyToClipboard()
|
||||
}
|
||||
|
||||
func copyCURLToClipboard() {
|
||||
self.curlRepresentation?.copyToClipboard()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ class DetailViewController: BaseViewController {
|
||||
|
||||
self.tabView.selectTabViewItem(at: self.currentDetailType.rawValue)
|
||||
self.urlTextField.stringValue = self.viewModel?.packet?.requestInfo?.url ?? ""
|
||||
self.httpMethodTextField.stringValue = self.viewModel?.packet?.requestInfo?.requestMethod ?? ""
|
||||
self.httpMethodTextField.stringValue = self.viewModel?.packet?.requestInfo?.requestMethod?.rawValue ?? ""
|
||||
}
|
||||
|
||||
func refreshTypeButtons() {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<fragment content="Test">
|
||||
<attributes>
|
||||
<color key="NSColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<font key="NSFont" size="13" name="DroidSansMono"/>
|
||||
<font key="NSFont" metaFont="system"/>
|
||||
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
@@ -207,8 +207,21 @@
|
||||
<action selector="copyButtonAction:" target="dbv-oR-1ws" id="ZeH-wK-TFV"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ze8-fq-lWt">
|
||||
<rect key="frame" x="379" y="7" width="36" height="16"/>
|
||||
<buttonCell key="cell" type="recessed" title="cURL" bezelStyle="recessed" alignment="center" state="on" imageScaling="proportionallyDown" inset="2" id="MSt-7f-JHj">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="systemBold" size="12"/>
|
||||
</buttonCell>
|
||||
<color key="contentTintColor" red="0.70980392160000005" green="0.49803921569999998" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<connections>
|
||||
<action selector="curlButtonAction:" target="dbv-oR-1ws" id="H2c-aD-nWX"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="ze8-fq-lWt" firstAttribute="centerY" secondItem="9zZ-1e-l97" secondAttribute="centerY" id="9Mr-Ib-eBx"/>
|
||||
<constraint firstItem="U6O-Tm-OuZ" firstAttribute="leading" secondItem="ze8-fq-lWt" secondAttribute="trailing" constant="10" id="pzJ-6j-Rbh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="U6O-Tm-OuZ" secondAttribute="trailing" constant="10" id="tkO-3l-Gzv"/>
|
||||
</constraints>
|
||||
</view>
|
||||
@@ -241,6 +254,7 @@
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="copyToClipboardButton" destination="U6O-Tm-OuZ" id="Bis-TZ-SjP"/>
|
||||
<outlet property="curlButton" destination="ze8-fq-lWt" id="FCG-bS-aGL"/>
|
||||
<outlet property="overviewTextView" destination="yGA-r3-ock" id="sTN-fX-keW"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
@@ -290,7 +304,7 @@
|
||||
<fragment content="sad kasd jasj dksad jkasjd jkasdjk asjkd jksadjk asjk djksajk jkdajk jkdsa jkdjk jkas djkkajsa dk">
|
||||
<attributes>
|
||||
<color key="NSColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<font key="NSFont" size="13" name="DroidSansMono"/>
|
||||
<font key="NSFont" metaFont="system"/>
|
||||
<paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
@@ -343,7 +357,7 @@
|
||||
<rect key="frame" x="0.0" y="12" width="135" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="3SO-nF-Jew">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
@@ -370,14 +384,14 @@
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="KeyValueTableCellView" id="Ze5-kZ-luS" customClass="KeyValueTableCellView" customModule="Bagel" customModuleProvider="target">
|
||||
<rect key="frame" x="138.5" y="1" width="299" height="43"/>
|
||||
<rect key="frame" x="139" y="1" width="299" height="43"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ll4-xn-DEL">
|
||||
<rect key="frame" x="0.0" y="12" width="299" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="GJr-nQ-UMJ">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
@@ -622,24 +636,24 @@
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mm2-yo-sQB">
|
||||
<rect key="frame" x="-2" y="319" width="29" height="19"/>
|
||||
<rect key="frame" x="-2" y="320" width="30" height="17"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="GET" id="S1x-ff-DRQ">
|
||||
<font key="font" size="13" name="EffraMedium-Regular"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="dHd-eX-X4k" customClass="ContentBar" customModule="Bagel" customModuleProvider="target">
|
||||
<rect key="frame" x="35" y="313" width="415" height="30"/>
|
||||
<rect key="frame" x="36" y="313" width="414" height="30"/>
|
||||
<view key="contentView" id="N8G-6p-Gm5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="415" height="30"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="30"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Baz-mg-73Q">
|
||||
<rect key="frame" x="3" y="6" width="409" height="18"/>
|
||||
<rect key="frame" x="3" y="6" width="408" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" focusRingType="none" alignment="left" placeholderString="" id="0y6-ve-dir">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
@@ -662,17 +676,17 @@
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VkR-Eh-dut">
|
||||
<rect key="frame" x="8" y="24" width="43" height="14"/>
|
||||
<rect key="frame" x="8" y="27" width="47" height="11"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="REQUEST" id="RAI-o2-Cnk">
|
||||
<font key="font" size="9" name="Effra-Regular"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CjX-gd-hJy">
|
||||
<rect key="frame" x="393" y="24" width="49" height="14"/>
|
||||
<rect key="frame" x="389" y="27" width="53" height="11"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="RESPONSE" id="To7-5v-rDc">
|
||||
<font key="font" size="9" name="Effra-Regular"/>
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</textFieldCell>
|
||||
|
||||
@@ -11,20 +11,18 @@ import macOSThemeKit
|
||||
|
||||
class DatePacketTableCellView: NSTableCellView {
|
||||
|
||||
@IBOutlet weak var titleTextField: NSTextField!
|
||||
@IBOutlet private weak var titleTextField: NSTextField!
|
||||
|
||||
var packet: BagelPacket!
|
||||
{
|
||||
didSet
|
||||
{
|
||||
self.refresh()
|
||||
var packet: BagelPacket? {
|
||||
didSet{
|
||||
guard let packet = packet else { return }
|
||||
refresh(with: packet)
|
||||
}
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
|
||||
self.titleTextField.textColor = ThemeColor.secondaryLabelColor
|
||||
self.titleTextField.stringValue = self.packet.requestInfo?.startDate?.readble ?? ""
|
||||
func refresh(with packet: BagelPacket) {
|
||||
titleTextField.textColor = ThemeColor.secondaryLabelColor
|
||||
titleTextField.stringValue = packet.requestInfo?.startDate?.readable ?? ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,32 +11,36 @@ import macOSThemeKit
|
||||
|
||||
class MethodPacketTableCellView: NSTableCellView {
|
||||
|
||||
@IBOutlet weak var titleTextField: NSTextField!
|
||||
@IBOutlet private weak var titleTextField: NSTextField!
|
||||
|
||||
var packet: BagelPacket!
|
||||
{
|
||||
didSet
|
||||
{
|
||||
self.refresh()
|
||||
var packet: BagelPacket?{
|
||||
didSet{
|
||||
guard let packet = packet else { return }
|
||||
refresh(with: packet)
|
||||
}
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
|
||||
func refresh(with packet: BagelPacket) {
|
||||
|
||||
var methodColor = ThemeColor.httpMethodDefaultColor
|
||||
|
||||
if self.packet.requestInfo?.requestMethod == "GET" {
|
||||
methodColor = ThemeColor.httpMethodGetColor
|
||||
}else if self.packet.requestInfo?.requestMethod == "POST" {
|
||||
methodColor = ThemeColor.httpMethodPostColor
|
||||
}else if self.packet.requestInfo?.requestMethod == "PUT" {
|
||||
methodColor = ThemeColor.httpMethodPutColor
|
||||
}else if self.packet.requestInfo?.requestMethod == "DELETE" {
|
||||
methodColor = ThemeColor.httpMethodDeleteColor
|
||||
|
||||
if let requestMethod = packet.requestInfo?.requestMethod {
|
||||
switch requestMethod {
|
||||
case .get:
|
||||
methodColor = ThemeColor.httpMethodGetColor
|
||||
case .put:
|
||||
methodColor = ThemeColor.httpMethodPutColor
|
||||
case .post:
|
||||
methodColor = ThemeColor.httpMethodPostColor
|
||||
case .delete:
|
||||
methodColor = ThemeColor.httpMethodDeleteColor
|
||||
case .head:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
self.titleTextField.textColor = methodColor
|
||||
self.titleTextField.stringValue = self.packet.requestInfo?.requestMethod ?? ""
|
||||
self.titleTextField.stringValue = packet.requestInfo?.requestMethod?.rawValue ?? ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -62,16 +62,23 @@
|
||||
<rect key="frame" x="1" y="1" width="40" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RPO-QB-zWr">
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="RPO-QB-zWr">
|
||||
<rect key="frame" x="5" y="0.0" width="34" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="etQ-5E-vgp"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="200" id="nCW-um-xTy">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="RPO-QB-zWr" secondAttribute="trailing" constant="3" id="Bl5-Mf-dwQ"/>
|
||||
<constraint firstItem="RPO-QB-zWr" firstAttribute="leading" secondItem="VPk-w5-xdq" secondAttribute="leading" constant="7" id="YyA-98-4ns"/>
|
||||
<constraint firstItem="RPO-QB-zWr" firstAttribute="centerY" secondItem="VPk-w5-xdq" secondAttribute="centerY" id="bJ7-DX-WK4"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="titleTextField" destination="RPO-QB-zWr" id="VPe-A4-zOx"/>
|
||||
</connections>
|
||||
@@ -94,16 +101,23 @@
|
||||
<rect key="frame" x="44" y="1" width="52" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9sG-qU-mJh">
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="9sG-qU-mJh">
|
||||
<rect key="frame" x="5" y="0.0" width="46" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="7Bn-Cb-fYk"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="GET" id="Ntk-Pw-UR8">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="9sG-qU-mJh" firstAttribute="centerY" secondItem="eqC-zI-qTu" secondAttribute="centerY" id="NId-x2-FL3"/>
|
||||
<constraint firstItem="9sG-qU-mJh" firstAttribute="leading" secondItem="eqC-zI-qTu" secondAttribute="leading" constant="7" id="VuC-XE-gYP"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9sG-qU-mJh" secondAttribute="trailing" constant="3" id="pQk-mB-u44"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="titleTextField" destination="9sG-qU-mJh" id="yHT-2o-p1v"/>
|
||||
</connections>
|
||||
@@ -127,16 +141,23 @@
|
||||
<rect key="frame" x="99" y="1" width="142" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ipb-Zo-mzM">
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="Ipb-Zo-mzM">
|
||||
<rect key="frame" x="5" y="2" width="136" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="18" id="H8P-2o-QNJ"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="ADt-eY-pVa">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="Ipb-Zo-mzM" secondAttribute="trailing" constant="3" id="RTe-RC-zjX"/>
|
||||
<constraint firstItem="Ipb-Zo-mzM" firstAttribute="leading" secondItem="gqm-6g-9Tm" secondAttribute="leading" constant="7" id="Yxt-Rz-Fyj"/>
|
||||
<constraint firstItem="Ipb-Zo-mzM" firstAttribute="top" secondItem="gqm-6g-9Tm" secondAttribute="top" id="sLz-cx-N8s"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="titleTextField" destination="Ipb-Zo-mzM" id="799-wV-bdT"/>
|
||||
</connections>
|
||||
@@ -160,16 +181,23 @@
|
||||
<rect key="frame" x="244" y="1" width="319" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="lqc-CZ-vWv">
|
||||
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="lqc-CZ-vWv">
|
||||
<rect key="frame" x="5" y="2" width="313" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="18" id="fbR-A4-8AR"/>
|
||||
</constraints>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" selectable="YES" sendsActionOnEndEditing="YES" title="Table View Cell" id="j9t-nF-LfF">
|
||||
<font key="font" size="12" name="DroidSansMono"/>
|
||||
<font key="font" metaFont="cellTitle"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="lqc-CZ-vWv" secondAttribute="trailing" constant="3" id="1sE-0a-tGJ"/>
|
||||
<constraint firstItem="lqc-CZ-vWv" firstAttribute="leading" secondItem="0Hf-Bc-1kK" secondAttribute="leading" constant="7" id="OSr-vD-oKm"/>
|
||||
<constraint firstItem="lqc-CZ-vWv" firstAttribute="top" secondItem="0Hf-Bc-1kK" secondAttribute="top" id="n3i-Gq-fs0"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<outlet property="titleTextField" destination="lqc-CZ-vWv" id="1uF-Ck-sP4"/>
|
||||
</connections>
|
||||
@@ -218,24 +246,24 @@
|
||||
</connections>
|
||||
</button>
|
||||
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="ECf-Ip-WqV">
|
||||
<rect key="frame" x="5" y="5" width="200" height="20"/>
|
||||
<rect key="frame" x="54" y="5" width="200" height="20"/>
|
||||
<view key="contentView" id="Vap-9R-hh7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="200" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Nh8-PV-Qe4">
|
||||
<rect key="frame" x="3" y="0.0" width="194" height="20"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Filter" id="OhO-md-Jfb">
|
||||
<font key="font" size="13" name="Effra-Regular"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="URL..." id="OhO-md-Jfb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="leading" secondItem="Vap-9R-hh7" secondAttribute="leading" constant="5" id="6Fu-xV-iMV"/>
|
||||
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="top" secondItem="Vap-9R-hh7" secondAttribute="top" id="MVc-al-bQg"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Nh8-PV-Qe4" secondAttribute="bottom" id="OFG-SD-vdg"/>
|
||||
<constraint firstItem="Nh8-PV-Qe4" firstAttribute="leading" secondItem="Vap-9R-hh7" secondAttribute="leading" constant="5" id="fZy-Mx-aKw"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Nh8-PV-Qe4" secondAttribute="trailing" constant="5" id="sjk-3w-cno"/>
|
||||
</constraints>
|
||||
</view>
|
||||
@@ -244,11 +272,85 @@
|
||||
</constraints>
|
||||
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</box>
|
||||
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="iSU-u4-CHh">
|
||||
<rect key="frame" x="262" y="5" width="72" height="20"/>
|
||||
<view key="contentView" id="bTY-Gz-LX8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="72" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="K4O-j7-3QY">
|
||||
<rect key="frame" x="3" y="0.0" width="66" height="20"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Status..." id="phe-Xy-3Ds">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="K4O-j7-3QY" firstAttribute="top" secondItem="bTY-Gz-LX8" secondAttribute="top" id="FDv-mK-aCx"/>
|
||||
<constraint firstAttribute="bottom" secondItem="K4O-j7-3QY" secondAttribute="bottom" id="NLP-tQ-b3h"/>
|
||||
<constraint firstItem="K4O-j7-3QY" firstAttribute="leading" secondItem="bTY-Gz-LX8" secondAttribute="leading" constant="5" id="jYY-Gr-yNL"/>
|
||||
<constraint firstAttribute="trailing" secondItem="K4O-j7-3QY" secondAttribute="trailing" constant="5" id="kQY-kN-zBh"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="72" id="4UX-81-bxQ"/>
|
||||
</constraints>
|
||||
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</box>
|
||||
<box boxType="custom" borderWidth="0.0" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="D6h-Wu-m6x">
|
||||
<rect key="frame" x="342" y="5" width="72" height="20"/>
|
||||
<view key="contentView" id="c8Z-eD-ZA3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="72" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="H4n-d7-YFE">
|
||||
<rect key="frame" x="3" y="0.0" width="66" height="20"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" focusRingType="none" placeholderString="Method..." id="OPB-NY-4Xr">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="H4n-d7-YFE" firstAttribute="top" secondItem="c8Z-eD-ZA3" secondAttribute="top" id="9y6-Yi-ucB"/>
|
||||
<constraint firstAttribute="bottom" secondItem="H4n-d7-YFE" secondAttribute="bottom" id="Cyz-B4-rvl"/>
|
||||
<constraint firstItem="H4n-d7-YFE" firstAttribute="leading" secondItem="c8Z-eD-ZA3" secondAttribute="leading" constant="5" id="h4Y-eh-hvG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="H4n-d7-YFE" secondAttribute="trailing" constant="5" id="nUm-kG-UZt"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="72" id="VTl-fD-bqE"/>
|
||||
</constraints>
|
||||
<color key="fillColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</box>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mer-XV-N6Z">
|
||||
<rect key="frame" x="6" y="5" width="42" height="20"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" enabled="NO" alignment="left" title="Filters" usesSingleLineMode="YES" id="6LO-kQ-Zld">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="ECf-Ip-WqV" firstAttribute="leading" secondItem="dvd-KM-mI8" secondAttribute="leading" constant="5" id="ABc-aZ-M1W"/>
|
||||
<constraint firstItem="iSU-u4-CHh" firstAttribute="top" secondItem="ECf-Ip-WqV" secondAttribute="top" id="5oz-DR-Sw5"/>
|
||||
<constraint firstItem="D6h-Wu-m6x" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="BZt-2l-JqE"/>
|
||||
<constraint firstItem="iSU-u4-CHh" firstAttribute="leading" secondItem="ECf-Ip-WqV" secondAttribute="trailing" constant="8" id="CoD-4z-PnH"/>
|
||||
<constraint firstItem="mer-XV-N6Z" firstAttribute="top" secondItem="Nh8-PV-Qe4" secondAttribute="top" id="DOY-qd-vYV"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9pa-LD-9G6" secondAttribute="trailing" constant="10" id="I5N-4v-LhZ"/>
|
||||
<constraint firstItem="mer-XV-N6Z" firstAttribute="bottom" secondItem="Nh8-PV-Qe4" secondAttribute="bottom" id="Qj9-fA-WYv"/>
|
||||
<constraint firstItem="ECf-Ip-WqV" firstAttribute="leading" secondItem="mer-XV-N6Z" secondAttribute="trailing" constant="8" id="RK9-XR-Ise"/>
|
||||
<constraint firstItem="mer-XV-N6Z" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="RTh-dM-w05"/>
|
||||
<constraint firstItem="mer-XV-N6Z" firstAttribute="leading" secondItem="dvd-KM-mI8" secondAttribute="leading" constant="8" id="Xcv-L7-Hct"/>
|
||||
<constraint firstItem="D6h-Wu-m6x" firstAttribute="top" secondItem="iSU-u4-CHh" secondAttribute="top" id="Yvc-7W-bLI"/>
|
||||
<constraint firstItem="D6h-Wu-m6x" firstAttribute="leading" secondItem="iSU-u4-CHh" secondAttribute="trailing" constant="8" id="aN8-9B-2x0"/>
|
||||
<constraint firstItem="iSU-u4-CHh" firstAttribute="centerY" secondItem="dvd-KM-mI8" secondAttribute="centerY" id="doj-wZ-8Ip"/>
|
||||
<constraint firstItem="D6h-Wu-m6x" firstAttribute="bottom" secondItem="iSU-u4-CHh" secondAttribute="bottom" id="id1-Ml-nZr"/>
|
||||
<constraint firstItem="ECf-Ip-WqV" firstAttribute="top" secondItem="dvd-KM-mI8" secondAttribute="top" constant="5" id="jC1-ca-z56"/>
|
||||
<constraint firstItem="iSU-u4-CHh" firstAttribute="bottom" secondItem="ECf-Ip-WqV" secondAttribute="bottom" id="qNt-eG-ll1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="ECf-Ip-WqV" secondAttribute="bottom" constant="5" id="zBj-Zq-CfZ"/>
|
||||
</constraints>
|
||||
</view>
|
||||
@@ -284,8 +386,10 @@
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="addressFilterTextField" destination="Nh8-PV-Qe4" id="lwy-vX-lgx"/>
|
||||
<outlet property="clearButton" destination="9pa-LD-9G6" id="IyR-HG-dqR"/>
|
||||
<outlet property="filterTextField" destination="Nh8-PV-Qe4" id="lwy-vX-lgx"/>
|
||||
<outlet property="methodFilterTextField" destination="H4n-d7-YFE" id="fPg-CN-Znu"/>
|
||||
<outlet property="statusFilterTextField" destination="K4O-j7-3QY" id="BGB-aB-n5p"/>
|
||||
<outlet property="tableView" destination="CKi-fU-sLr" id="v7l-Ps-Ash"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
||||
@@ -10,7 +10,18 @@ import Cocoa
|
||||
import macOSThemeKit
|
||||
|
||||
class PacketsViewController: BaseViewController {
|
||||
|
||||
|
||||
struct TableIdentifiers {
|
||||
static let statusCode = "statusCode"
|
||||
static let method = "method"
|
||||
static let url = "url"
|
||||
static let date = "date"
|
||||
}
|
||||
|
||||
enum FilterTags: Int {
|
||||
case address, status, method
|
||||
}
|
||||
|
||||
static var statusColumnWidth = CGFloat(50.0)
|
||||
static var methodColumnWidth = CGFloat(55.0)
|
||||
static var dateColumnWidth = CGFloat(150.0)
|
||||
@@ -20,7 +31,10 @@ class PacketsViewController: BaseViewController {
|
||||
|
||||
@IBOutlet weak var clearButton: NSButton!
|
||||
@IBOutlet weak var tableView: BaseTableView!
|
||||
@IBOutlet weak var filterTextField: NSTextField!
|
||||
|
||||
@IBOutlet weak var addressFilterTextField: NSTextField!
|
||||
@IBOutlet weak var statusFilterTextField: NSTextField!
|
||||
@IBOutlet weak var methodFilterTextField: NSTextField!
|
||||
|
||||
override func setup() {
|
||||
|
||||
@@ -31,133 +45,120 @@ class PacketsViewController: BaseViewController {
|
||||
self.tableView.backgroundColor = ThemeColor.controlBackgroundColor
|
||||
self.tableView.gridColor = ThemeColor.gridColor
|
||||
|
||||
self.filterTextField.backgroundColor = ThemeColor.controlBackgroundColor
|
||||
self.filterTextField.delegate = self
|
||||
setupFilterTextFields()
|
||||
|
||||
self.viewModel?.onChange = { [weak self] in
|
||||
|
||||
self?.refresh()
|
||||
}
|
||||
|
||||
self.setupTableViewHeaders()
|
||||
}
|
||||
|
||||
private func setupFilterTextFields() {
|
||||
self.addressFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
|
||||
self.addressFilterTextField.tag = FilterTags.address.rawValue
|
||||
self.addressFilterTextField.delegate = self
|
||||
|
||||
self.statusFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
|
||||
self.statusFilterTextField.tag = FilterTags.status.rawValue
|
||||
self.statusFilterTextField.delegate = self
|
||||
|
||||
self.methodFilterTextField.backgroundColor = ThemeColor.controlBackgroundColor
|
||||
self.methodFilterTextField.tag = FilterTags.method.rawValue
|
||||
self.methodFilterTextField.delegate = self
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
|
||||
let isScrolledToBottom = self.isScrolledToBottom()
|
||||
|
||||
self.tableView.reloadData()
|
||||
|
||||
if let selectedItemIndex = self.viewModel?.selectedItemIndex {
|
||||
|
||||
self.tableView.selectRowIndexes(IndexSet(integer: selectedItemIndex), byExtendingSelection: false)
|
||||
}
|
||||
|
||||
if isScrolledToBottom {
|
||||
|
||||
if isScrolledToBottom() {
|
||||
self.scrollToBottom()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func setupTableViewHeaders() {
|
||||
|
||||
for tableColumn in self.tableView.tableColumns {
|
||||
|
||||
if tableColumn.identifier.rawValue == "statusCode" {
|
||||
|
||||
switch tableColumn.identifier.rawValue {
|
||||
case TableIdentifiers.statusCode:
|
||||
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Status")
|
||||
tableColumn.width = PacketsViewController.statusColumnWidth
|
||||
|
||||
}else if tableColumn.identifier.rawValue == "method" {
|
||||
|
||||
case TableIdentifiers.method:
|
||||
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Method")
|
||||
tableColumn.width = PacketsViewController.methodColumnWidth
|
||||
|
||||
}else if tableColumn.identifier.rawValue == "url" {
|
||||
|
||||
case TableIdentifiers.url:
|
||||
tableColumn.headerCell = FlatTableHeaderCell(textCell: "URL")
|
||||
tableColumn.width = self.view.frame.size.width - PacketsViewController.statusColumnWidth - PacketsViewController.dateColumnWidth - PacketsViewController.methodColumnWidth
|
||||
|
||||
}else if tableColumn.identifier.rawValue == "date" {
|
||||
|
||||
tableColumn.width = self.view.frame.size.width - PacketsViewController.statusColumnWidth - PacketsViewController.dateColumnWidth - PacketsViewController.methodColumnWidth
|
||||
case TableIdentifiers.date:
|
||||
tableColumn.headerCell = FlatTableHeaderCell(textCell: "Date")
|
||||
tableColumn.width = PacketsViewController.dateColumnWidth
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func clearButtonAction(_ sender: Any) {
|
||||
|
||||
self.viewModel?.clearPackets()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource
|
||||
{
|
||||
extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource {
|
||||
func numberOfRows(in tableView: NSTableView) -> Int {
|
||||
|
||||
return self.viewModel?.itemCount() ?? 0
|
||||
}
|
||||
|
||||
|
||||
func tableView(_ tableView: NSTableView, rowViewForRow row: Int) -> NSTableRowView? {
|
||||
|
||||
return FlatTableRowView()
|
||||
}
|
||||
|
||||
|
||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||
guard let identifier = tableColumn?.identifier.rawValue else { return nil }
|
||||
|
||||
if (tableColumn?.identifier)!.rawValue == "statusCode" {
|
||||
|
||||
switch identifier {
|
||||
case TableIdentifiers.statusCode:
|
||||
let cell: StatusPacketTableCellView = self.tableView.makeView(withOwner: nil)!
|
||||
cell.packet = self.viewModel?.item(at: row)
|
||||
cell.backgroundStyle = .normal
|
||||
return cell
|
||||
|
||||
}else if (tableColumn?.identifier)!.rawValue == "method" {
|
||||
|
||||
case TableIdentifiers.method:
|
||||
let cell: MethodPacketTableCellView = self.tableView.makeView(withOwner: nil)!
|
||||
cell.packet = self.viewModel?.item(at: row)
|
||||
cell.backgroundStyle = .normal
|
||||
return cell
|
||||
|
||||
}else if (tableColumn?.identifier)!.rawValue == "url" {
|
||||
|
||||
case TableIdentifiers.url:
|
||||
let cell: URLPacketTableCellView = self.tableView.makeView(withOwner: nil)!
|
||||
cell.packet = self.viewModel?.item(at: row)
|
||||
cell.backgroundStyle = .normal
|
||||
return cell
|
||||
|
||||
}else if (tableColumn?.identifier)!.rawValue == "date" {
|
||||
|
||||
case TableIdentifiers.date:
|
||||
let cell: DatePacketTableCellView = self.tableView.makeView(withOwner: nil)!
|
||||
cell.packet = self.viewModel?.item(at: row)
|
||||
cell.backgroundStyle = .normal
|
||||
return cell
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tableViewSelectionDidChange(_ notification: Notification) {
|
||||
|
||||
let selectedRow = self.tableView.selectedRow
|
||||
|
||||
if selectedRow >= 0 , let item = self.viewModel?.item(at: selectedRow) {
|
||||
|
||||
if item !== self.viewModel?.selectedItem {
|
||||
|
||||
self.onPacketSelect?(item)
|
||||
}
|
||||
}else {
|
||||
|
||||
guard selectedRow >= 0, let item = self.viewModel?.item(at: selectedRow) else {
|
||||
self.onPacketSelect?(nil)
|
||||
return
|
||||
}
|
||||
|
||||
guard item !== self.viewModel?.selectedItem else { return }
|
||||
self.onPacketSelect?(item)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -166,8 +167,18 @@ extension PacketsViewController: NSTableViewDelegate, NSTableViewDataSource
|
||||
extension PacketsViewController: NSTextFieldDelegate {
|
||||
|
||||
func controlTextDidChange(_ obj: Notification) {
|
||||
guard let tag = (obj.object as? NSTextField)?.tag else { return }
|
||||
guard let filterTag = FilterTags(rawValue: tag) else { return }
|
||||
|
||||
self.viewModel?.filterTerm = self.filterTextField.stringValue
|
||||
switch filterTag {
|
||||
case .address:
|
||||
viewModel?.addressFilterTerm = addressFilterTextField.stringValue
|
||||
case .method:
|
||||
viewModel?.methodFilterTerm = methodFilterTextField.stringValue
|
||||
case .status:
|
||||
viewModel?.statusFilterTerm = statusFilterTextField.stringValue
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -176,17 +187,11 @@ extension PacketsViewController: NSTextFieldDelegate {
|
||||
extension PacketsViewController {
|
||||
|
||||
func isScrolledToBottom() -> Bool {
|
||||
|
||||
if self.tableView.enclosingScrollView?.verticalScroller?.floatValue ?? 0 > 0.9 {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
return tableView.enclosingScrollView?.verticalScroller?.floatValue ?? 0 > 0.9
|
||||
}
|
||||
|
||||
func scrollToBottom() {
|
||||
|
||||
self.tableView.scrollToEndOfDocument(nil)
|
||||
tableView.scrollToEndOfDocument(nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,31 @@
|
||||
import Cocoa
|
||||
|
||||
class PacketsViewModel: BaseListViewModel<BagelPacket> {
|
||||
|
||||
var filterTerm = "" {
|
||||
|
||||
var addressFilterTerm = "" {
|
||||
didSet {
|
||||
self.refreshItems()
|
||||
}
|
||||
}
|
||||
|
||||
var methodFilterTerm = "" {
|
||||
didSet {
|
||||
self.refreshItems()
|
||||
}
|
||||
}
|
||||
|
||||
var statusFilterTerm = "" {
|
||||
didSet {
|
||||
self.refreshItems()
|
||||
}
|
||||
}
|
||||
|
||||
private var allPackets: [BagelPacket] {
|
||||
return BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? []
|
||||
}
|
||||
|
||||
|
||||
func register() {
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didGetPacket, object: nil)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didUpdatePacket, object: nil)
|
||||
@@ -27,46 +43,61 @@ class PacketsViewModel: BaseListViewModel<BagelPacket> {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshItems), name: BagelNotifications.didSelectDevice, object: nil)
|
||||
}
|
||||
|
||||
|
||||
var selectedItem: BagelPacket? {
|
||||
|
||||
return BagelController.shared.selectedProjectController?.selectedDeviceController?.selectedPacket
|
||||
}
|
||||
|
||||
|
||||
var selectedItemIndex: Int? {
|
||||
guard let selectedItem = self.selectedItem else { return nil }
|
||||
|
||||
if let selectedItem = self.selectedItem {
|
||||
|
||||
return self.items.firstIndex { $0 === selectedItem }
|
||||
}
|
||||
|
||||
return nil
|
||||
return self.items.firstIndex { $0 === selectedItem }
|
||||
}
|
||||
|
||||
@objc func refreshItems() {
|
||||
|
||||
self.filter(items: BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? [])
|
||||
self.onChange?()
|
||||
items = filter(items: allPackets)
|
||||
onChange?()
|
||||
}
|
||||
|
||||
func filter(items: [BagelPacket]?) {
|
||||
func filter(items: [BagelPacket]) -> [BagelPacket] {
|
||||
var filteredItems = performAddressFiltration(items)
|
||||
filteredItems = performMethodFiltration(filteredItems)
|
||||
return performStatusFiltration(filteredItems)
|
||||
}
|
||||
|
||||
func performAddressFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
|
||||
guard addressFilterTerm.count > 0 else {
|
||||
return items
|
||||
}
|
||||
|
||||
if let items = items, filterTerm.count > 0 {
|
||||
|
||||
self.items = items.filter({ (packet) -> Bool in
|
||||
|
||||
return packet.requestInfo?.url?.contains(self.filterTerm) ?? true
|
||||
})
|
||||
|
||||
}else{
|
||||
|
||||
self.items = BagelController.shared.selectedProjectController?.selectedDeviceController?.packets ?? []
|
||||
return items.filter {
|
||||
$0.requestInfo?.url?.contains(self.addressFilterTerm) ?? true }
|
||||
}
|
||||
|
||||
func performMethodFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
|
||||
guard methodFilterTerm.count > 0 else {
|
||||
return items
|
||||
}
|
||||
|
||||
return items.filter
|
||||
{ $0.requestInfo?.requestMethod?.rawValue.lowercased()
|
||||
.contains(self.methodFilterTerm.lowercased()) ?? true }
|
||||
}
|
||||
|
||||
func performStatusFiltration(_ items: [BagelPacket]) -> [BagelPacket] {
|
||||
guard statusFilterTerm.count > 0 else {
|
||||
return items
|
||||
}
|
||||
|
||||
guard !statusFilterTerm.trimmingCharacters(in: .whitespaces).isEmpty else {
|
||||
return items.filter { $0.requestInfo?.statusCode?.trimmingCharacters(in: .whitespaces).isEmpty ?? true}
|
||||
}
|
||||
|
||||
return items.filter
|
||||
{ $0.requestInfo?.statusCode?.contains(self.statusFilterTerm) ?? false
|
||||
}
|
||||
}
|
||||
|
||||
func clearPackets() {
|
||||
|
||||
BagelController.shared.selectedProjectController?.selectedDeviceController?.clear()
|
||||
self.refreshItems()
|
||||
}
|
||||
|
||||
@@ -11,20 +11,18 @@ import macOSThemeKit
|
||||
|
||||
class URLPacketTableCellView: NSTableCellView {
|
||||
|
||||
@IBOutlet weak var titleTextField: NSTextField!
|
||||
@IBOutlet private weak var titleTextField: NSTextField!
|
||||
|
||||
var packet: BagelPacket!
|
||||
{
|
||||
didSet
|
||||
{
|
||||
self.refresh()
|
||||
var packet: BagelPacket? {
|
||||
didSet{
|
||||
guard let packet = packet else { return }
|
||||
refresh(with: packet)
|
||||
}
|
||||
}
|
||||
|
||||
func refresh() {
|
||||
|
||||
self.titleTextField.textColor = ThemeColor.labelColor
|
||||
self.titleTextField.stringValue = self.packet.requestInfo?.url ?? ""
|
||||
func refresh(with packet: BagelPacket) {
|
||||
titleTextField.textColor = ThemeColor.labelColor
|
||||
titleTextField.stringValue = packet.requestInfo?.url ?? ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ class ProjectsViewController: BaseViewController {
|
||||
self.tableView.delegate = self
|
||||
self.tableView.dataSource = self
|
||||
self.tableView.backgroundColor = ThemeColor.projectListBackgroundColor
|
||||
|
||||
|
||||
|
||||
|
||||
self.viewModel?.onChange = { [weak self] in
|
||||
|
||||
self?.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
import Cocoa
|
||||
|
||||
class BagelPacket: Codable {
|
||||
|
||||
var packetId: String?
|
||||
|
||||
var requestInfo: BagelRequestInfo?
|
||||
|
||||
@@ -8,12 +8,20 @@
|
||||
|
||||
import Cocoa
|
||||
|
||||
enum RequestMethod: String, Codable {
|
||||
case get = "GET"
|
||||
case post = "POST"
|
||||
case put = "PUT"
|
||||
case delete = "DELETE"
|
||||
case head = "HEAD"
|
||||
}
|
||||
|
||||
class BagelRequestInfo: Codable {
|
||||
|
||||
var url: String?
|
||||
var requestHeaders: [String: String]?
|
||||
var requestBody: String?
|
||||
var requestMethod: String?
|
||||
var requestMethod: RequestMethod?
|
||||
|
||||
var responseHeaders: [String: String]?
|
||||
var responseData: String?
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// CURLRepresentation.swift
|
||||
// Bagel
|
||||
//
|
||||
// Created by Mathias Amnell on 2019-01-23.
|
||||
// Copyright © 2019 Yagiz Lab. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class CURLRepresentation: ContentRepresentation {
|
||||
|
||||
init(requestInfo: BagelRequestInfo?) {
|
||||
|
||||
super.init()
|
||||
|
||||
if let requestInfo = requestInfo {
|
||||
self.rawString = requestInfo.curlString
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BagelRequestInfo {
|
||||
// Credits to shaps80
|
||||
// https://gist.github.com/shaps80/ba6a1e2d477af0383e8f19b87f53661d
|
||||
fileprivate var curlString: String {
|
||||
guard let url = url else { return "" }
|
||||
var baseCommand = "curl \(url)"
|
||||
|
||||
if requestMethod == .head {
|
||||
baseCommand += " --head"
|
||||
}
|
||||
|
||||
var command = [baseCommand]
|
||||
|
||||
if let method = self.requestMethod, method != .get && method != .head {
|
||||
command.append("-X \(method)")
|
||||
}
|
||||
|
||||
if let headers = requestHeaders {
|
||||
for (key, value) in headers where key != "Cookie" {
|
||||
command.append("-H '\(key): \(value)'")
|
||||
}
|
||||
}
|
||||
|
||||
if let data = requestBody {
|
||||
command.append("-d '\(data)'")
|
||||
}
|
||||
|
||||
return command.joined(separator: " \\\n\t")
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -18,7 +18,7 @@ class OverviewRepresentation: ContentRepresentation {
|
||||
|
||||
var overviewString = ""
|
||||
|
||||
overviewString = overviewString + (requestInfo.requestMethod ?? "")
|
||||
overviewString = overviewString + (requestInfo.requestMethod?.rawValue ?? "")
|
||||
overviewString = overviewString + " "
|
||||
overviewString = overviewString + (requestInfo.url ?? "")
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
}
|
||||
|
||||
if (value === null) {
|
||||
return '<li><span class="key">"' + encode(key) + '": </span><span class="null">"' + encode(value) + '"</span></li>';
|
||||
return '<li><span class="key">"' + encode(key) + '": </span><span class="null">null</span></li>';
|
||||
}
|
||||
|
||||
switch(type){
|
||||
|
||||
+1
-1
@@ -17,4 +17,4 @@ SPEC CHECKSUMS:
|
||||
|
||||
PODFILE CHECKSUM: ebe70cf0430bb9673b9d2acef3c2a16142460de8
|
||||
|
||||
COCOAPODS: 1.6.0.beta.2
|
||||
COCOAPODS: 1.6.0
|
||||
|
||||
Reference in New Issue
Block a user