Skip to content

Commit

Permalink
Merge pull request #284 from wakatime/main
Browse files Browse the repository at this point in the history
Release v5.17.0
  • Loading branch information
alanhamlett authored Jul 29, 2024
2 parents eb8f1ce + 6bff9eb commit 24f9324
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 51 deletions.
27 changes: 23 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Contributing

To contribute to this project please carefully read this document.

## Setup

`macos-wakatime` is written in [Swift](https://www.swift.org/).
This project depends on the [xcodegen](https://github.com/yonaskolb/XcodeGen?tab=readme-ov-file#installing) command line tool.

```bash
git clone git@github.com:wakatime/macos-wakatime.git
cd macos-wakatime
xcodegen
```

Then open the `WakaTime.xcodeproj` in [Xcode 15.2](https://developer.apple.com/services-account/download?path=/Developer_Tools/Xcode_15.2/Xcode_15.2.xip).
Currently there’s a bug in new Swift compiler versions, so the largest Xcode version working with this app is 15.2.

## Branches

Expand All @@ -17,9 +24,21 @@ This project currently has two branches

Build with `Xcode` before creating any pull requests, or your PR won’t pass the automated checks.

## SwiftLint

To fix linter warning(s), run `swiftlint --fix`.

## Branching Stratgegy

Please follow our guideline for branch names [here](https://github.com/wakatime/semver-action#branch-names). Branches off the pattern won't be accepted.
We require specific branch name prefixes for PRs:

- `^major/.+` - `major`
- `^feature/.+` - `minor`
- `^bugfix/.+` - `patch`
- `^docs?/.+` - `build`
- `^misc/.+` - `build`

More info at [wakatime/semver-action](https://github.com/wakatime/semver-action#branch-names).

## Pull Requests

Expand Down
12 changes: 0 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,10 @@ If you don’t use any other WakaTime plugins, run `rm -r ~/.wakatime*`.

Before requesting support for a new app, first check the [list of supported apps][supported apps].

## SwiftLint

To fix linter warning(s), run `swiftlint --fix`.

## Contributing

Pull requests and issues are welcome!
See [Contributing][contributing] for more details.
The main thing to know is we require specific branch name prefixes for PRs:

- `^major/.+` - `major`
- `^feature/.+` - `minor`
- `^bugfix/.+` - `patch`
- `^docs?/.+` - `build`
- `^misc/.+` - `build`

Many thanks to all [contributors][authors]!

Made with :heart: by the WakaTime Team.
Expand Down
18 changes: 0 additions & 18 deletions WakaTime/Extensions/AXUIElementExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,24 +369,6 @@ extension AXUIElement {
"Value: \"\(ellipsedValue)\""
)
}

func extractPrefix(_ str: String?, separator: String, minCount: Int? = nil, fullTitle: Bool = false) -> String? {
guard let str = str else { return nil }

let parts = str.components(separatedBy: separator)

if let minCount = minCount, minCount > 0, parts.count < minCount {
return nil
}

if !parts.isEmpty && parts[0].trimmingCharacters(in: .whitespacesAndNewlines) != "" {
if fullTitle {
return str.trimmingCharacters(in: .whitespacesAndNewlines)
}
return parts[0].trimmingCharacters(in: .whitespacesAndNewlines)
}
return nil
}
}

enum AXUIElementNotification {
Expand Down
79 changes: 62 additions & 17 deletions WakaTime/Watchers/MonitoredApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum MonitoredApp: String, CaseIterable {
case wecom = "com.tencent.WeWorkMac"
case whatsapp = "net.whatsapp.WhatsApp"
case xcode = "com.apple.dt.Xcode"
case zed = "dev.zed.Zed"
case zoom = "us.zoom.xos"

init?(from bundleId: String) {
Expand Down Expand Up @@ -65,6 +66,7 @@ enum MonitoredApp: String, CaseIterable {
MonitoredApp.tableplus.rawValue,
MonitoredApp.xcode.rawValue,
MonitoredApp.zoom.rawValue,
MonitoredApp.zed.rawValue,
]

// list apps which we aren't yet able to track, so they're hidden from the Monitored Apps menu
Expand Down Expand Up @@ -118,13 +120,20 @@ enum MonitoredApp: String, CaseIterable {
fatalError("\(rawValue) should never use window title")
case .zoom:
return .meeting
case .zed:
return .coding
}
}

func project(for element: AXUIElement) -> String? {
// TODO: detect repo from GitHub Desktop Client if possible
guard let url = currentBrowserUrl(for: element) else { return nil }
return project(from: url)
switch self {
case .zed:
return extractSuffix(element.rawTitle, separator: "")
default:
guard let url = currentBrowserUrl(for: element) else { return nil }
return project(from: url)
}
}

private func project(from url: String) -> String? {
Expand Down Expand Up @@ -234,7 +243,7 @@ enum MonitoredApp: String, CaseIterable {
// ICTK2MacTextView
let textAreaElement = element.firstDescendantWhere { $0.role == kAXTextAreaRole }
if let value = textAreaElement?.value {
let title = element.extractPrefix(value, separator: "\n")
let title = extractPrefix(value, separator: "\n")
return title
}
return nil
Expand All @@ -256,58 +265,94 @@ enum MonitoredApp: String, CaseIterable {
fatalError("\(self.rawValue) should never use window title as entity")
case .figma:
guard
let title = element.extractPrefix(element.rawTitle, separator: ""),
let title = extractPrefix(element.rawTitle, separator: ""),
title != "Figma",
title != "Drafts"
else { return nil }
return title
case .firefox:
fatalError("\(self.rawValue) should never use window title as entity")
case .github:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .imessage:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .iterm2:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .linear:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .notes:
fatalError("\(self.rawValue) should never use window title as entity")
case .notion:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .postman:
guard
let title = element.extractPrefix(element.rawTitle, separator: " - ", fullTitle: true),
let title = extractPrefix(element.rawTitle, separator: " - ", fullTitle: true),
title != "Postman"
else { return nil }
return title
case .slack:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .safari:
fatalError("\(self.rawValue) should never use window title as entity")
case .safaripreview:
fatalError("\(self.rawValue) should never use window title as entity")
case .tableplus:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .terminal:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .warp:
guard
let title = element.extractPrefix(element.rawTitle, separator: " - "),
let title = extractPrefix(element.rawTitle, separator: " - "),
title != "Warp"
else { return nil }
return title
case .wecom:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .whatsapp:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .xcode:
fatalError("\(self.rawValue) should never use window title as entity")
case .zoom:
return element.extractPrefix(element.rawTitle, separator: " - ")
return extractPrefix(element.rawTitle, separator: " - ")
case .zed:
return extractPrefix(element.rawTitle, separator: "")
}
}

private func extractPrefix(_ str: String?, separator: String, minCount: Int? = nil, fullTitle: Bool = false) -> String? {
guard let str = str else { return nil }

let parts = str.components(separatedBy: separator)
guard !parts.isEmpty else { return nil }
guard let item = parts.first else { return nil }

if let minCount = minCount, minCount > 0, parts.count < minCount {
return nil
}

if item.trimmingCharacters(in: .whitespacesAndNewlines) != "" {
if fullTitle {
return str.trimmingCharacters(in: .whitespacesAndNewlines)
}
return item.trimmingCharacters(in: .whitespacesAndNewlines)
}
return nil
}

private func extractSuffix(_ str: String?, separator: String) -> String? {
guard let str = str else { return nil }

let parts = str.components(separatedBy: separator)
guard !parts.isEmpty else { return nil }
guard let item = parts.last else { return nil }

if item.trimmingCharacters(in: .whitespacesAndNewlines) != "" {
return item.trimmingCharacters(in: .whitespacesAndNewlines)
}

return nil
}

private func domainFromUrl(_ url: String) -> String? {
guard let host = URL(stringWithoutScheme: url)?.host else { return nil }
let domain = host.replacingOccurrences(of: "^www.", with: "", options: .regularExpression)
Expand Down

0 comments on commit 24f9324

Please sign in to comment.