From fd5042390dd56dbfdb7ab810785b4e65c7e25721 Mon Sep 17 00:00:00 2001 From: Hariharan Mudaliar Date: Sun, 5 Oct 2025 22:25:43 +0530 Subject: [PATCH] Onboarding Enhancement --- DynamicIsland/DynamicIslandApp.swift | 3 +- DynamicIsland/Localizable.xcstrings | 20 +- .../Onboarding/OnboardingFinishView.swift | 13 + .../Onboarding/OnboardingView.swift | 13 + .../Onboarding/ProfileSelectionView.swift | 260 ++++++++++++++ .../components/Onboarding/WelcomeView.swift | 13 + DynamicIsland/models/Constants.swift | 1 + ONBOARDING_ENHANCEMENT.md | 184 ++++++++++ ReadMe.md | 317 +++++++++++++++--- reset_app_defaults.sh | 80 +++++ 10 files changed, 853 insertions(+), 51 deletions(-) create mode 100644 DynamicIsland/components/Onboarding/ProfileSelectionView.swift create mode 100644 ONBOARDING_ENHANCEMENT.md create mode 100755 reset_app_defaults.sh diff --git a/DynamicIsland/DynamicIslandApp.swift b/DynamicIsland/DynamicIslandApp.swift index 03134c9..7a7a8c2 100644 --- a/DynamicIsland/DynamicIslandApp.swift +++ b/DynamicIsland/DynamicIslandApp.swift @@ -447,7 +447,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { if change.newValue == true && Defaults[.sneakPeekStyles] != .standard { Defaults[.sneakPeekStyles] = .standard } - self?.debouncedUpdateWindowSize() + // Update window size IMMEDIATELY (no debouncing) to prevent position shift + self?.updateWindowSizeIfNeeded() }.store(in: &cancellables) // Observe screen recording settings changes diff --git a/DynamicIsland/Localizable.xcstrings b/DynamicIsland/Localizable.xcstrings index 0e6a6b9..11bcc07 100644 --- a/DynamicIsland/Localizable.xcstrings +++ b/DynamicIsland/Localizable.xcstrings @@ -312,6 +312,10 @@ }, "Choose your preferred AI model and configuration" : { + }, + "Choose Your Profile" : { + "comment" : "A title displayed above the list of profile selection options.", + "isCommentAutoGenerated" : true }, "Circle" : { @@ -819,9 +823,6 @@ } } } - }, - "Media change with horizontal gestures" : { - }, "Media controls" : { @@ -1114,6 +1115,10 @@ "comment" : "The title of the privacy and security settings screen.", "isCommentAutoGenerated" : true }, + "Privacy Policy" : { + "comment" : "A link to the privacy policy.", + "isCommentAutoGenerated" : true + }, "Progress bar" : { "localizations" : { "en" : { @@ -1264,6 +1269,10 @@ }, "Select Calendars" : { + }, + "Select one or more profiles to customize your experience" : { + "comment" : "A description below the header that instructs users to select one or more profiles to customize their experience.", + "isCommentAutoGenerated" : true }, "Select the music source you want to use. You can change this later in the app settings." : { @@ -1519,8 +1528,9 @@ "Try different search terms" : { }, - "Two-finger swipe up on notch to close, two-finger swipe down on notch to open when **Open notch on hover** option is disabled" : { - + "Two-finger swipe up on notch to close, two-finger swipe down on notch to open when **Open notch on hover** option is disabled. Two-finger horizontal swipes to control media playback" : { + "comment" : "A footer text describing the gesture controls in the settings view.", + "isCommentAutoGenerated" : true }, "UI Mode" : { diff --git a/DynamicIsland/components/Onboarding/OnboardingFinishView.swift b/DynamicIsland/components/Onboarding/OnboardingFinishView.swift index 776e3d2..fd7bdf9 100644 --- a/DynamicIsland/components/Onboarding/OnboardingFinishView.swift +++ b/DynamicIsland/components/Onboarding/OnboardingFinishView.swift @@ -45,6 +45,19 @@ struct OnboardingFinishView: View { .buttonStyle(.borderedProminent) .controlSize(.large) .keyboardShortcut(.defaultAction) + + // Privacy Policy Link + Button(action: { + if let url = URL(string: "https://ebullioscopic.github.io/DynamicIsland/privacy-policy") { + NSWorkspace.shared.open(url) + } + }) { + Text("Privacy Policy") + .font(.caption) + .foregroundColor(.secondary) + } + .buttonStyle(.plain) + .padding(.top, 4) } .padding(24) } diff --git a/DynamicIsland/components/Onboarding/OnboardingView.swift b/DynamicIsland/components/Onboarding/OnboardingView.swift index d652011..a0252f3 100644 --- a/DynamicIsland/components/Onboarding/OnboardingView.swift +++ b/DynamicIsland/components/Onboarding/OnboardingView.swift @@ -13,6 +13,7 @@ enum OnboardingStep { case cameraPermission case calendarPermission case musicPermission + case profileSelection case finished } @@ -81,6 +82,17 @@ struct OnboardingView: View { case .musicPermission: MusicControllerSelectionView( onContinue: { + withAnimation(.easeInOut(duration: 0.6)) { + step = .profileSelection + } + } + ) + .transition(.opacity) + + case .profileSelection: + ProfileSelectionView( + onContinue: { profiles in + applyProfileSettings(profiles) withAnimation(.easeInOut(duration: 0.6)) { step = .finished } @@ -105,3 +117,4 @@ struct OnboardingView: View { await calendarService.requestAccess() } } + diff --git a/DynamicIsland/components/Onboarding/ProfileSelectionView.swift b/DynamicIsland/components/Onboarding/ProfileSelectionView.swift new file mode 100644 index 0000000..5663a94 --- /dev/null +++ b/DynamicIsland/components/Onboarding/ProfileSelectionView.swift @@ -0,0 +1,260 @@ +// +// ProfileSelectionView.swift +// DynamicIsland +// +// Created on 2025-10-05. +// + +import SwiftUI +import Defaults + +struct UserProfile: Identifiable, Hashable { + let id: String + let name: String + let icon: String + let description: String + let gradient: [Color] +} + +struct ProfileSelectionView: View { + @State private var selectedProfiles: Set = [] + let onContinue: (Set) -> Void + + let profiles: [UserProfile] = [ + UserProfile( + id: "developer", + name: "Developer", + icon: "terminal.fill", + description: "Code and debug with color picker, stats monitoring, and screen assistant.", + gradient: [Color.blue, Color.purple] + ), + UserProfile( + id: "designer", + name: "Designer", + icon: "paintbrush.fill", + description: "Create and design with color picker, mirror, and visual effects.", + gradient: [Color.pink, Color.orange] + ), + UserProfile( + id: "lightuse", + name: "Light Use", + icon: "sparkles", + description: "Simple and minimal interface with just the essentials for everyday tasks.", + gradient: [Color.green, Color.mint] + ), + UserProfile( + id: "student", + name: "Student", + icon: "book.fill", + description: "Stay organized with calendar, timer, and battery monitoring.", + gradient: [Color.indigo, Color.cyan] + ) + ] + + var body: some View { + VStack(spacing: 24) { + // Header + VStack(spacing: 8) { + Image(systemName: "person.3.fill") + .font(.system(size: 50)) + .foregroundStyle(.linearGradient(colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing)) + .padding(.bottom, 8) + + Text("Choose Your Profile") + .font(.largeTitle) + .fontWeight(.bold) + + Text("Select one or more profiles to customize your experience") + .font(.body) + .foregroundColor(.secondary) + .multilineTextAlignment(.center) + .padding(.horizontal, 40) + } + .padding(.top, 20) + + // Profile Grid + LazyVGrid(columns: [GridItem(.flexible()), GridItem(.flexible())], spacing: 16) { + ForEach(profiles) { profile in + ProfileCard( + profile: profile, + isSelected: selectedProfiles.contains(profile.id), + onTap: { + toggleProfile(profile.id) + } + ) + } + } + .padding(.horizontal, 24) + + Spacer() + + // Continue Button + Button(action: { + if !selectedProfiles.isEmpty { + onContinue(selectedProfiles) + } + }) { + Text("Continue") + .frame(maxWidth: .infinity) + .padding(.vertical, 12) + } + .buttonStyle(.borderedProminent) + .disabled(selectedProfiles.isEmpty) + .padding(.horizontal, 24) + .padding(.bottom, 24) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background( + VisualEffectView(material: .underWindowBackground, blendingMode: .behindWindow) + .ignoresSafeArea() + ) + } + + private func toggleProfile(_ profileId: String) { + withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) { + if selectedProfiles.contains(profileId) { + selectedProfiles.remove(profileId) + } else { + selectedProfiles.insert(profileId) + } + } + } +} + +struct ProfileCard: View { + let profile: UserProfile + let isSelected: Bool + let onTap: () -> Void + + @State private var isHovering = false + + var body: some View { + Button(action: onTap) { + VStack(alignment: .leading, spacing: 12) { + HStack { + Image(systemName: profile.icon) + .font(.system(size: 28)) + .foregroundStyle(.linearGradient(colors: profile.gradient, startPoint: .topLeading, endPoint: .bottomTrailing)) + + Spacer() + + if isSelected { + Image(systemName: "checkmark.circle.fill") + .font(.system(size: 22)) + .foregroundStyle(.linearGradient(colors: profile.gradient, startPoint: .topLeading, endPoint: .bottomTrailing)) + .transition(.scale.combined(with: .opacity)) + } + } + + Text(profile.name) + .font(.headline) + .fontWeight(.semibold) + .foregroundColor(.primary) + + Text(profile.description) + .font(.caption) + .foregroundColor(.secondary) + .lineLimit(3) + .fixedSize(horizontal: false, vertical: true) + } + .padding(16) + .frame(height: 160) + .background( + RoundedRectangle(cornerRadius: 16) + .fill(isSelected ? + LinearGradient(colors: profile.gradient.map { $0.opacity(0.15) }, startPoint: .topLeading, endPoint: .bottomTrailing) : + LinearGradient(colors: [Color.gray.opacity(0.1)], startPoint: .topLeading, endPoint: .bottomTrailing) + ) + ) + .overlay( + RoundedRectangle(cornerRadius: 16) + .strokeBorder( + isSelected ? + LinearGradient(colors: profile.gradient, startPoint: .topLeading, endPoint: .bottomTrailing) : + LinearGradient(colors: [Color.clear], startPoint: .topLeading, endPoint: .bottomTrailing), + lineWidth: isSelected ? 2 : 0 + ) + ) + .scaleEffect(isHovering ? 1.02 : 1.0) + .shadow(color: isSelected ? profile.gradient[0].opacity(0.3) : .clear, radius: 8, x: 0, y: 4) + } + .buttonStyle(.plain) + .onHover { hovering in + withAnimation(.easeInOut(duration: 0.2)) { + isHovering = hovering + } + } + } +} + +// MARK: - Profile Settings Configuration + +func applyProfileSettings(_ profiles: Set) { + // Clipboard is ALWAYS enabled (per user request) + Defaults[.enableClipboardManager] = true + + // Developer Profile Settings + let isDeveloper = profiles.contains("developer") + if isDeveloper { + Defaults[.enableColorPickerFeature] = true + Defaults[.enableStatsFeature] = true + Defaults[.enableTimerFeature] = true + Defaults[.enableScreenAssistant] = true + Defaults[.showMirror] = false + Defaults[.enableMinimalisticUI] = false + } + + // Designer Profile Settings + let isDesigner = profiles.contains("designer") + if isDesigner { + Defaults[.enableColorPickerFeature] = true + Defaults[.showMirror] = true + Defaults[.lightingEffect] = true + Defaults[.inlineHUD] = true + Defaults[.enableStatsFeature] = false + Defaults[.enableTimerFeature] = false + Defaults[.enableMinimalisticUI] = false + Defaults[.enableScreenAssistant] = false + } + + // Light Use Profile Settings + let isLightUse = profiles.contains("lightuse") + if isLightUse { + Defaults[.enableMinimalisticUI] = true + Defaults[.enableColorPickerFeature] = false + Defaults[.showMirror] = false + Defaults[.enableStatsFeature] = false + Defaults[.enableTimerFeature] = true + Defaults[.inlineHUD] = false + Defaults[.enableScreenAssistant] = false + } + + // Student Profile Settings + let isStudent = profiles.contains("student") + if isStudent { + Defaults[.enableTimerFeature] = true + Defaults[.showCalendar] = true + Defaults[.enableColorPickerFeature] = false + Defaults[.showMirror] = false + Defaults[.enableStatsFeature] = false + Defaults[.enableMinimalisticUI] = false + Defaults[.enableScreenAssistant] = false + } + + // If Light Use is NOT selected but others are, ensure minimalistic is OFF + if !isLightUse && !profiles.isEmpty { + Defaults[.enableMinimalisticUI] = false + } + + // Common settings for all profiles + Defaults[.menubarIcon] = true + Defaults[.enableHaptics] = true + + print("โœ… Applied profile settings for: \(profiles.joined(separator: ", "))") +} + +#Preview { + ProfileSelectionView(onContinue: { profiles in + print("Selected profiles: \(profiles)") + }) +} diff --git a/DynamicIsland/components/Onboarding/WelcomeView.swift b/DynamicIsland/components/Onboarding/WelcomeView.swift index 634ee83..d67d00c 100644 --- a/DynamicIsland/components/Onboarding/WelcomeView.swift +++ b/DynamicIsland/components/Onboarding/WelcomeView.swift @@ -58,6 +58,19 @@ struct WelcomeView: View { .padding(.vertical, 6) } .buttonStyle(BorderedProminentButtonStyle()) + + // Privacy Policy Link + Button(action: { + if let url = URL(string: "https://ebullioscopic.github.io/DynamicIsland/privacy-policy") { + NSWorkspace.shared.open(url) + } + }) { + Text("Privacy Policy") + .font(.caption) + .foregroundColor(.secondary) + } + .buttonStyle(.plain) + .padding(.top, 8) } .padding(.top) } diff --git a/DynamicIsland/models/Constants.swift b/DynamicIsland/models/Constants.swift index 87ae850..3f5010a 100644 --- a/DynamicIsland/models/Constants.swift +++ b/DynamicIsland/models/Constants.swift @@ -248,6 +248,7 @@ extension Defaults.Keys { // MARK: Gestures static let enableGestures = Key("enableGestures", default: true) static let closeGestureEnabled = Key("closeGestureEnabled", default: true) + static let enableMediaGestures = Key("enableMediaGestures", default: true) static let gestureSensitivity = Key("gestureSensitivity", default: 200.0) // MARK: Media playback diff --git a/ONBOARDING_ENHANCEMENT.md b/ONBOARDING_ENHANCEMENT.md new file mode 100644 index 0000000..591aa26 --- /dev/null +++ b/ONBOARDING_ENHANCEMENT.md @@ -0,0 +1,184 @@ +# Onboarding Enhancement - User Profile Selection + +## Overview +Added comprehensive user profile selection to the onboarding flow, allowing users to customize their DynamicIsland experience based on their work type. + +## What Was Changed + +### 1. New Files Created + +#### `ProfileSelectionView.swift` +- **Location**: `DynamicIsland/components/Onboarding/ProfileSelectionView.swift` +- **Features**: + - Multi-select card interface with 4 user profiles + - Beautiful gradient cards with hover effects + - Profile-specific settings configuration + - At least one profile must be selected to continue + +#### `reset_app_defaults.sh` +- **Location**: Root directory +- **Purpose**: Reset app to factory defaults for testing +- **Usage**: `./reset_app_defaults.sh` + +### 2. Modified Files + +#### `OnboardingView.swift` +- Added `profileSelection` step to `OnboardingStep` enum +- Integrated `ProfileSelectionView` before finish screen +- Added profile settings application logic + +#### `WelcomeView.swift` +- Added "Privacy Policy" link button +- Links to: `https://ebullioscopic.github.io/DynamicIsland/privacy-policy` + +#### `OnboardingFinishView.swift` +- Added "Privacy Policy" link button + +## User Profiles + +### ๐Ÿ”ง Developer +**For**: Developers and programmers +**Enables**: +- โœ… Color Picker +- โœ… Stats Monitoring +- โœ… Timer +- โœ… Screen Assistant +- โŒ Mirror (disabled) +- โŒ Minimalistic UI (disabled) + +**Note**: Clipboard is always enabled for all profiles + +### ๐ŸŽจ Designer +**For**: Graphic designers and creatives +**Enables**: +- โœ… Color Picker +- โœ… Mirror +- โœ… Lighting Effects +- โœ… Inline HUD +- โŒ Stats (disabled) +- โŒ Timer (disabled) +- โŒ Screen Assistant (disabled) +- โŒ Minimalistic UI (disabled) + +**Note**: Clipboard is always enabled for all profiles + +### โœจ Light Use +**For**: Minimal everyday use +**Enables**: +- โœ… Minimalistic UI (simplified interface) +- โœ… Timer +- โŒ All other advanced features disabled + +**Note**: Clipboard is always enabled for all profiles + +### ๐Ÿ“š Student +**For**: Students and learners +**Enables**: +- โœ… Timer +- โœ… Calendar +- โœ… Battery Monitoring +- โŒ Color Picker (disabled) +- โŒ Mirror (disabled) +- โŒ Stats (disabled) +- โŒ Screen Assistant (disabled) +- โŒ Minimalistic UI (disabled) + +**Note**: Clipboard is always enabled for all profiles + +## Multi-Select Logic + +- Users can select **one or more** profiles +- Settings use **OR logic**: If ANY selected profile enables a feature, it's enabled +- **Exception**: Minimalistic UI is only enabled if "Light Use" is selected AND no other profiles are selected +- Common settings (menubar icon, haptics) enabled for all profiles + +## Privacy Policy Integration + +- Links added to Welcome and Finish screens +- Opens in default browser +- URL: `https://ebullioscopic.github.io/DynamicIsland/privacy-policy` +- **Note**: You need to create this page on GitHub Pages + +## Reset Script Usage + +To test the onboarding flow fresh: + +```bash +# Run the reset script +./reset_app_defaults.sh + +# The script will: +# 1. Kill the app if running +# 2. Clear UserDefaults +# 3. Remove Application Support files +# 4. Remove caches +# 5. Remove preference files +# 6. Remove saved state + +# Then launch the app +open -a DynamicIsland +``` + +## Updated Onboarding Flow + +**New Flow**: +1. Welcome Screen (with Privacy Policy link) +2. Camera Permission +3. Calendar Permission +4. Music Controller Selection +5. **โœจ Profile Selection** (NEW!) +6. Finish Screen (with Privacy Policy link) + +## Testing Checklist + +- [ ] Profile cards display correctly +- [ ] Multi-select works (can select/deselect profiles) +- [ ] Cannot continue without selecting at least one profile +- [ ] Hover effects work on profile cards +- [ ] Settings are applied correctly for each profile combination +- [ ] Privacy Policy links open correct URL +- [ ] Reset script clears all app data +- [ ] Onboarding shows on fresh launch after reset +- [ ] Selected profile settings persist after closing onboarding + +## Profile Settings Matrix + +| Setting | Developer | Designer | Light Use | Student | Always Enabled | +|---------|-----------|----------|-----------|---------|----------------| +| **Clipboard** | โœ… | โœ… | โœ… | โœ… | **YES** | +| Minimalistic UI | OFF | OFF | **ON** | OFF | - | +| Color Picker | **ON** | **ON** | OFF | OFF | - | +| Mirror | OFF | **ON** | OFF | OFF | - | +| Stats | **ON** | OFF | OFF | OFF | - | +| Timer | **ON** | OFF | **ON** | **ON** | - | +| Screen Assistant | **ON** | OFF | OFF | OFF | - | +| Lighting Effects | - | **ON** | - | - | - | +| Inline HUD | - | **ON** | OFF | - | - | +| Calendar | - | - | - | **ON** | - | + +**Note**: Clipboard Manager is always enabled regardless of profile selection. + +## Next Steps + +1. **Create GitHub Pages Privacy Policy**: + - Create `docs/privacy-policy.md` in the repository + - Enable GitHub Pages for the repo + - Add actual privacy policy content + +2. **Test All Profile Combinations**: + - Single profiles (4 tests) + - Common combinations (Developer+Designer, etc.) + - All profiles selected + +3. **Verify Settings Integration**: + - Check that disabled features don't appear in UI + - Verify minimalistic mode works correctly + - Test feature toggles in settings + +## Implementation Notes + +- Profile selection is **required** (cannot skip) +- Settings are applied immediately when continuing +- Profile data is stored in UserDefaults +- Reset script is safe - only clears app-specific data +- All UI uses SwiftUI with proper transitions and animations diff --git a/ReadMe.md b/ReadMe.md index cc82791..a4e9d84 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -56,6 +56,9 @@ - **Audio Visualizer**: Dynamic spectrum visualization with color adaptation - **Multi-Platform Support**: Apple Music, Spotify, YouTube Music, and more - **Smooth Transitions**: Elegant animations between tracks and states +- **Minimalistic Mode**: Streamlined 420px compact layout for essential controls +- **Lighting Effects**: Beautiful album art glow effects with player tinting +- **Sneak Peek**: Standard and inline preview modes for quick glances ### ๐Ÿ“Š Advanced System Monitoring - **CPU, Memory, GPU, Network, Disk**: Real-time stats with live graphs @@ -63,8 +66,9 @@ - **Intelligent Layout**: Vertical expansion, 1-5 graph layouts, perfect centering - **Customizable Visibility**: Toggle individual graphs on/off - **Smooth Animations**: Debounced updates for fluid transitions +- **Stats Panel**: Floating window with detailed system metrics -### ๐ŸŽจ ColorPicker (NEW!) +### ๐ŸŽจ ColorPicker
ColorPicker Panel
@@ -72,10 +76,43 @@
- **Screen Color Picking**: Raycast-inspired panel, real-time magnification -- **Multiple Formats**: HEX, RGB, HSL, SwiftUI, UIColor, and more +- **Multiple Formats**: HEX, RGB, HSL, SwiftUI, UIColor, NSColor, CSS, and more - **History & Quick Copy**: Recent colors, hover info, click to copy - **Global Shortcut**: Cmd+Shift+P (customizable) -- **Settings Integration**: Enable/disable, customize controls +- **Panel & Popover Modes**: Choose between floating panel or integrated popover +- **Settings Integration**: Full control over features and appearance + +### ๐Ÿ“‹ Clipboard Manager +
+ Clipboard Panel +
+ Clipboard Popover +
+ +- **Clipboard History**: Access recent clipboard items with thumbnails +- **Panel & Popover**: Dual display modes for flexible access +- **Always Active**: Clipboard monitoring enabled by default +- **Quick Access**: Click to copy, keyboard shortcuts for rapid paste + +### ๐Ÿง  Screen Assistant +- **AI-Powered Analysis**: Intelligent screen content understanding +- **Panel & Popover Modes**: Flexible display options +- **Context-Aware**: Smart suggestions based on screen content +- **Keyboard Shortcut**: Quick access to screen analysis + +### โœจ Minimalistic Mode (NEW!) +- **Compact Layout**: 420px width (vs 640px normal) +- **Essential Features Only**: Music controls, HUDs, timer - no clutter +- **Perfect for Light Use**: Minimal interface for everyday tasks +- **Auto-Configuration**: Profile-based setup during onboarding +- **Smooth Transitions**: Seamless switching between modes + +### ๐ŸŽฏ Smart Onboarding (NEW!) +- **User Profiles**: Developer, Designer, Light Use, Student +- **Multi-Select**: Choose multiple profiles for combined features +- **Auto-Configuration**: Settings applied based on selected profiles +- **Privacy Policy**: Integrated privacy policy links +- **Guided Setup**: Camera, calendar, music permissions with clear explanations ### โฑ๏ธ Timer & Productivity - **Multiple Timers**: Create/manage named timers @@ -96,23 +133,41 @@ - **Perfect Alignment**: Maintains center positioning across all states ### ๐Ÿ—‚๏ธ Widgets & Panels -
- Clipboard Panel -
- Clipboard Popover -
- -- **Clipboard Manager**: Quick access to recent clipboard items +- **Multiple Panel Modes**: Floating panels and integrated popovers +- **Clipboard Manager**: Quick access to recent clipboard items (always enabled) +- **Screen Assistant**: AI-powered screen content analysis +- **ColorPicker**: Professional color picking tool +- **Stats Panel**: Floating system monitoring window - **Weather Widget**: Displays current weather (location access required) +- **Calendar Integration**: View upcoming events and schedules - **App Switcher**: Swipe gestures for fast app switching +### โŒจ๏ธ Keyboard Shortcuts +- **Toggle Notch**: Customizable shortcut to open/close DynamicIsland +- **Clipboard Panel**: Quick access to clipboard history +- **ColorPicker**: Instant color picker activation (Cmd+Shift+P) +- **Screen Assistant**: AI analysis shortcut +- **Stats Panel**: Toggle system monitoring window +- **Demo Timer**: Start 5-minute demo timer +- **Sneak Peek**: Quick preview toggle +- **Fully Customizable**: All shortcuts can be remapped + +### ๐ŸŽจ Customization & Theming +- **Minimalistic Mode**: Toggle between full-featured and minimal layouts +- **Corner Radius Scaling**: Adjust notch roundness +- **Lighting Effects**: Album art glow and player tinting +- **Shadow Effects**: Customize drop shadows +- **Mirror Feature**: Quick camera preview +- **Custom Animations**: Modern or classic close animations +- **Profile-Based Setup**: Auto-configure based on use case + --- ## ๐Ÿš€ Getting Started ### Prerequisites - **macOS Sonoma 14.0+** (Optimized for Sequoia 15.0+) -- **MacBook with Notch** (Pro 14"/16" M1/M2/M3 series) +- **MacBook with Notch** (Pro 14"/16" M1/M2/M3/M4 series) - **Xcode 15.0+**, **Swift 5.9+** - **Admin privileges** for system monitoring features @@ -122,9 +177,33 @@ git clone https://github.com/Ebullioscopic/DynamicIsland.git cd DynamicIsland open DynamicIsland.xcodeproj ``` -1. Enable **Accessibility**, **Screen Recording**, and **Full Disk Access** in System Settings -2. Build and run in Xcode (`Cmd + R`) -3. The app will appear in your menu bar and activate the notch +1. Build and run in Xcode (`Cmd + R`) +2. **First Launch Onboarding**: + - Choose your profile(s): Developer, Designer, Light Use, or Student + - Grant permissions: Camera (for mirror), Calendar, Music + - Settings auto-configured based on your selection +3. Enable **Accessibility** for advanced features (ColorPicker, Screen Assistant) +4. The app will appear in your menu bar and activate the notch + +### Quick Start Profiles + +**๐Ÿ”ง Developer** +- ColorPicker, Stats, Screen Assistant, Timer enabled +- Full feature set for coding workflows + +**๐ŸŽจ Designer** +- ColorPicker, Mirror, Lighting Effects enabled +- Visual-focused tools and aesthetics + +**โœจ Light Use** +- Minimalistic Mode (420px compact layout) +- Essential features only: Music, HUDs, Timer + +**๐Ÿ“š Student** +- Calendar, Timer, Clipboard enabled +- Organization-focused feature set + +**Note**: Clipboard Manager is always enabled regardless of profile selection. --- @@ -134,44 +213,129 @@ open DynamicIsland.xcodeproj - **Hover to Activate**: Move cursor near the notch to expand - **Click to Open**: Tap the notch area for full controls - **Gesture Support**: Swipe down to expand, swipe up to close -- **Tab Navigation**: Switch between Home, Shelf, Timer, Stats, ColorPicker, and more +- **Tab Navigation**: Switch between Home, Stats, Timer, and more + +### First Time Setup +1. **Choose Your Profile**: Select Developer, Designer, Light Use, or Student +2. **Grant Permissions**: Camera, Calendar, Music access as needed +3. **Enable Accessibility**: For ColorPicker and Screen Assistant (optional) +4. **Customize**: Visit Settings to fine-tune features + +### Music & Media +- **Now Playing**: Album art, track info, playback controls +- **Visualizer**: Real-time audio spectrum (enable in Settings) +- **Minimalistic Mode**: Compact 420px layout for essential controls +- **Sneak Peek**: Quick preview without fully opening ### System Monitoring - **Stats Tab**: CPU, Memory, GPU, Network, Disk with live graphs -- **Layout Intelligence**: 1-3 graphs in a row, 4 in 2ร—2 grid, 5 in 3+2 layout +- **Layout Intelligence**: 1-3 graphs in a row, 4+ in grid layout +- **Stats Panel**: Floating window for persistent monitoring - **Smooth Transitions**: Animated layout changes, perfect centering ### ColorPicker -- **Panel & Popover**: Pick colors anywhere, see recent colors, copy formats -- **Shortcut**: Cmd+Shift+P to open picker +- **Quick Access**: Cmd+Shift+P or from tab navigation +- **Pick Colors**: Click anywhere on screen to sample +- **Copy Formats**: HEX, RGB, HSL, SwiftUI, CSS, and more +- **History**: Access recently picked colors +- **Panel/Popover**: Choose your preferred display mode -### Clipboard & Widgets -- **Clipboard Panel**: Access recent clipboard items -- **Weather Widget**: Current weather in notch (location access required) -- **App Switcher**: Swipe to switch apps +### Clipboard Manager +- **Always Active**: Clipboard history automatically tracked +- **Panel Access**: Keyboard shortcut or tab navigation +- **Quick Copy**: Click any item to copy to clipboard +- **Visual Previews**: See thumbnails of copied content + +### Screen Assistant +- **AI Analysis**: Intelligent screen content understanding +- **Context Aware**: Smart suggestions based on what you're viewing +- **Keyboard Shortcut**: Quick activation +- **Privacy First**: Local processing, no data sent externally ### Customization -- **Preferences Pane**: Long-press notch to open +- **Settings Window**: Click menubar icon โ†’ Settings +- **Profile Switch**: Change between Developer/Designer/Light/Student modes +- **Minimalistic Toggle**: Enable/disable compact layout +- **Feature Toggles**: Enable/disable individual features +- **Keyboard Shortcuts**: Customize all hotkeys - **Themes**: Light, dark, system adaptive -- **Widget Settings**: Enable/disable, adjust sizes, display preferences -- **Gestures**: Customize swipe, tap, long-press actions --- ## โš™๏ธ Configuration ### Settings Categories -- **Stats**: Enable/disable CPU, Memory, GPU, Network, Disk monitoring -- **Music & Media**: Visualizer type, color adaptation, media sources -- **Timer**: Default duration, notification style, colors, auto-start -- **Appearance & Behavior**: Theme, hover sensitivity, animation speed, corner radius, shadow effects + +#### General +- **Menubar Icon**: Show/hide menubar icon - **Multi-Display Support**: Choose main monitor, show on all displays -- **Keyboard Shortcuts**: Toggle DynamicIsland, open settings, quick stats, timer control +- **Minimalistic Mode**: Enable compact 420px layout +- **User Profiles**: Switch between Developer/Designer/Light/Student + +#### Appearance +- **Corner Radius Scaling**: Adjust notch roundness +- **Lighting Effects**: Album art glow and player tinting +- **Shadow Effects**: Enable/disable drop shadows +- **Mirror Feature**: Toggle camera preview +- **Modern Animations**: Choose animation styles +- **Themes**: Light, dark, system adaptive + +#### Behavior +- **Hover Sensitivity**: Adjust activation distance +- **Open on Hover**: Auto-expand on cursor proximity +- **Haptic Feedback**: Enable/disable haptics +- **Gestures**: Customize swipe, tap, long-press actions + +#### Features +- **Stats Monitoring**: Enable/disable CPU, Memory, GPU, Network, Disk +- **ColorPicker**: Toggle feature, set keyboard shortcut, panel/popover mode +- **Clipboard Manager**: Always enabled, configure display mode +- **Screen Assistant**: Enable/disable, set keyboard shortcut +- **Timer**: Default duration, notification style, colors +- **Music & Media**: Visualizer type, color adaptation, media sources + +#### Keyboard Shortcuts +- **Toggle Notch**: Open/close DynamicIsland +- **Sneak Peek**: Quick preview toggle +- **Clipboard**: Open clipboard panel +- **ColorPicker**: Activate color picker (default: Cmd+Shift+P) +- **Screen Assistant**: Open AI assistant +- **Stats Panel**: Toggle monitoring window +- **Demo Timer**: Start 5-minute timer +- **All Customizable**: Remap any shortcut + +#### Privacy & Permissions +- **Accessibility**: Required for ColorPicker, Screen Assistant +- **Camera**: For mirror feature +- **Calendar**: For event display +- **Music**: For playback controls + +### Reset to Defaults +Use the included script to reset all settings: +```bash +./reset_app_defaults.sh +``` +This will: +- Clear all UserDefaults +- Remove application support files +- Remove caches and preferences +- Reset to fresh install state (shows onboarding) --- ## ๐Ÿšง Roadmap +### โœ… Recently Added +- **Minimalistic Mode**: Compact 420px layout for light use +- **Smart Onboarding**: Profile-based setup (Developer/Designer/Light/Student) +- **ColorPicker**: Professional screen color picking tool +- **Clipboard Manager**: Always-on clipboard history +- **Screen Assistant**: AI-powered screen analysis +- **Panel System**: Floating windows and integrated popovers +- **Lighting Effects**: Album art glow and player tinting +- **Stats Panel**: Floating system monitoring window +- **Enhanced Keyboard Shortcuts**: Full customization support + ### ๐Ÿ”„ Upcoming Features - **Enhanced Calendar Integration**: Weekly/monthly views, event details - **Weather Widget**: Location-based forecasts, beautiful animations @@ -185,28 +349,91 @@ open DynamicIsland.xcodeproj - **3D Animations**: Enhanced visual effects - **Plugin Architecture**: Third-party extensions - **Cross-Platform**: iPad/iPhone companion apps +- **Localization**: Multi-language support --- ## ๐Ÿ”ง Troubleshooting ### Common Issues & Solutions -- **Permissions**: Enable Accessibility, Screen Recording, Full Disk Access -- **Stats Not Updating**: Check feature toggles, restart monitoring, verify permissions -- **Music Controls Not Working**: Ensure media app is playing, check permissions, restart app -- **Performance Issues**: Reduce update frequency, disable unused features, restart app -### Advanced -- **Reset to Defaults**: - ```bash - defaults delete com.ebullioscopic.DynamicIsland - ``` -- **Clean Reinstall**: - 1. Quit DynamicIsland - 2. Delete app from Applications - 3. Remove settings: `~/Library/Preferences/com.ebullioscopic.DynamicIsland.plist` - 4. Reinstall from latest build -- **Debug Mode**: Hold `โŒฅ` while opening Settings โ†’ Advanced โ†’ Debug Mode โ†’ Enable Verbose Logging +#### Permissions +- **Accessibility**: Required for ColorPicker and Screen Assistant + - Go to System Settings โ†’ Privacy & Security โ†’ Accessibility + - Enable DynamicIsland + - **Important**: Quit and restart the app after granting permission +- **Camera**: For mirror feature +- **Calendar**: For event display +- **Screen Recording**: For advanced features (optional) + +#### Stats Not Updating +- Check feature toggles in Settings โ†’ Stats +- Verify Stats feature is enabled +- Restart monitoring from Settings +- Check Activity Monitor for CPU/memory usage + +#### Music Controls Not Working +- Ensure media app (Music, Spotify, etc.) is playing +- Check Music permission in System Settings +- Restart DynamicIsland +- Try switching between media apps + +#### ColorPicker Not Working +- Grant Accessibility permission (see above) +- **Must quit and restart** app after granting permission +- Check keyboard shortcut isn't conflicting +- Verify ColorPicker feature is enabled in Settings + +#### Window Positioning Issues +- If notch appears shifted after toggling Minimalistic Mode: + - This was fixed in recent updates + - Update to latest version + - Window now repositions immediately + +#### Performance Issues +- Reduce stats update frequency in Settings +- Disable unused features (Stats, Visualizer, etc.) +- Check "Minimalistic Mode" for lighter resource usage +- Close other resource-intensive apps +- Restart DynamicIsland + +### Advanced Troubleshooting + +#### Reset to Factory Defaults +Use the included reset script: +```bash +cd /path/to/DynamicIsland +./reset_app_defaults.sh +``` + +Or manually: +```bash +# Clear UserDefaults +defaults delete com.karthikinformationtechnology.DynamicIsland + +# Remove app data +rm -rf ~/Library/Application\ Support/DynamicIsland +rm -rf ~/Library/Caches/com.karthikinformationtechnology.DynamicIsland +rm -f ~/Library/Preferences/com.karthikinformationtechnology.DynamicIsland.plist +rm -rf ~/Library/Saved\ Application\ State/com.karthikinformationtechnology.DynamicIsland.savedState +``` + +#### Clean Reinstall +1. Quit DynamicIsland +2. Delete app from Applications +3. Run reset script (above) +4. Rebuild from Xcode + +#### Debug Mode +- Hold `โŒฅ` while opening Settings +- Navigate to Advanced โ†’ Debug Mode +- Enable Verbose Logging +- Check Console.app for detailed logs + +### Getting Help +- **GitHub Issues**: [Report bugs or request features](https://github.com/Ebullioscopic/DynamicIsland/issues) +- **Discussions**: [Ask questions, share ideas](https://github.com/Ebullioscopic/DynamicIsland/discussions) +- **Documentation**: Check `ONBOARDING_ENHANCEMENT.md`, `SYSTEM_TIMER_DETECTION.md` for detailed guides --- diff --git a/reset_app_defaults.sh b/reset_app_defaults.sh new file mode 100755 index 0000000..fdfc356 --- /dev/null +++ b/reset_app_defaults.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# Reset DynamicIsland App - Clear all defaults and app state +# This script simulates a fresh first launch of the app + +set -e # Exit on error + +APP_NAME="DynamicIsland" +BUNDLE_ID="com.karthikinformationtechnology.DynamicIsland" + +echo "๐Ÿงน Resetting $APP_NAME to factory defaults..." +echo "" + +# Step 1: Kill the app if it's running +echo "1๏ธโƒฃ Checking if $APP_NAME is running..." +if pgrep -x "$APP_NAME" > /dev/null; then + echo " โš ๏ธ $APP_NAME is running. Terminating..." + killall "$APP_NAME" 2>/dev/null || true + sleep 1 + echo " โœ… App terminated" +else + echo " โ„น๏ธ $APP_NAME is not running" +fi + +# Step 2: Clear UserDefaults +echo "" +echo "2๏ธโƒฃ Clearing UserDefaults for $BUNDLE_ID..." +defaults delete "$BUNDLE_ID" 2>/dev/null && echo " โœ… UserDefaults cleared" || echo " โ„น๏ธ No UserDefaults found (already clean)" + +# Step 3: Remove Application Support files +echo "" +echo "3๏ธโƒฃ Removing Application Support files..." +APP_SUPPORT_DIR="$HOME/Library/Application Support/$APP_NAME" +if [ -d "$APP_SUPPORT_DIR" ]; then + rm -rf "$APP_SUPPORT_DIR" + echo " โœ… Removed: $APP_SUPPORT_DIR" +else + echo " โ„น๏ธ No Application Support directory found" +fi + +# Step 4: Remove Caches +echo "" +echo "4๏ธโƒฃ Removing cached data..." +CACHE_DIR="$HOME/Library/Caches/$BUNDLE_ID" +if [ -d "$CACHE_DIR" ]; then + rm -rf "$CACHE_DIR" + echo " โœ… Removed: $CACHE_DIR" +else + echo " โ„น๏ธ No cache directory found" +fi + +# Step 5: Remove Preferences plist (backup of defaults) +echo "" +echo "5๏ธโƒฃ Removing preference files..." +PREF_FILE="$HOME/Library/Preferences/$BUNDLE_ID.plist" +if [ -f "$PREF_FILE" ]; then + rm -f "$PREF_FILE" + echo " โœ… Removed: $PREF_FILE" +else + echo " โ„น๏ธ No preference file found" +fi + +# Step 6: Remove Saved Application State +echo "" +echo "6๏ธโƒฃ Removing saved application state..." +SAVED_STATE_DIR="$HOME/Library/Saved Application State/$BUNDLE_ID.savedState" +if [ -d "$SAVED_STATE_DIR" ]; then + rm -rf "$SAVED_STATE_DIR" + echo " โœ… Removed: $SAVED_STATE_DIR" +else + echo " โ„น๏ธ No saved state found" +fi + +# Done +echo "" +echo "โœจ Reset complete! $APP_NAME will show onboarding on next launch." +echo "" +echo "To launch the app now, run:" +echo " open -a $APP_NAME" +echo ""