Skip to content

Commit

Permalink
Merge pull request #297 from wakatime/feature/more-supported-apps
Browse files Browse the repository at this point in the history
Add support for more apps
  • Loading branch information
alanhamlett authored Aug 22, 2024
2 parents 3e73015 + 80a8876 commit cd523c1
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 4 deletions.
104 changes: 101 additions & 3 deletions WakaTime/Helpers/MonitoringManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,29 @@ class MonitoringManager {
}
}

// swiftlint:disable cyclomatic_complexity
static func title(for app: NSRunningApplication, _ element: AXUIElement) -> String? {
guard let monitoredApp = app.monitoredApp else {
return extractPrefix(element.rawTitle, separator: "")
return extractPrefix(element.rawTitle)
}

switch monitoredApp {
case .adobeaftereffect:
return extractPrefix(element.rawTitle)
case .adobebridge:
return extractPrefix(element.rawTitle)
case .adobeillustrator:
return extractPrefix(element.rawTitle)
case .adobemediaencoder:
return extractPrefix(element.rawTitle)
case .adobephotoshop:
return extractPrefix(element.rawTitle)
case .adobepremierepro:
return extractPrefix(element.rawTitle)
case .arcbrowser:
fatalError("\(monitoredApp.rawValue) should never use window title as entity")
case .beeper:
return extractPrefix(element.rawTitle)
case .brave:
fatalError("\(monitoredApp.rawValue) should never use window title as entity")
case .canva:
Expand All @@ -180,6 +195,8 @@ class MonitoringManager {
return extractPrefix(element.rawTitle, separator: " - ")
case .linear:
return extractPrefix(element.rawTitle, separator: " - ")
case .miro:
return extractSuffix(element.rawTitle)
case .notes:
fatalError("\(monitoredApp.rawValue) should never use window title as entity")
case .notion:
Expand All @@ -190,6 +207,8 @@ class MonitoringManager {
title != "Postman"
else { return nil }
return title
case .rocketchat:
return extractPrefix(element.rawTitle)
case .slack:
return extractPrefix(element.rawTitle, separator: " - ")
case .safari:
Expand Down Expand Up @@ -223,8 +242,22 @@ class MonitoringManager {
guard let monitoredApp = app.monitoredApp else { return .coding }

switch monitoredApp {
case .adobeaftereffect:
return .designing
case .adobebridge:
return .designing
case .adobeillustrator:
return .designing
case .adobemediaencoder:
return .designing
case .adobephotoshop:
return .designing
case .adobepremierepro:
return .designing
case .arcbrowser:
return .browsing
case .beeper:
return .communicating
case .brave:
return .browsing
case .canva:
Expand All @@ -243,12 +276,16 @@ class MonitoringManager {
return .coding
case .linear:
return .planning
case .miro:
return .planning
case .notes:
return .writingdocs
case .notion:
return .writingdocs
case .postman:
return .debugging
case .rocketchat:
return .communicating
case .slack:
return .communicating
case .safari:
Expand All @@ -273,6 +310,7 @@ class MonitoringManager {
return .coding
}
}
// swiftlint:enable cyclomatic_complexity

static func project(for app: NSRunningApplication, _ element: AXUIElement) -> String? {
guard let monitoredApp = app.monitoredApp else {
Expand Down Expand Up @@ -367,9 +405,13 @@ class MonitoringManager {
return address
}

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

guard let separator = separator else {
return getFirstPrefixMatch(str)
}

let parts = str.components(separatedBy: separator)
guard !parts.isEmpty else { return nil }
guard let item = parts.first else { return nil }
Expand All @@ -387,9 +429,13 @@ class MonitoringManager {
return nil
}

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

guard let separator = separator else {
return getFirstSuffixMatch(str)
}

var parts = str.components(separatedBy: separator)
guard !parts.isEmpty else { return nil }
guard parts.count > 1 else { return nil }
Expand All @@ -416,6 +462,58 @@ class MonitoringManager {
guard let port = URL(stringWithoutScheme: url)?.port else { return domain }
return "\(domain):\(port)"
}

static let separators = [
"-",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
]

static func getFirstPrefixMatch(_ str: String) -> String {
guard !str.isEmpty else { return str.trimmingCharacters(in: .whitespacesAndNewlines) }

for separator in separators {
let parts = str.components(separatedBy: separator)
guard parts.count > 1 else { continue }
guard let item = parts.first else { continue }

let trimmed = item.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { continue }

return trimmed
}

return str.trimmingCharacters(in: .whitespacesAndNewlines)
}

static func getFirstSuffixMatch(_ str: String) -> String {
guard !str.isEmpty else { return str.trimmingCharacters(in: .whitespacesAndNewlines) }

for separator in separators {
let parts = str.components(separatedBy: separator)
guard parts.count > 1 else { continue }
guard let item = parts.last else { continue }

let trimmed = item.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { continue }

return trimmed
}

return str.trimmingCharacters(in: .whitespacesAndNewlines)
}
}

struct HeartbeatData {
Expand Down
2 changes: 1 addition & 1 deletion WakaTime/Views/MonitoredAppsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class MonitoredAppsView: NSView, NSOutlineViewDataSource, NSOutlineViewDelegate
let bundleId = id.replacingOccurrences(of: "-setapp$", with: "", options: .regularExpression)

guard
bundleId != "com.apple.finder",
!MonitoredApp.unsupportedAppIds.contains(where: { $0 == bundleId }),
!MonitoredApp.allBundleIds.contains(where: { $0 == bundleId })
else { continue }

Expand Down
15 changes: 15 additions & 0 deletions WakaTime/Watchers/MonitoredApp.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import AppKit

enum MonitoredApp: String, CaseIterable {
case adobeaftereffect = "com.adobe.AfterEffects"
case adobebridge = "com.adobe.bridge14"
case adobeillustrator = "com.adobe.illustrator"
case adobemediaencoder = "com.adobe.ame.application.24"
case adobephotoshop = "com.adobe.Photoshop"
case adobepremierepro = "com.adobe.PremierePro.24"
case arcbrowser = "company.thebrowser.Browser"
case beeper = "im.beeper"
case brave = "com.brave.Browser"
case canva = "com.canva.CanvaDesktop"
case chrome = "com.google.Chrome"
Expand All @@ -11,9 +18,11 @@ enum MonitoredApp: String, CaseIterable {
case imessage = "com.apple.MobileSMS"
case iterm2 = "com.googlecode.iterm2"
case linear = "com.linear"
case miro = "com.electron.realtimeboard"
case notes = "com.apple.Notes"
case notion = "notion.id"
case postman = "com.postmanlabs.mac"
case rocketchat = "chat.rocket"
case safari = "com.apple.Safari"
case safaripreview = "com.apple.SafariTechnologyPreview"
case slack = "com.tinyspeck.slackmacgap"
Expand All @@ -36,6 +45,12 @@ enum MonitoredApp: String, CaseIterable {
}
}

// Hide these from the Monitored Apps menu
static let unsupportedAppIds = [
"macos-wakatime.WakaTime",
"com.apple.finder",
]

static var allBundleIds: [String] {
MonitoredApp.allCases.map { $0.rawValue }
}
Expand Down

0 comments on commit cd523c1

Please sign in to comment.