Update Settings View and stuff

This commit is contained in:
Hariharan Mudaliar 2025-12-04 13:55:14 +05:30
commit 106f431682
3 changed files with 25 additions and 204 deletions

View file

@ -2033,6 +2033,7 @@
} }
}, },
"Add manually" : { "Add manually" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -6674,6 +6675,7 @@
} }
}, },
"Description" : { "Description" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -6790,6 +6792,7 @@
"isCommentAutoGenerated" : true "isCommentAutoGenerated" : true
}, },
"Disable" : { "Disable" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -8581,6 +8584,7 @@
"isCommentAutoGenerated" : true "isCommentAutoGenerated" : true
}, },
"Extensions" : { "Extensions" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -10537,6 +10541,7 @@
} }
}, },
"Installed extensions" : { "Installed extensions" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -13893,6 +13898,7 @@
} }
}, },
"No extension installed" : { "No extension installed" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -15721,6 +15727,7 @@
"isCommentAutoGenerated" : true "isCommentAutoGenerated" : true
}, },
"Restart" : { "Restart" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -15863,6 +15870,7 @@
} }
}, },
"Running" : { "Running" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {
@ -19150,6 +19158,7 @@
} }
}, },
"Uninstall" : { "Uninstall" : {
"extractionState" : "stale",
"localizations" : { "localizations" : {
"ar" : { "ar" : {
"stringUnit" : { "stringUnit" : {

View file

@ -34,7 +34,6 @@ private enum SettingsTab: String, CaseIterable, Identifiable {
case downloads case downloads
case shelf case shelf
case shortcuts case shortcuts
case extensions
case about case about
var id: String { rawValue } var id: String { rawValue }
@ -58,7 +57,6 @@ private enum SettingsTab: String, CaseIterable, Identifiable {
case .downloads: return "Downloads" case .downloads: return "Downloads"
case .shelf: return "Shelf" case .shelf: return "Shelf"
case .shortcuts: return "Shortcuts" case .shortcuts: return "Shortcuts"
case .extensions: return "Extensions"
case .about: return "About" case .about: return "About"
} }
} }
@ -82,7 +80,6 @@ private enum SettingsTab: String, CaseIterable, Identifiable {
case .downloads: return "square.and.arrow.down" case .downloads: return "square.and.arrow.down"
case .shelf: return "books.vertical" case .shelf: return "books.vertical"
case .shortcuts: return "keyboard" case .shortcuts: return "keyboard"
case .extensions: return "puzzlepiece.extension"
case .about: return "info.circle" case .about: return "info.circle"
} }
} }
@ -106,7 +103,6 @@ private enum SettingsTab: String, CaseIterable, Identifiable {
case .downloads: return .gray case .downloads: return .gray
case .shelf: return .brown case .shelf: return .brown
case .shortcuts: return .orange case .shortcuts: return .orange
case .extensions: return .blue
case .about: return .secondary case .about: return .secondary
} }
} }
@ -233,7 +229,6 @@ private struct SettingsForm<Content: View>: View {
} }
struct SettingsView: View { struct SettingsView: View {
@StateObject var extensionManager = DynamicIslandExtensionManager()
@State private var selectedTab: SettingsTab = .general @State private var selectedTab: SettingsTab = .general
@State private var searchText: String = "" @State private var searchText: String = ""
@StateObject private var highlightCoordinator = SettingsHighlightCoordinator() @StateObject private var highlightCoordinator = SettingsHighlightCoordinator()
@ -260,11 +255,13 @@ struct SettingsView: View {
.padding(.horizontal, 12) .padding(.horizontal, 12)
List(filteredTabs, selection: selectionBinding) { tab in List(filteredTabs, selection: selectionBinding) { tab in
let isComingSoon = tab == .downloads
NavigationLink(value: tab) { NavigationLink(value: tab) {
HStack(spacing: 10) { HStack(spacing: 10) {
sidebarIcon(for: tab) sidebarIcon(for: tab)
.opacity(isComingSoon ? 0.45 : 1)
Text(tab.title) Text(tab.title)
.foregroundStyle(Color.primary) .foregroundStyle(isComingSoon ? Color.secondary : Color.primary)
if tab == .osd { if tab == .osd {
Spacer() Spacer()
Text("ALPHA") Text("ALPHA")
@ -276,11 +273,15 @@ struct SettingsView: View {
Capsule() Capsule()
.fill(Color.orange) .fill(Color.orange)
) )
} else if isComingSoon {
Spacer()
comingSoonTag()
} }
} }
.padding(.vertical, 4) .padding(.vertical, 4)
} }
.tag(tab) .tag(tab)
.disabled(isComingSoon)
.listRowInsets(EdgeInsets(top: 4, leading: 12, bottom: 4, trailing: 10)) .listRowInsets(EdgeInsets(top: 4, leading: 12, bottom: 4, trailing: 10))
} }
.listStyle(SidebarListStyle()) .listStyle(SidebarListStyle())
@ -303,13 +304,12 @@ struct SettingsView: View {
.opacity(0) // Invisible, but reserves space for a consistent look between tabs .opacity(0) // Invisible, but reserves space for a consistent look between tabs
.disabled(true) .disabled(true)
} }
.environmentObject(extensionManager)
.environmentObject(highlightCoordinator) .environmentObject(highlightCoordinator)
.formStyle(.grouped) .formStyle(.grouped)
.frame(width: 700) .frame(width: 700)
.onChange(of: searchText) { _, newValue in .onChange(of: searchText) { _, newValue in
let matches = tabsMatchingSearch(newValue) let matches = tabsMatchingSearch(newValue)
guard let firstMatch = matches.first else { return } guard let firstMatch = matches.first(where: { $0 != .downloads }) else { return }
if !matches.contains(resolvedSelection) { if !matches.contains(resolvedSelection) {
selectedTab = firstMatch selectedTab = firstMatch
} }
@ -347,7 +347,10 @@ struct SettingsView: View {
private var selectionBinding: Binding<SettingsTab> { private var selectionBinding: Binding<SettingsTab> {
Binding( Binding(
get: { resolvedSelection }, get: { resolvedSelection },
set: { selectedTab = $0 } set: { newValue in
guard newValue != .downloads else { return }
selectedTab = newValue
}
) )
} }
@ -382,7 +385,6 @@ struct SettingsView: View {
.downloads, .downloads,
.shelf, .shelf,
.shortcuts, .shortcuts,
.extensions,
.about .about
] ]
@ -402,10 +404,11 @@ struct SettingsView: View {
} }
private var searchSuggestions: [SettingsSearchEntry] { private var searchSuggestions: [SettingsSearchEntry] {
Array(searchEntries(matching: searchText).prefix(8)) Array(searchEntries(matching: searchText).filter { $0.tab != .downloads }.prefix(8))
} }
private func handleSearchSuggestionSelection(_ suggestion: SettingsSearchEntry) { private func handleSearchSuggestionSelection(_ suggestion: SettingsSearchEntry) {
guard suggestion.tab != .downloads else { return }
highlightCoordinator.focus(on: suggestion) highlightCoordinator.focus(on: suggestion)
selectedTab = suggestion.tab selectedTab = suggestion.tab
} }
@ -583,12 +586,6 @@ struct SettingsView: View {
SettingsSearchEntry(tab: .battery, title: "Show power status notifications", keywords: ["notifications", "power"], highlightID: SettingsTab.battery.highlightID(for: "Show power status notifications")), SettingsSearchEntry(tab: .battery, title: "Show power status notifications", keywords: ["notifications", "power"], highlightID: SettingsTab.battery.highlightID(for: "Show power status notifications")),
SettingsSearchEntry(tab: .battery, title: "Show power status icons", keywords: ["power icons", "charging icon"], highlightID: SettingsTab.battery.highlightID(for: "Show power status icons")), SettingsSearchEntry(tab: .battery, title: "Show power status icons", keywords: ["power icons", "charging icon"], highlightID: SettingsTab.battery.highlightID(for: "Show power status icons")),
// Downloads
SettingsSearchEntry(tab: .downloads, title: "Show download progress", keywords: ["downloads", "progress"], highlightID: SettingsTab.downloads.highlightID(for: "Show download progress")),
SettingsSearchEntry(tab: .downloads, title: "Enable Safari Downloads", keywords: ["safari", "browser"], highlightID: SettingsTab.downloads.highlightID(for: "Enable Safari Downloads")),
SettingsSearchEntry(tab: .downloads, title: "Download indicator style", keywords: ["indicator", "style"], highlightID: SettingsTab.downloads.highlightID(for: "Download indicator style")),
SettingsSearchEntry(tab: .downloads, title: "Download icon style", keywords: ["icon", "style"], highlightID: SettingsTab.downloads.highlightID(for: "Download icon style")),
// HUDs // HUDs
SettingsSearchEntry(tab: .hud, title: "Show Bluetooth device connections", keywords: ["bluetooth", "hud"], highlightID: SettingsTab.hud.highlightID(for: "Show Bluetooth device connections")), SettingsSearchEntry(tab: .hud, title: "Show Bluetooth device connections", keywords: ["bluetooth", "hud"], highlightID: SettingsTab.hud.highlightID(for: "Show Bluetooth device connections")),
SettingsSearchEntry(tab: .hud, title: "Use circular battery indicator", keywords: ["battery", "circular"], highlightID: SettingsTab.hud.highlightID(for: "Use circular battery indicator")), SettingsSearchEntry(tab: .hud, title: "Use circular battery indicator", keywords: ["battery", "circular"], highlightID: SettingsTab.hud.highlightID(for: "Use circular battery indicator")),
@ -714,8 +711,6 @@ struct SettingsView: View {
switch tab { switch tab {
case .timer, .stats, .clipboard, .screenAssistant, .colorPicker, .shelf: case .timer, .stats, .clipboard, .screenAssistant, .colorPicker, .shelf:
return !enableMinimalisticUI return !enableMinimalisticUI
case .downloads:
return extensionManager.installedExtensions.contains { $0.bundleIdentifier == downloadManagerExtension }
default: default:
return true return true
} }
@ -810,10 +805,6 @@ struct SettingsView: View {
SettingsForm(tab: .shortcuts) { SettingsForm(tab: .shortcuts) {
Shortcuts() Shortcuts()
} }
case .extensions:
SettingsForm(tab: .extensions) {
Extensions()
}
case .about: case .about:
if let controller = updaterController { if let controller = updaterController {
SettingsForm(tab: .about) { SettingsForm(tab: .about) {
@ -1150,6 +1141,8 @@ struct Downloads: View {
} }
} }
.navigationTitle("Downloads") .navigationTitle("Downloads")
.disabled(true)
.opacity(0.6)
} }
} }
@ -1928,125 +1921,6 @@ struct Shelf: View {
} }
} }
struct Extensions: View {
@EnvironmentObject var extensionManager: DynamicIslandExtensionManager
@State private var effectTrigger: Bool = false
var body: some View {
Form {
//warningBadge("We don't support extensions yet") // Uhhhh You do? <><><> Oori.S
Section {
List {
ForEach(extensionManager.installedExtensions.indices, id: \.self) { index in
let item = extensionManager.installedExtensions[index]
HStack {
AppIcon(for: item.bundleIdentifier)
.resizable()
.frame(width: 24, height: 24)
Text(item.name)
ListItemPopover {
Text("Description")
}
Spacer(minLength: 0)
HStack(spacing: 6) {
Circle()
.frame(width: 6, height: 6)
.foregroundColor(isExtensionRunning(item.bundleIdentifier) ? .green : item.status == .disabled ? .gray : .red)
.conditionalModifier(isExtensionRunning(item.bundleIdentifier)) { view in
view
.shadow(color: .green, radius: 3)
}
Text(isExtensionRunning(item.bundleIdentifier) ? "Running" : item.status == .disabled ? "Disabled" : "Stopped")
.contentTransition(.numericText())
.foregroundStyle(.secondary)
.font(.footnote)
}
.frame(width: 60, alignment: .leading)
Menu(content: {
Button("Restart") {
let ws = NSWorkspace.shared
if let ext = ws.runningApplications.first(where: { $0.bundleIdentifier == item.bundleIdentifier }) {
ext.terminate()
}
if let appURL = ws.urlForApplication(withBundleIdentifier: item.bundleIdentifier) {
ws.openApplication(at: appURL, configuration: .init(), completionHandler: nil)
}
}
.keyboardShortcut("R", modifiers: .command)
Button("Disable") {
if let ext = NSWorkspace.shared.runningApplications.first(where: { $0.bundleIdentifier == item.bundleIdentifier }) {
ext.terminate()
}
extensionManager.installedExtensions[index].status = .disabled
}
.keyboardShortcut("D", modifiers: .command)
Divider()
Button("Uninstall", role: .destructive) {
//
}
}, label: {
Image(systemName: "ellipsis.circle")
.foregroundStyle(.secondary)
})
.controlSize(.regular)
}
.buttonStyle(PlainButtonStyle())
.padding(.vertical, 5)
}
}
.frame(minHeight: 120)
.actionBar {
Button {} label: {
HStack(spacing: 3) {
Image(systemName: "plus")
Text("Add manually")
}
.foregroundStyle(.secondary)
}
.disabled(true)
Spacer()
Button {
withAnimation(.linear(duration: 1)) {
effectTrigger.toggle()
} completion: {
effectTrigger.toggle()
}
extensionManager.checkIfExtensionsAreInstalled()
} label: {
HStack(spacing: 3) {
Image(systemName: "arrow.triangle.2.circlepath")
.rotationEffect(effectTrigger ? .degrees(360) : .zero)
}
.foregroundStyle(.secondary)
}
}
.controlSize(.small)
.buttonStyle(PlainButtonStyle())
.overlay {
if extensionManager.installedExtensions.isEmpty {
Text("No extension installed")
.foregroundStyle(Color(.secondaryLabelColor))
.padding(.bottom, 22)
}
}
} header: {
HStack(spacing: 0) {
Text("Installed extensions")
if !extensionManager.installedExtensions.isEmpty {
Text(" – \(extensionManager.installedExtensions.count)")
.foregroundStyle(.secondary)
}
}
}
}
.navigationTitle("Extensions")
// TipsView()
// .padding(.horizontal, 19)
}
}
struct LiveActivitiesSettings: View { struct LiveActivitiesSettings: View {
@ObservedObject var coordinator = DynamicIslandViewCoordinator.shared @ObservedObject var coordinator = DynamicIslandViewCoordinator.shared
@ObservedObject var recordingManager = ScreenRecordingManager.shared @ObservedObject var recordingManager = ScreenRecordingManager.shared

View file

@ -1,62 +0,0 @@
//
// DynamicIslandExtensionManager.swift
// DynamicIsland
//
// Created by Harsh Vardhan Goswami on 04/08/24.
// DynamicIslandExtensionManager.swift
// DynamicIsland
//
// Created by Harsh Vardhan Goswami on 07/09/24.
//
import Foundation
import SwiftUI
var clipboardExtension: String = "dynamicisland.TheDynamicClipboard"
var hudExtension: String = "dynamicisland.TheDynamicHUDs"
var downloadManagerExtension: String = "dynamicisland.TheDynamicDownloadManager"
struct Extension: Identifiable, Hashable {
var id = UUID()
var name: String
var bundleIdentifier: String
var status: StatusModel = .enabled
}
enum StatusModel {
case disabled
case enabled
}
class DynamicIslandExtensionManager: ObservableObject {
@Published var installedExtensions: [Extension] = [] {
didSet {
// Only log when there's an actual change in content, not just initialization
if oldValue != installedExtensions {
print("📦 Extensions installed: \(installedExtensions.map { $0.name })")
}
}
}
var extensions = [
clipboardExtension,
hudExtension
]
init() {
checkIfExtensionsAreInstalled()
DistributedNotificationCenter.default().addObserver(self, selector: #selector(checkIfExtensionsAreInstalled), name: NSNotification.Name("NSWorkspaceDidLaunchApplicationNotification"), object: nil)
}
@objc func checkIfExtensionsAreInstalled() {
installedExtensions = []
for extensionName in extensions {
if NSWorkspace.shared.urlForApplication(withBundleIdentifier: extensionName) != nil {
let ext = Extension(name: extensionName.components(separatedBy: ".").last ?? extensionName, bundleIdentifier: extensionName)
installedExtensions.append(ext)
}
}
}
}