Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ env:
XCODE_VERSION: '26.0'

jobs:
lint:
name: Lint
runs-on: macos-26
timeout-minutes: 5

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install SwiftLint
run: brew install swiftlint

- name: Run SwiftLint
run: swiftlint lint --reporter github-actions-logging

build:
name: Build
runs-on: macos-26
Expand Down
54 changes: 54 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
included:
- BetterCapture
- BetterCaptureTests

excluded:
- BetterCapture.xcodeproj

opt_in_rules:
- array_init
- closure_spacing
- collection_alignment
- contains_over_filter_count
- empty_collection_literal
- empty_string
- explicit_init
- first_where
- flatmap_over_map_reduce
- identical_operands
- joined_default_parameter
- last_where
- legacy_multiple
- let_var_whitespace
- lower_acl_than_parent
- modifier_order
- operator_usage_whitespace
- overridden_super_call
- prefer_self_type_over_type_of_self
- prohibited_super_call
- redundant_nil_coalescing
- sorted_first_last
- toggle_bool
- trailing_closure
- unneeded_parentheses_in_closure_argument
- weak_delegate
- yoda_condition

disabled_rules:
- todo

analyzer_rules:
- unused_import
- unused_declaration

line_length:
warning: 120
error: 200

type_body_length:
warning: 300
error: 500

file_length:
warning: 500
error: 800
22 changes: 11 additions & 11 deletions BetterCapture/View/AreaSelectionOverlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -566,19 +566,19 @@ final class AreaSelectionView: NSView {
// MARK: - Handle Calculation

private func allHandleRects() -> [ResizeHandle: CGRect] {
let r = selectionRect
let s = handleSize
let half = s / 2
let rect = selectionRect
let size = handleSize
let half = size / 2

return [
.topLeft: CGRect(x: r.minX - half, y: r.maxY - half, width: s, height: s),
.top: CGRect(x: r.midX - half, y: r.maxY - half, width: s, height: s),
.topRight: CGRect(x: r.maxX - half, y: r.maxY - half, width: s, height: s),
.left: CGRect(x: r.minX - half, y: r.midY - half, width: s, height: s),
.right: CGRect(x: r.maxX - half, y: r.midY - half, width: s, height: s),
.bottomLeft: CGRect(x: r.minX - half, y: r.minY - half, width: s, height: s),
.bottom: CGRect(x: r.midX - half, y: r.minY - half, width: s, height: s),
.bottomRight: CGRect(x: r.maxX - half, y: r.minY - half, width: s, height: s),
.topLeft: CGRect(x: rect.minX - half, y: rect.maxY - half, width: size, height: size),
.top: CGRect(x: rect.midX - half, y: rect.maxY - half, width: size, height: size),
.topRight: CGRect(x: rect.maxX - half, y: rect.maxY - half, width: size, height: size),
.left: CGRect(x: rect.minX - half, y: rect.midY - half, width: size, height: size),
.right: CGRect(x: rect.maxX - half, y: rect.midY - half, width: size, height: size),
.bottomLeft: CGRect(x: rect.minX - half, y: rect.minY - half, width: size, height: size),
.bottom: CGRect(x: rect.midX - half, y: rect.minY - half, width: size, height: size),
.bottomRight: CGRect(x: rect.maxX - half, y: rect.minY - half, width: size, height: size),
]
}

Expand Down
18 changes: 13 additions & 5 deletions BetterCapture/View/MenuBarSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,19 @@ struct MenuBarToggle: View {

// MARK: - Expandable Picker Row

/// Represents a single option in a `MenuBarExpandablePicker`
struct PickerOption<Value: Hashable & Equatable> {
let value: Value
let label: String
var isDisabled: Bool = false
var disabledMessage: String?
}

/// A menu bar style picker that expands inline to show options with hover effect
struct MenuBarExpandablePicker<SelectionValue: Hashable & Equatable>: View {
let name: String
@Binding var selection: SelectionValue
let options: [(value: SelectionValue, label: String, isDisabled: Bool, disabledMessage: String?)]
let options: [PickerOption<SelectionValue>]
@State private var isExpanded = false
@State private var isHovered = false

Expand All @@ -98,14 +106,14 @@ struct MenuBarExpandablePicker<SelectionValue: Hashable & Equatable>: View {
) {
self.name = name
self._selection = selection
self.options = options.map { ($0.value, $0.label, false, nil) }
self.options = options.map { PickerOption(value: $0.value, label: $0.label) }
}

/// Full initializer with disabled state support
init(
name: String,
selection: Binding<SelectionValue>,
optionsWithState: [(value: SelectionValue, label: String, isDisabled: Bool, disabledMessage: String?)]
optionsWithState: [PickerOption<SelectionValue>]
) {
self.name = name
self._selection = selection
Expand Down Expand Up @@ -450,7 +458,7 @@ struct VideoSettingsSection: View {
selection: $settings.videoCodec,
optionsWithState: VideoCodec.allCases.map { codec in
let isSupported = settings.containerFormat.supportedVideoCodecs.contains(codec)
return (
return PickerOption(
value: codec,
label: codec.rawValue,
isDisabled: !isSupported,
Expand Down Expand Up @@ -517,7 +525,7 @@ struct AudioSettingsSection: View {
selection: $settings.audioCodec,
optionsWithState: AudioCodec.allCases.map { codec in
let isSupported = settings.containerFormat.supportedAudioCodecs.contains(codec)
return (
return PickerOption(
value: codec,
label: codec.rawValue,
isDisabled: !isSupported,
Expand Down
Loading