Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/Upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
NoahKamara committed Sep 27, 2023
2 parents acd3913 + 8fd1ab0 commit dde7d52
Show file tree
Hide file tree
Showing 44 changed files with 355 additions and 692 deletions.
11 changes: 9 additions & 2 deletions .github/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,18 @@
- Run the “Actions” target, which will open the app and then open the Shortcuts app. You can then test out your work.
- Add the action to `readme.md` and `app-store-description.txt`.

#### Code style

- Use tab-indentation.
- Use `/**\nDescription.\n*/` comment style over `\\\ Description.`.
- Prefer `let` whenever possible.
- Make types and variables `private` whenever possible.
- Make sure linting passes.
- Keep all the code related to the action in a single file. Reusable extensions can be put in `Utilities.swift`.

### General

- Make sure you test on both macOS and iOS before submitting a pull request.
- Make sure linting passes.
- Use tab-indentation.

### Pull request

Expand Down
374 changes: 40 additions & 334 deletions Actions.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Actions.xcodeproj/xcshareddata/xcschemes/Actions.xcscheme
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1400"
LastUpgradeVersion = "1500"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1410"
LastUpgradeVersion = "1500"
wasCreatedForAppExtension = "YES"
version = "2.0">
<BuildAction
Expand All @@ -16,8 +16,8 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "E31748A52916A0B100F6319E"
BuildableName = "Intents Extension iOS.appex"
BlueprintName = "Intents Extension iOS"
BuildableName = "Intents Extension.appex"
BlueprintName = "Intents Extension"
ReferencedContainer = "container:Actions.xcodeproj">
</BuildableReference>
</BuildActionEntry>
Expand Down
4 changes: 2 additions & 2 deletions Config.xcconfig
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
MARKETING_VERSION = 2.7.0
CURRENT_PROJECT_VERSION = 45
MARKETING_VERSION = 2.8.1
CURRENT_PROJECT_VERSION = 47
30 changes: 30 additions & 0 deletions Intents Extension/Actions/Boolean.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import AppIntents

struct Boolean: AppIntent {
static let title: LocalizedStringResource = "Boolean"

static let description = IntentDescription(
"""
Passes the specified boolean value to the next action.
Similar to the built-in “Number” and “Text” actions.
This can be useful if you want to create a variable that is initially set to a boolean.
""",
categoryName: "Parse / Generate"
)

@Parameter(
title: "Boolean",
displayName: Bool.IntentDisplayName(true: "true", false: "false")
)
var boolean: Bool

static var parameterSummary: some ParameterSummary {
Summary("\(\.$boolean)")
}

func perform() async throws -> some IntentResult & ReturnsValue<Bool> {
.result(value: boolean)
}
}
3 changes: 1 addition & 2 deletions Intents Extension/Actions/ConvertCoordinatesToLocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ Tip: Use the built-in “Get Details of Locations” action to get more details
Summary("Get location at coordinates \(\.$latitude), \(\.$longitude)")
}

@MainActor
func perform() async throws -> some IntentResult & ReturnsValue<CLLocation> {
func perform() async throws -> some IntentResult & ReturnsValue<CLPlacemark> {
let placemarks = try await CLGeocoder().reverseGeocodeLocation(.init(latitude: latitude, longitude: longitude))

guard let placemark = placemarks.first else {
Expand Down
12 changes: 6 additions & 6 deletions Intents Extension/Actions/FormatDuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,17 @@ extension FormatDurationUnitStyleAppEnum {
fileprivate var toNative: DateComponentsFormatter.UnitsStyle {
switch self {
case .positional:
return .positional
.positional
case .abbreviated:
return .abbreviated
.abbreviated
case .brief:
return .brief
.brief
case .short:
return .short
.short
case .full:
return .full
.full
case .spellOut:
return .spellOut
.spellOut
}
}
}
8 changes: 4 additions & 4 deletions Intents Extension/Actions/FormatPersonName.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ extension FormatPersonNameStyleAppEnum {
fileprivate var toNative: PersonNameComponents.FormatStyle.Style {
switch self {
case .short:
return .short
.short
case .medium:
return .medium
.medium
case .long:
return .long
.long
case .abbreviated:
return .abbreviated
.abbreviated
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions Intents Extension/Actions/GetBatteryState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@ struct GetBatteryState: AppIntent, CustomIntentMigratedAppIntent {
}

func perform() async throws -> some IntentResult & ReturnsValue<Bool> {
let result = {
switch state {
let result = switch state {
case .unplugged:
return Device.batteryState == .unplugged
Device.batteryState == .unplugged
case .charging:
return Device.batteryState == .charging
Device.batteryState == .charging
case .full:
return Device.batteryState == .full
Device.batteryState == .full
}
}()

return .result(value: result)
}
Expand Down
10 changes: 4 additions & 6 deletions Intents Extension/Actions/GetFilePath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ Folder paths always end with a slash.
throw "The given file does not have a path.".toError
}

var result = {
switch type {
var result = switch type {
case .path:
return fileURL.path
fileURL.path
case .url:
return fileURL.absoluteString
fileURL.absoluteString
case .tildePath:
return fileURL.tildePath
fileURL.tildePath
}
}()

if file.type == .folder {
result = result.ensureSuffix("/")
Expand Down
92 changes: 92 additions & 0 deletions Intents Extension/Actions/GetModifierKeyState.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import AppIntents
import SwiftUI

@available(iOS, unavailable)
struct GetModifierKeyState: AppIntent {
static let title: LocalizedStringResource = "Get Modifier Key State"

static let description = IntentDescription(
"""
Returns which modifier keys are currently pressed.
This can be useful to have alternative behavior when, for example, the user presses the Option key.
Supported modifier keys:
- Shift
- Control
- Option
- Command
- Function
""",
categoryName: "Device",
searchKeywords: [
"keyboard",
"shortcut",
"hotkey"
]
)

static var parameterSummary: some ParameterSummary {
Summary("Get state of modifier keys")
}

func perform() async throws -> some IntentResult & ReturnsValue<ModifierKeyState_AppEntity> {
.result(value: .init())
}
}

// Note: It should be possible to support iOS, but I don't have a physical keyboard to test with (doesn't work in the simulator), so I'm leaving it out for now.
// `GCKeyboard.coalesced?.keyboardInput?.button(forKeyCode: .leftShift)?.isPressed`s

struct ModifierKeyState_AppEntity: TransientAppEntity {
static let typeDisplayRepresentation = TypeDisplayRepresentation(name: "Modifier Key State")

@Property(title: "Shift")
var shift: Bool

@Property(title: "Control")
var control: Bool

@Property(title: "Option")
var option: Bool

@Property(title: "Command")
var command: Bool

@Property(title: "Function (Fn)")
var function: Bool

var displayRepresentation: DisplayRepresentation {
.init(
title: "Modifier keys",
subtitle:
"""
Shift: \("\(shift)")
Control: \("\(control)")
Option: \("\(option)")
Command: \("\(command)")
Function: \("\(function)")
"""
)
}

init() {
#if os(macOS)
let flags = NSEvent.modifierFlags

// I am intentionally excluding `.capsLock` because it's confusing since it works differently. It doesn't mean "pressed", it means "on".

self.shift = flags.contains(.shift)
self.control = flags.contains(.control)
self.option = flags.contains(.option)
self.command = flags.contains(.command)
self.function = flags.contains(.function)
#else
self.shift = false
self.control = false
self.option = false
self.command = false
self.function = false
#endif
}
}
Loading

0 comments on commit dde7d52

Please sign in to comment.