diff --git a/interject/Interject! Watch Watch App/Assets.xcassets/AccentColor.colorset/Contents.json b/interject/Interject! Watch Watch App/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/interject/Interject! Watch Watch App/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/interject/Interject! Watch Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json b/interject/Interject! Watch Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..49c81cd --- /dev/null +++ b/interject/Interject! Watch Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "watchos", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/interject/Interject! Watch Watch App/Assets.xcassets/Contents.json b/interject/Interject! Watch Watch App/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/interject/Interject! Watch Watch App/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/interject/Interject! Watch Watch App/ContentView.swift b/interject/Interject! Watch Watch App/ContentView.swift new file mode 100644 index 0000000..31e0b29 --- /dev/null +++ b/interject/Interject! Watch Watch App/ContentView.swift @@ -0,0 +1,26 @@ +// +// ContentView.swift +// Interject! Watch Watch App +// +// Created by Rory on 7/12/26. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + Spacer() + VStack { + Text(Sentence().word(.first, safe: true)) + Text(Sentence().word(.second, safe: true)) + Text(Sentence().word(.noun, safe: true)) + } + Spacer() + Text("SFW") + .padding() + } +} + +#Preview { + ContentView() +} diff --git a/interject/Interject! Watch Watch App/Interject__WatchApp.swift b/interject/Interject! Watch Watch App/Interject__WatchApp.swift new file mode 100644 index 0000000..01ecfc2 --- /dev/null +++ b/interject/Interject! Watch Watch App/Interject__WatchApp.swift @@ -0,0 +1,25 @@ +// +// Interject__WatchApp.swift +// Interject! Watch Watch App +// +// Created by Rory on 7/12/26. +// + +import SwiftUI + +extension String { + var uppercaseFirst: String { + return prefix(1).uppercased() + dropFirst() + } +} + +@main +struct Interject__Watch_Watch_AppApp: App { + var safeForWork = true; + var phrase = Sentence() + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/interject/Interject! Watch Watch AppTests/Interject__Watch_Watch_AppTests.swift b/interject/Interject! Watch Watch AppTests/Interject__Watch_Watch_AppTests.swift new file mode 100644 index 0000000..92a289b --- /dev/null +++ b/interject/Interject! Watch Watch AppTests/Interject__Watch_Watch_AppTests.swift @@ -0,0 +1,19 @@ +// +// Interject__Watch_Watch_AppTests.swift +// Interject! Watch Watch AppTests +// +// Created by Rory on 7/12/26. +// + +import Testing +@testable import Interject__Watch_Watch_App + +struct Interject__Watch_Watch_AppTests { + + @Test func example() async throws { + // Write your test here and use APIs like `#expect(...)` to check expected conditions. + // Swift Testing Documentation + // https://developer.apple.com/documentation/testing + } + +} diff --git a/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITests.swift b/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITests.swift new file mode 100644 index 0000000..96ba33b --- /dev/null +++ b/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITests.swift @@ -0,0 +1,43 @@ +// +// Interject__Watch_Watch_AppUITests.swift +// Interject! Watch Watch AppUITests +// +// Created by Rory on 7/12/26. +// + +import XCTest + +final class Interject__Watch_Watch_AppUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + // XCUIAutomation Documentation + // https://developer.apple.com/documentation/xcuiautomation + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITestsLaunchTests.swift b/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITestsLaunchTests.swift new file mode 100644 index 0000000..84c6584 --- /dev/null +++ b/interject/Interject! Watch Watch AppUITests/Interject__Watch_Watch_AppUITestsLaunchTests.swift @@ -0,0 +1,35 @@ +// +// Interject__Watch_Watch_AppUITestsLaunchTests.swift +// Interject! Watch Watch AppUITests +// +// Created by Rory on 7/12/26. +// + +import XCTest + +final class Interject__Watch_Watch_AppUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + // XCUIAutomation Documentation + // https://developer.apple.com/documentation/xcuiautomation + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/interject/Interject! iMessage/MainInterface.storyboard b/interject/Interject! iMessage/MainInterface.storyboard index 326d211..c96a5c3 100644 --- a/interject/Interject! iMessage/MainInterface.storyboard +++ b/interject/Interject! iMessage/MainInterface.storyboard @@ -1,8 +1,8 @@ - + - + @@ -28,8 +28,19 @@ - + + + + @@ -38,6 +49,17 @@ + + + @@ -55,10 +77,6 @@ - - - - @@ -68,16 +86,8 @@ - - - - - - - - - - + + diff --git a/interject/Interject! iMessage/MessagesViewController.swift b/interject/Interject! iMessage/MessagesViewController.swift index f01f800..d9f88ae 100644 --- a/interject/Interject! iMessage/MessagesViewController.swift +++ b/interject/Interject! iMessage/MessagesViewController.swift @@ -21,6 +21,8 @@ class MessagesViewController: MSMessagesAppViewController { // MARK: UI VARS @IBOutlet weak var sfwLabel: UIBarButtonItem! @IBOutlet weak var phraseLabel: UILabel! + @IBOutlet weak var newLabel: UIBarButtonItem! + @IBOutlet weak var sendLabel: UIBarButtonItem! // MARK: Local Vars @@ -32,7 +34,8 @@ class MessagesViewController: MSMessagesAppViewController { // first load, Let's explain what the need to do. override func viewDidLoad() { super.viewDidLoad() - phraseLabel.text = "Swipe down for new words, up to send." + sentence = Sentence().new(current: sentence) + updatePhraseLabel() } // Toggle sfw @@ -57,7 +60,11 @@ class MessagesViewController: MSMessagesAppViewController { // Send a phrase to messages @IBAction func sendPhrase(_ sender: Any) { let conversation = self.activeConversation - conversation?.insertText(phraseLabel.text!) { error in } + conversation?.insertText(phraseLabel.text!) { [weak self] error in + DispatchQueue.main.async { + self?.requestPresentationStyle(.compact) + } + } } // Update the label diff --git a/interject/Interject!.xcodeproj/project.pbxproj b/interject/Interject!.xcodeproj/project.pbxproj index c29c751..4374b99 100644 --- a/interject/Interject!.xcodeproj/project.pbxproj +++ b/interject/Interject!.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ 761EDD593003F176006FC7FB /* Interject! iMessage.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 761EDD4C3003F175006FC7FB /* Interject! iMessage.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 761EDD6E3003F269006FC7FB /* words.json in Resources */ = {isa = PBXBuildFile; fileRef = 765F5A4B30029EC7004C2F29 /* words.json */; }; 761EDD703003F5FF006FC7FB /* Words.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98D0A2DE274721620084F7F9 /* Words.swift */; }; + 761EDD9530040902006FC7FB /* Interject! Watch Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 761EDD7530040900006FC7FB /* Interject! Watch Watch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 761EDDA030040B14006FC7FB /* Words.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98D0A2DE274721620084F7F9 /* Words.swift */; }; 762C51A22BC33AE5000689D9 /* Tips.swift in Sources */ = {isa = PBXBuildFile; fileRef = 762C51A12BC33AE5000689D9 /* Tips.swift */; }; 762C51A42BCAD9BC000689D9 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 762C51A32BCAD9BC000689D9 /* StoreKit.framework */; }; 762C51A62BCADA1C000689D9 /* Products.storekit in Resources */ = {isa = PBXBuildFile; fileRef = 762C51A52BCADA1C000689D9 /* Products.storekit */; }; @@ -46,6 +48,27 @@ remoteGlobalIDString = 761EDD4B3003F175006FC7FB; remoteInfo = "Interject! iMessage"; }; + 761EDD8230040902006FC7FB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 98D0A29D27471FF80084F7F9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 761EDD7430040900006FC7FB; + remoteInfo = "Interject! Watch Watch App"; + }; + 761EDD8C30040902006FC7FB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 98D0A29D27471FF80084F7F9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 761EDD7430040900006FC7FB; + remoteInfo = "Interject! Watch Watch App"; + }; + 761EDD9330040902006FC7FB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 98D0A29D27471FF80084F7F9 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 761EDD7430040900006FC7FB; + remoteInfo = "Interject! Watch Watch App"; + }; 98D0A2B627471FF90084F7F9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 98D0A29D27471FF80084F7F9 /* Project object */; @@ -63,6 +86,17 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 761EDD9930040902006FC7FB /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + 761EDD9530040902006FC7FB /* Interject! Watch Watch App.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; 98EA0F4F2863963F00B4E136 /* Embed Foundation Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -79,6 +113,9 @@ /* Begin PBXFileReference section */ 761EDD463003EB67006FC7FB /* Intents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Intents.swift; sourceTree = ""; }; 761EDD4C3003F175006FC7FB /* Interject! iMessage.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Interject! iMessage.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + 761EDD7530040900006FC7FB /* Interject! Watch Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Interject! Watch Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 761EDD8130040902006FC7FB /* Interject! Watch Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Interject! Watch Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 761EDD8B30040902006FC7FB /* Interject! Watch Watch AppUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Interject! Watch Watch AppUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 762C51A12BC33AE5000689D9 /* Tips.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tips.swift; sourceTree = ""; }; 762C51A32BCAD9BC000689D9 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; 762C51A52BCADA1C000689D9 /* Products.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Products.storekit; sourceTree = ""; }; @@ -121,6 +158,9 @@ /* Begin PBXFileSystemSynchronizedRootGroup section */ 761EDD4E3003F175006FC7FB /* Interject! iMessage */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (761EDD6F3003F317006FC7FB /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = "Interject! iMessage"; sourceTree = ""; }; + 761EDD7630040900006FC7FB /* Interject! Watch Watch App */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Interject! Watch Watch App"; sourceTree = ""; }; + 761EDD8430040902006FC7FB /* Interject! Watch Watch AppTests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Interject! Watch Watch AppTests"; sourceTree = ""; }; + 761EDD8E30040902006FC7FB /* Interject! Watch Watch AppUITests */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "Interject! Watch Watch AppUITests"; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ @@ -132,6 +172,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 761EDD7230040900006FC7FB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD7E30040902006FC7FB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD8830040902006FC7FB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 98D0A2A227471FF80084F7F9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -181,6 +242,9 @@ 98D0A2B827471FF90084F7F9 /* Interject!Tests */, 98D0A2C227471FF90084F7F9 /* Interject!UITests */, 761EDD4E3003F175006FC7FB /* Interject! iMessage */, + 761EDD7630040900006FC7FB /* Interject! Watch Watch App */, + 761EDD8430040902006FC7FB /* Interject! Watch Watch AppTests */, + 761EDD8E30040902006FC7FB /* Interject! Watch Watch AppUITests */, 9879879A2865299F00E82AF6 /* Frameworks */, 98D0A2A627471FF80084F7F9 /* Products */, ); @@ -193,6 +257,9 @@ 98D0A2B527471FF90084F7F9 /* Interject!Tests.xctest */, 98D0A2BF27471FF90084F7F9 /* Interject!UITests.xctest */, 761EDD4C3003F175006FC7FB /* Interject! iMessage.appex */, + 761EDD7530040900006FC7FB /* Interject! Watch Watch App.app */, + 761EDD8130040902006FC7FB /* Interject! Watch Watch AppTests.xctest */, + 761EDD8B30040902006FC7FB /* Interject! Watch Watch AppUITests.xctest */, ); name = Products; sourceTree = ""; @@ -291,6 +358,74 @@ productReference = 761EDD4C3003F175006FC7FB /* Interject! iMessage.appex */; productType = "com.apple.product-type.app-extension.messages"; }; + 761EDD7430040900006FC7FB /* Interject! Watch Watch App */ = { + isa = PBXNativeTarget; + buildConfigurationList = 761EDD9630040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch App" */; + buildPhases = ( + 761EDD7130040900006FC7FB /* Sources */, + 761EDD7230040900006FC7FB /* Frameworks */, + 761EDD7330040900006FC7FB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 761EDD7630040900006FC7FB /* Interject! Watch Watch App */, + ); + name = "Interject! Watch Watch App"; + packageProductDependencies = ( + ); + productName = "Interject! Watch Watch App"; + productReference = 761EDD7530040900006FC7FB /* Interject! Watch Watch App.app */; + productType = "com.apple.product-type.application"; + }; + 761EDD8030040902006FC7FB /* Interject! Watch Watch AppTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 761EDD9A30040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch AppTests" */; + buildPhases = ( + 761EDD7D30040902006FC7FB /* Sources */, + 761EDD7E30040902006FC7FB /* Frameworks */, + 761EDD7F30040902006FC7FB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 761EDD8330040902006FC7FB /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 761EDD8430040902006FC7FB /* Interject! Watch Watch AppTests */, + ); + name = "Interject! Watch Watch AppTests"; + packageProductDependencies = ( + ); + productName = "Interject! Watch Watch AppTests"; + productReference = 761EDD8130040902006FC7FB /* Interject! Watch Watch AppTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 761EDD8A30040902006FC7FB /* Interject! Watch Watch AppUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 761EDD9D30040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch AppUITests" */; + buildPhases = ( + 761EDD8730040902006FC7FB /* Sources */, + 761EDD8830040902006FC7FB /* Frameworks */, + 761EDD8930040902006FC7FB /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 761EDD8D30040902006FC7FB /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + 761EDD8E30040902006FC7FB /* Interject! Watch Watch AppUITests */, + ); + name = "Interject! Watch Watch AppUITests"; + packageProductDependencies = ( + ); + productName = "Interject! Watch Watch AppUITests"; + productReference = 761EDD8B30040902006FC7FB /* Interject! Watch Watch AppUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; 98D0A2A427471FF80084F7F9 /* Interject! */ = { isa = PBXNativeTarget; buildConfigurationList = 98D0A2C927471FF90084F7F9 /* Build configuration list for PBXNativeTarget "Interject!" */; @@ -299,11 +434,13 @@ 98D0A2A227471FF80084F7F9 /* Frameworks */, 98D0A2A327471FF80084F7F9 /* Resources */, 98EA0F4F2863963F00B4E136 /* Embed Foundation Extensions */, + 761EDD9930040902006FC7FB /* Embed Watch Content */, ); buildRules = ( ); dependencies = ( 761EDD583003F176006FC7FB /* PBXTargetDependency */, + 761EDD9430040902006FC7FB /* PBXTargetDependency */, ); name = "Interject!"; productName = "Interject!"; @@ -354,12 +491,23 @@ attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 2650; - LastUpgradeCheck = 2650; + LastUpgradeCheck = 2700; TargetAttributes = { 761EDD4B3003F175006FC7FB = { CreatedOnToolsVersion = 26.5; LastSwiftMigration = 2650; }; + 761EDD7430040900006FC7FB = { + CreatedOnToolsVersion = 26.5; + }; + 761EDD8030040902006FC7FB = { + CreatedOnToolsVersion = 26.5; + TestTargetID = 761EDD7430040900006FC7FB; + }; + 761EDD8A30040902006FC7FB = { + CreatedOnToolsVersion = 26.5; + TestTargetID = 761EDD7430040900006FC7FB; + }; 98D0A2A427471FF80084F7F9 = { CreatedOnToolsVersion = 13.1; }; @@ -390,6 +538,9 @@ 98D0A2B427471FF90084F7F9 /* Interject!Tests */, 98D0A2BE27471FF90084F7F9 /* Interject!UITests */, 761EDD4B3003F175006FC7FB /* Interject! iMessage */, + 761EDD7430040900006FC7FB /* Interject! Watch Watch App */, + 761EDD8030040902006FC7FB /* Interject! Watch Watch AppTests */, + 761EDD8A30040902006FC7FB /* Interject! Watch Watch AppUITests */, ); }; /* End PBXProject section */ @@ -403,6 +554,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 761EDD7330040900006FC7FB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD7F30040902006FC7FB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD8930040902006FC7FB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 98D0A2A327471FF80084F7F9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -441,6 +613,28 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 761EDD7130040900006FC7FB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 761EDDA030040B14006FC7FB /* Words.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD7D30040902006FC7FB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 761EDD8730040902006FC7FB /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 98D0A2A127471FF80084F7F9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -488,6 +682,21 @@ target = 761EDD4B3003F175006FC7FB /* Interject! iMessage */; targetProxy = 761EDD573003F176006FC7FB /* PBXContainerItemProxy */; }; + 761EDD8330040902006FC7FB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 761EDD7430040900006FC7FB /* Interject! Watch Watch App */; + targetProxy = 761EDD8230040902006FC7FB /* PBXContainerItemProxy */; + }; + 761EDD8D30040902006FC7FB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 761EDD7430040900006FC7FB /* Interject! Watch Watch App */; + targetProxy = 761EDD8C30040902006FC7FB /* PBXContainerItemProxy */; + }; + 761EDD9430040902006FC7FB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 761EDD7430040900006FC7FB /* Interject! Watch Watch App */; + targetProxy = 761EDD9330040902006FC7FB /* PBXContainerItemProxy */; + }; 98D0A2B727471FF90084F7F9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 98D0A2A427471FF80084F7F9 /* Interject! */; @@ -514,7 +723,7 @@ INFOPLIST_FILE = "Interject! iMessage/Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "Interject! iMessage"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 26.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -549,7 +758,7 @@ INFOPLIST_FILE = "Interject! iMessage/Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "Interject! iMessage"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; - IPHONEOS_DEPLOYMENT_TARGET = 26.5; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -569,6 +778,187 @@ }; name = Release; }; + 761EDD9730040902006FC7FB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = "Interject! Watch"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "us.hinnen.Interject-"; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 3.04; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.watchkitapp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 26.6; + }; + name = Debug; + }; + 761EDD9830040902006FC7FB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = "Interject! Watch"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = "us.hinnen.Interject-"; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 3.04; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.watchkitapp"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 26.6; + }; + name = Release; + }; + 761EDD9B30040902006FC7FB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5P9XB49J6K; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.Interject--Watch-Watch-AppTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Interject! Watch Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Interject! Watch Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 26.5; + }; + name = Debug; + }; + 761EDD9C30040902006FC7FB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5P9XB49J6K; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.Interject--Watch-Watch-AppTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Interject! Watch Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Interject! Watch Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 26.5; + }; + name = Release; + }; + 761EDD9E30040902006FC7FB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5P9XB49J6K; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.Interject--Watch-Watch-AppUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_TARGET_NAME = "Interject! Watch Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 26.5; + }; + name = Debug; + }; + 761EDD9F30040902006FC7FB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 5P9XB49J6K; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "us.hinnen.Interject-.Interject--Watch-Watch-AppUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + STRING_CATALOG_GENERATE_SYMBOLS = NO; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_TARGET_NAME = "Interject! Watch Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 26.5; + }; + name = Release; + }; 98D0A2C727471FF90084F7F9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -632,6 +1022,7 @@ STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; @@ -691,6 +1082,7 @@ STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = 1; VALIDATE_PRODUCT = YES; }; name = Release; @@ -712,7 +1104,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -743,7 +1135,7 @@ INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 17.6; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -764,7 +1156,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -787,7 +1179,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -809,6 +1201,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -830,6 +1223,7 @@ CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = "$(RECOMMENDED_IPHONEOS_DEPLOYMENT_TARGET)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -857,6 +1251,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 761EDD9630040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 761EDD9730040902006FC7FB /* Debug */, + 761EDD9830040902006FC7FB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 761EDD9A30040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch AppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 761EDD9B30040902006FC7FB /* Debug */, + 761EDD9C30040902006FC7FB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 761EDD9D30040902006FC7FB /* Build configuration list for PBXNativeTarget "Interject! Watch Watch AppUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 761EDD9E30040902006FC7FB /* Debug */, + 761EDD9F30040902006FC7FB /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 98D0A2A027471FF80084F7F9 /* Build configuration list for PBXProject "Interject!" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/interject/Interject!.xcodeproj/project.xcworkspace/xcuserdata/roryhinnen.xcuserdatad/UserInterfaceState.xcuserstate b/interject/Interject!.xcodeproj/project.xcworkspace/xcuserdata/roryhinnen.xcuserdatad/UserInterfaceState.xcuserstate index 3882ca6..5772d87 100644 Binary files a/interject/Interject!.xcodeproj/project.xcworkspace/xcuserdata/roryhinnen.xcuserdatad/UserInterfaceState.xcuserstate and b/interject/Interject!.xcodeproj/project.xcworkspace/xcuserdata/roryhinnen.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/interject/Interject!.xcodeproj/xcshareddata/xcschemes/Interject!.xcscheme b/interject/Interject!.xcodeproj/xcshareddata/xcschemes/Interject!.xcscheme index 29ec41d..0518a88 100644 --- a/interject/Interject!.xcodeproj/xcshareddata/xcschemes/Interject!.xcscheme +++ b/interject/Interject!.xcodeproj/xcshareddata/xcschemes/Interject!.xcscheme @@ -1,6 +1,6 @@ SchemeUserState + Interject! Watch Watch App.xcscheme_^#shared#^_ + + orderHint + 2 + Interject! iMessage MessagesExtension.xcscheme_^#shared#^_ orderHint diff --git a/interject/Interject!/Intents.swift b/interject/Interject!/Intents.swift index 9f6c045..0ceaed8 100644 --- a/interject/Interject!/Intents.swift +++ b/interject/Interject!/Intents.swift @@ -5,35 +5,33 @@ import AppIntents -@available(iOS 16.0, *) -struct GenerateInsultIntent: AppIntent { - static var title: LocalizedStringResource = "Generate Insult" - static var description = IntentDescription("Generates a new random insult phrase.") +struct GenerateDescriptorIntent: AppIntent { + static var title: LocalizedStringResource = "Interject" + static var description = IntentDescription("Generates a new random descriptive phrase.") func perform() async throws -> some IntentResult & ReturnsValue { // Fall back to true (safe mode) if the app hasn't set the preference yet let isSfw = UserDefaults.standard.object(forKey: "SFW") as? Bool ?? true let sentence = Sentence().new(current: Sentence()) - let insult = [ + let interjection = [ sentence.word(.first, safe: isSfw), sentence.word(.second, safe: isSfw), sentence.word(.noun, safe: isSfw) ].joined(separator: " ") - return .result(value: insult) + return .result(value: interjection, dialog: IntentDialog(stringLiteral: interjection)) } } -@available(iOS 16.0, *) struct InterjectShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( - intent: GenerateInsultIntent(), + intent: GenerateDescriptorIntent(), phrases: [ - "Generate an insult with \(.applicationName)", - "Insult me with \(.applicationName)", - "Give me an insult from \(.applicationName)" + "Generate an interjection with \(.applicationName)", + "Describe me with \(.applicationName)", + "Give me an interjection from \(.applicationName)" ], - shortTitle: "Generate Insult", + shortTitle: "Generate Interjection", systemImageName: "bubble.left.fill" ) } diff --git a/interject/Interject!/View/Interject_App.swift b/interject/Interject!/View/Interject_App.swift index f1ddb45..130c284 100644 --- a/interject/Interject!/View/Interject_App.swift +++ b/interject/Interject!/View/Interject_App.swift @@ -6,6 +6,7 @@ // import SwiftUI +import AppIntents @main @@ -13,6 +14,10 @@ struct Interject_App: App { @StateObject var settings = Settings() @StateObject var store = Store() + init() { + InterjectShortcuts.updateAppShortcutParameters() + } + var body: some Scene { WindowGroup { ContentView() diff --git a/interject/Interject!/words.json b/interject/Interject!/words.json index 4f7124f..789e2ed 100644 --- a/interject/Interject!/words.json +++ b/interject/Interject!/words.json @@ -24,7 +24,7 @@ {"word": "clay-brained", "meaning": "Rock head"}, {"word": "clouted", "meaning": "Senseless, reeling from being beat"}, {"word": "cockered", "meaning": "Spoiled"}, - {"word": "couch-loving", "meaning": "A less than attractive person", "nsfw": "couch-fucking", "nsfwMeaning": "J.D. Vance"}, + {"word": "couch-loving", "meaning": "The amourous intention of a rural poet", "nsfw": "couch-fucking", "nsfwMeaning": "The sexual target of a rural poet"}, {"word": "common-kissing", "meaning": "Rogue, a rascal, grabs others without permission"}, {"word": "craven", "meaning": "Cowardly"}, {"word": "crook-pated", "meaning": "A thug, a thief who takes by violence"},