diff --git a/.gitignore b/.gitignore index 34a62cb..9082292 100644 --- a/.gitignore +++ b/.gitignore @@ -121,6 +121,7 @@ integration.json # GitHub instructions and agent files # .github/instructions/ +.github/assets/ rough_note.md Solid SettingsView.swift.md @@ -156,4 +157,4 @@ mew-notch/ /References/ /builds/ -/appdmg.json \ No newline at end of file +/appdmg.json diff --git a/DynamicIsland/Localizable.xcstrings b/DynamicIsland/Localizable.xcstrings index 43742e8..c493d44 100644 --- a/DynamicIsland/Localizable.xcstrings +++ b/DynamicIsland/Localizable.xcstrings @@ -1013,11 +1013,47 @@ } } }, + "%lld day%@ ago" : { + "comment" : "Text that appears in the \"Time\" column of the \"Account History\" view, indicating how long ago a particular event occurred. The number in the parentheses is replaced with the actual number of days.", + "isCommentAutoGenerated" : true, + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld day%2$@ ago" + } + } + } + }, + "%lld hour%@ ago" : { + "comment" : "Text for a time string, showing how many hours have passed since a given date.", + "isCommentAutoGenerated" : true, + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld hour%2$@ ago" + } + } + } + }, "%lld min" : { "comment" : "A text label displaying the current value of the \"Notify before\" slider. The argument is the current value of the slider, expressed in minutes.", "isCommentAutoGenerated" : true, "shouldTranslate" : false }, + "%lld minute%@ ago" : { + "comment" : "A string describing how long ago a particular event occurred, based on the number of minutes that have passed.", + "isCommentAutoGenerated" : true, + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$lld minute%2$@ ago" + } + } + } + }, "%lld px" : { "comment" : "A label displaying the current expanded notch width value. The value is shown in pixels.", "isCommentAutoGenerated" : true, @@ -1129,6 +1165,26 @@ }, "shouldTranslate" : false }, + "%lldd ago" : { + "comment" : "A string describing how many days have passed since a given date. The argument is the number of days.", + "isCommentAutoGenerated" : true + }, + "%lldh" : { + "comment" : "Text that describes a time interval, such as \"1 hour ago\".", + "isCommentAutoGenerated" : true + }, + "%lldh ago" : { + "comment" : "A string describing how long ago a given date was, in terms of hours.", + "isCommentAutoGenerated" : true + }, + "%lldm" : { + "comment" : "A string that describes how long ago a given date was, in a human-readable form.", + "isCommentAutoGenerated" : true + }, + "%lldm ago" : { + "comment" : "A string describing how long ago a given date was, in terms of minutes. The argument is the number of minutes.", + "isCommentAutoGenerated" : true + }, "%lldx" : { "localizations" : { "fr" : { @@ -1535,6 +1591,10 @@ } } }, + "±10 Seconds" : { + "comment" : "Name of the music skip behavior that skips the current track within ±10 seconds.", + "isCommentAutoGenerated" : true + }, "0" : { "comment" : "A label displayed in a circular gauge to indicate the minimum battery level.", "isCommentAutoGenerated" : true, @@ -1851,8 +1911,11 @@ } } }, + "Accent" : { + "comment" : "Name of the tint mode for the caps lock indicator that uses the accent color.", + "isCommentAutoGenerated" : true + }, "Accent color" : { - "extractionState" : "stale", "localizations" : { "ar" : { "stringUnit" : { @@ -2197,6 +2260,10 @@ } } }, + "Adaptive gradient" : { + "comment" : "Name of the timer icon color mode option that uses an adaptive gradient.", + "isCommentAutoGenerated" : true + }, "Add" : { "localizations" : { "ar" : { @@ -3270,6 +3337,26 @@ } } }, + "Allow extension live activities" : { + "comment" : "Toggle to allow extension live activities.", + "isCommentAutoGenerated" : true + }, + "Allow extension lock screen widgets" : { + "comment" : "Text displayed in a toggle that allows users to enable or disable the display of lock screen widgets in Atoll.", + "isCommentAutoGenerated" : true + }, + "Allow extension notch experiences" : { + "comment" : "Text displayed in a toggle that allows users to enable or disable the display of notch-specific features in an extension.", + "isCommentAutoGenerated" : true + }, + "Allow interactive web content" : { + "comment" : "Toggle label for allowing interactive web content in notch experiences.", + "isCommentAutoGenerated" : true + }, + "Allow minimalistic overrides" : { + "comment" : "Label for a toggle that allows minimalistic overrides in notch experiences.", + "isCommentAutoGenerated" : true + }, "Allowed Features" : { "comment" : "A label describing the allowed features for an app extension.", "isCommentAutoGenerated" : true, @@ -3766,6 +3853,10 @@ } } }, + "Apple Music" : { + "comment" : "Names for the different media player types available in the app.", + "isCommentAutoGenerated" : true + }, "Applies the notch-style parallax effect to the lock screen media widget album art." : { "localizations" : { "pt-BR" : { @@ -3788,6 +3879,10 @@ } } }, + "AQI" : { + "comment" : "Label for the US AQI scale in the lock screen weather view.", + "isCommentAutoGenerated" : true + }, "Are you sure you want to delete \"%@\"?" : { "comment" : "A confirmation prompt asking the user to confirm the deletion of a custom idle animation. The placeholder text inside the quotation marks should be replaced with the name of the animation.", "localizations" : { @@ -3849,7 +3944,6 @@ "shouldTranslate" : false }, "Atoll can show all your upcoming events in one place. Access to your calendar is needed to display your schedule." : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -3860,7 +3954,6 @@ } }, "Atoll includes a mirror feature that lets you quickly check your appearance using your camera, right from the notch. Camera access is required only to show this live preview. You can turn the mirror feature on or off at any time in the app." : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -4175,6 +4268,10 @@ } } }, + "Bar" : { + "comment" : "Localized name for \"Bar\" timer progress style.", + "isCommentAutoGenerated" : true + }, "Battery" : { "localizations" : { "ar" : { @@ -4853,6 +4950,10 @@ } } }, + "Break" : { + "comment" : "Name of a default timer preset that lasts for 5 minutes.", + "isCommentAutoGenerated" : true + }, "Breakdown" : { "comment" : "A label displayed above the breakdown of memory usage.", "isCommentAutoGenerated" : true, @@ -5554,6 +5655,10 @@ } } }, + "Charging battery" : { + "comment" : "Text displayed in the status text field when the device is charging.", + "isCommentAutoGenerated" : true + }, "Charging on Hold: Desktop Mode" : { "localizations" : { "ar" : { @@ -6129,6 +6234,14 @@ } } }, + "Circular" : { + "comment" : "Label for the \"Circular\" tab in the HUD and OSD settings view.", + "isCommentAutoGenerated" : true + }, + "Classic" : { + "comment" : "Name of the timer surface mode in the lock screen that looks like a traditional stopwatch.", + "isCommentAutoGenerated" : true + }, "Classic mode keeps the original translucent black background." : { "comment" : "A description of the \"Classic mode\" option in the Lock Screen Integration settings.", "isCommentAutoGenerated" : true, @@ -6582,6 +6695,10 @@ } } }, + "Code and debug with color picker, stats monitoring, and screen assistant." : { + "comment" : "Description of a user profile when the name is \"Developer\".", + "isCommentAutoGenerated" : true + }, "Collect the latest crash report to share with the developer when reporting lock screen or overlay issues." : { "comment" : "A footer for the \"Diagnostics\" section of the lock screen settings.", "isCommentAutoGenerated" : true, @@ -6940,6 +7057,12 @@ } } } + }, + "Connects directly to the Apple Music app." : { + + }, + "Connects directly to the Spotify app." : { + }, "Continue" : { "localizations" : { @@ -7221,6 +7344,10 @@ } } }, + "CPU" : { + "comment" : "Title for the CPU usage graph.", + "isCommentAutoGenerated" : true + }, "CPU Usage" : { "localizations" : { "fr" : { @@ -7237,6 +7364,10 @@ } } }, + "Create and design with color picker, mirror, and visual effects." : { + "comment" : "Description of a user profile when the name is \"Designer\".", + "isCommentAutoGenerated" : true + }, "Create from Clipboard" : { "localizations" : { "pt-BR" : { @@ -7471,6 +7602,9 @@ } } } + }, + "Custom Liquid" : { + }, "Custom liquid glass already renders with Apple's liquid material, so this option is managed automatically." : { "comment" : "A description of the custom liquid blur option in the media settings.", @@ -8001,6 +8135,10 @@ } } }, + "Deep Work" : { + "comment" : "Name of a default timer preset for deep work.", + "isCommentAutoGenerated" : true + }, "Default" : { "localizations" : { "ar" : { @@ -8316,6 +8454,10 @@ }, "Deselect All" : { + }, + "Designer" : { + "comment" : "Name of a user profile for a designer.", + "isCommentAutoGenerated" : true }, "Detection Status" : { "comment" : "The header for a section that displays whether the screen recording detection feature is currently active or inactive.", @@ -8335,6 +8477,10 @@ } } }, + "Developer" : { + "comment" : "Name of a user profile.", + "isCommentAutoGenerated" : true + }, "Devices" : { "comment" : "The title of the \"Devices\" section in the settings menu.", "isCommentAutoGenerated" : true, @@ -8359,6 +8505,10 @@ } } }, + "Digital" : { + "comment" : "Name for the \"Digital\" style of reminder presentation.", + "isCommentAutoGenerated" : true + }, "Dimensions" : { "localizations" : { "pt-BR" : { @@ -8585,6 +8735,10 @@ } } }, + "Disk" : { + "comment" : "Title for the \"Disk\" section in the stats view.", + "isCommentAutoGenerated" : true + }, "Disk Read" : { "localizations" : { "fr" : { @@ -9162,6 +9316,10 @@ } } }, + "EAQI" : { + "comment" : "The label to use for the compact version of the weather air quality scale in the lock screen.", + "isCommentAutoGenerated" : true + }, "Easily copy, store, and manage your most-used content. Upgrade now for advanced features like multi-item storage and quick access!" : { "localizations" : { "ar" : { @@ -9436,7 +9594,6 @@ } }, "Enable Calendar Access" : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -9447,7 +9604,6 @@ } }, "Enable Camera Access" : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -9588,6 +9744,10 @@ }, "Enable Dynamic Island media controls to manage the lock screen panel." : { + }, + "Enable extension diagnostics logging" : { + "comment" : "A toggle that enables or disables logging of diagnostic information related to extensions.", + "isCommentAutoGenerated" : true }, "Enable extensions to allow third-party apps to display live activities and lock screen widgets in Atoll." : { "comment" : "A footer text that explains the purpose of enabling extensions.", @@ -10017,6 +10177,10 @@ } } }, + "Enable third-party extensions" : { + "comment" : "Toggle to enable or disable third-party extensions.", + "isCommentAutoGenerated" : true + }, "Enable timer live activity" : { "localizations" : { "pt-BR" : { @@ -10371,6 +10535,10 @@ } } }, + "Event color" : { + "comment" : "Name of the chip style that shows the event color.", + "isCommentAutoGenerated" : true + }, "Event List" : { "comment" : "A section header in the calendar settings view, describing the list of calendar events.", "isCommentAutoGenerated" : true, @@ -10664,6 +10832,14 @@ } } }, + "Favorites" : { + "comment" : "Localized name of the \"Favorites\" tab in the clipboard.", + "isCommentAutoGenerated" : true + }, + "File" : { + "comment" : "Display name for a \"File\" clipboard item type.", + "isCommentAutoGenerated" : true + }, "Files dropped on the shelf will be shared via this service" : { "comment" : "A description below the currently selected quick share provider, explaining that files dropped on the shelf will be shared via that provider.", "isCommentAutoGenerated" : true, @@ -10808,6 +10984,10 @@ } } }, + "Focus" : { + "comment" : "Name of a default timer preset.", + "isCommentAutoGenerated" : true + }, "Focus active: %@" : { "comment" : "An accessibility label for the focus widget, describing the currently active focus mode.", "isCommentAutoGenerated" : true, @@ -10858,6 +11038,14 @@ } } }, + "Frosted Glass" : { + "comment" : "The name of the frosted glass style.", + "isCommentAutoGenerated" : true + }, + "Full charge" : { + "comment" : "Text displayed in the status text when the battery is fully charged.", + "isCommentAutoGenerated" : true + }, "Full Disk Access required" : { "extractionState" : "stale", "localizations" : { @@ -11425,6 +11613,10 @@ }, "shouldTranslate" : false }, + "Glass" : { + "comment" : "Name of the timer surface mode that uses a glass effect.", + "isCommentAutoGenerated" : true + }, "Glass mode" : { "localizations" : { "pt-BR" : { @@ -11547,6 +11739,10 @@ } } }, + "GPU" : { + "comment" : "Title for the GPU usage graph.", + "isCommentAutoGenerated" : true + }, "GPU Usage" : { "localizations" : { "fr" : { @@ -11679,6 +11875,10 @@ } } }, + "Green" : { + "comment" : "Display name for the \"Green\" caps lock indicator tint mode.", + "isCommentAutoGenerated" : true + }, "Height:" : { "extractionState" : "stale", "localizations" : { @@ -12073,6 +12273,10 @@ } } }, + "History" : { + "comment" : "Localized name of each tab in the clipboard view.", + "isCommentAutoGenerated" : true + }, "History Size" : { "localizations" : { "fr" : { @@ -12475,6 +12679,10 @@ } } }, + "Image" : { + "comment" : "Name of the \"Image\" clipboard item type.", + "isCommentAutoGenerated" : true + }, "Import" : { "localizations" : { "fr" : { @@ -12917,6 +13125,14 @@ } } }, + "just now" : { + "comment" : "Text describing a moment in time that is just now.", + "isCommentAutoGenerated" : true + }, + "Just now" : { + "comment" : "A string indicating that an action was performed just recently.", + "isCommentAutoGenerated" : true + }, "Keyboard Backlight HUD" : { "localizations" : { "fr" : { @@ -13137,6 +13353,10 @@ } } }, + "Light Use" : { + "comment" : "Name of the \"Light Use\" user profile.", + "isCommentAutoGenerated" : true + }, "Line Width: %lldpx" : { "localizations" : { "pt-BR" : { @@ -13159,6 +13379,10 @@ }, "shouldTranslate" : false }, + "Liquid Glass" : { + "comment" : "Name of the \"Liquid Glass\" lock screen glass style.", + "isCommentAutoGenerated" : true + }, "Liquid Glass requires macOS 26 or later." : { "localizations" : { "fr" : { @@ -13617,6 +13841,10 @@ } } }, + "Low battery" : { + "comment" : "Text displayed when the battery level drops below a certain threshold.", + "isCommentAutoGenerated" : true + }, "Low Power Mode" : { "localizations" : { "ar" : { @@ -13717,6 +13945,10 @@ } } }, + "Low Power: %@" : { + "comment" : "Text displayed in a status label at the top of the screen indicating whether low power mode is on or off.", + "isCommentAutoGenerated" : true + }, "Mac battery at %d percent" : { "comment" : "Mac battery gauge accessibility label", "localizations" : { @@ -14855,6 +15087,10 @@ } } }, + "Memory" : { + "comment" : "Title of the memory usage single value graph.", + "isCommentAutoGenerated" : true + }, "Memory Usage" : { "localizations" : { "fr" : { @@ -14985,6 +15221,10 @@ } } }, + "Mic" : { + "comment" : "Name of a sneak action type that controls the microphone.", + "isCommentAutoGenerated" : true + }, "Mic %@" : { "extractionState" : "stale", "localizations" : { @@ -15294,7 +15534,6 @@ } }, "Minutes" : { - "extractionState" : "stale", "localizations" : { "fr" : { "stringUnit" : { @@ -16153,6 +16392,10 @@ } } }, + "Network" : { + "comment" : "Title for the \"Network\" section in the stats view.", + "isCommentAutoGenerated" : true + }, "Network Download" : { "localizations" : { "fr" : { @@ -17045,6 +17288,10 @@ } } }, + "Not charging" : { + "comment" : "Text displayed in the status text when the battery is not charging.", + "isCommentAutoGenerated" : true + }, "Not Now" : { "localizations" : { "ar" : { @@ -17496,6 +17743,14 @@ } } }, + "Now Playing" : { + "comment" : "Localized name for each media controller type.", + "isCommentAutoGenerated" : true + }, + "Off" : { + "comment" : "Text displayed in a status label at the top of the screen indicating whether low power mode is on or off.", + "isCommentAutoGenerated" : true + }, "OK" : { "localizations" : { "ar" : { @@ -17597,6 +17852,10 @@ }, "shouldTranslate" : false }, + "On" : { + "comment" : "Status text that indicates whether low power mode is on or off.", + "isCommentAutoGenerated" : true + }, "One or more files failed to load" : { "localizations" : { "ar" : { @@ -17851,6 +18110,10 @@ } } }, + "Panel" : { + "comment" : "Display name for the \"Panel\" clipboard display mode.", + "isCommentAutoGenerated" : true + }, "Panel mode shows clipboard in a floating window near the notch." : { "comment" : "A description of the \"Panel\" clipboard display mode.", "isCommentAutoGenerated" : true, @@ -17899,7 +18162,6 @@ } }, "Percentage" : { - "extractionState" : "stale", "localizations" : { "en" : { "stringUnit" : { @@ -18143,6 +18405,10 @@ } } }, + "Popover" : { + "comment" : "Description of a timer display mode when the controls are displayed as a popover.", + "isCommentAutoGenerated" : true + }, "Popover mode shows clipboard as a dropdown attached to the clipboard button." : { "comment" : "A description of the \"Popover mode\" in the Clipboard Settings view.", "isCommentAutoGenerated" : true, @@ -18297,6 +18563,10 @@ } } }, + "Progress" : { + "comment" : "Name of the download indicator style that shows a progress bar.", + "isCommentAutoGenerated" : true + }, "Progress bar" : { "extractionState" : "stale", "localizations" : { @@ -18668,6 +18938,10 @@ } } }, + "R " : { + "comment" : "Label for the read data in the disk usage graph.", + "isCommentAutoGenerated" : true + }, "Re-authorize" : { "comment" : "A button that re-authorizes an app when pressed.", "isCommentAutoGenerated" : true, @@ -19102,6 +19376,10 @@ } } }, + "Requires a third-party client with API plugin enabled." : { + "comment" : "Description of a music controller type when it requires a third-party client with an API plugin enabled.", + "isCommentAutoGenerated" : true + }, "Requires Accessibility permission so Dynamic Island can intercept the hardware volume keys." : { "localizations" : { "pt-BR" : { @@ -19413,6 +19691,10 @@ } } }, + "Rich Text" : { + "comment" : "Name for a clipboard item type that represents a rich text format.", + "isCommentAutoGenerated" : true + }, "Right" : { "localizations" : { "pt-BR" : { @@ -19423,6 +19705,10 @@ } } }, + "Ring" : { + "comment" : "Name of the timer progress style that shows a ring animation.", + "isCommentAutoGenerated" : true + }, "Rotation:" : { "extractionState" : "stale", "localizations" : { @@ -20243,6 +20529,10 @@ } } }, + "Separate Tab" : { + "comment" : "Name of the clipboard display mode option that opens the clipboard in a separate tab.", + "isCommentAutoGenerated" : true + }, "Separate Tab mode integrates Copied Items and Notes into a single view. If both are enabled, Notes appear on the right and Clipboard on the left." : { "comment" : "A description of the \"Separate Tab\" clipboard display mode.", "isCommentAutoGenerated" : true, @@ -20893,6 +21183,10 @@ }, "Show events within the next" : { + }, + "Show extension tabs" : { + "comment" : "Label for a toggle that enables or disables the display of tabs in notch experiences.", + "isCommentAutoGenerated" : true }, "Show floating pause/stop controls" : { "localizations" : { @@ -21293,6 +21587,14 @@ } } }, + "Shows screen assistant as a dropdown attached to the AI button" : { + "comment" : "Description of the \"Popover\" screen assistant display mode.", + "isCommentAutoGenerated" : true + }, + "Shows screen assistant in a floating panel near the notch" : { + "comment" : "Description of the \"panel\" display mode for the screen assistant.", + "isCommentAutoGenerated" : true + }, "Shows the model's reasoning process before the final answer" : { "localizations" : { "fr" : { @@ -21318,6 +21620,9 @@ } } } + }, + "Simple and minimal interface with just the essentials for everyday tasks." : { + }, "Size & Scale" : { "extractionState" : "stale", @@ -21352,6 +21657,10 @@ } } }, + "Skip forward or backward by ten seconds" : { + "comment" : "Description of the \"Skip forward or backward by ten seconds\" music skip behavior option.", + "isCommentAutoGenerated" : true + }, "Slider color" : { "localizations" : { "ar" : { @@ -21919,6 +22228,10 @@ } } }, + "Spotify" : { + "comment" : "Name of a media controller type for Spotify.", + "isCommentAutoGenerated" : true + }, "Square" : { "localizations" : { "ar" : { @@ -22018,12 +22331,19 @@ } } } + }, + "Standard" : { + }, "Standard notch media controls are hidden while this toggle is off." : { }, "Standard notch media controls are hidden. Re-enable the toggle above to restore them." : { + }, + "Standard previous/next track controls" : { + "comment" : "Description of a music skip behavior option that uses standard previous/next track controls.", + "isCommentAutoGenerated" : true }, "Start" : { "localizations" : { @@ -22283,6 +22603,9 @@ "comment" : "A label for the status of an extension.", "isCommentAutoGenerated" : true, "shouldTranslate" : false + }, + "Stay organized with calendar, timer, and battery monitoring." : { + }, "Stop" : { "localizations" : { @@ -22432,6 +22755,10 @@ } } }, + "Student" : { + "comment" : "Name of a user profile for a student.", + "isCommentAutoGenerated" : true + }, "Style" : { "localizations" : { "pt-BR" : { @@ -22731,6 +23058,10 @@ } } }, + "Tab" : { + "comment" : "Name of the \"Tab\" display mode.", + "isCommentAutoGenerated" : true + }, "Take area screenshot" : { "localizations" : { "fr" : { @@ -22757,6 +23088,10 @@ } } }, + "Text" : { + "comment" : "Name of a clipboard item type that contains plain text.", + "isCommentAutoGenerated" : true + }, "TheDynamicIsland" : { "shouldTranslate" : false }, @@ -23355,6 +23690,10 @@ }, "shouldTranslate" : false }, + "Track Skip" : { + "comment" : "Display name for the \"Track Skip\" music skip behavior option.", + "isCommentAutoGenerated" : true + }, "Transform" : { "extractionState" : "stale", "localizations" : { @@ -23655,6 +23994,10 @@ } } }, + "Unknown" : { + "comment" : "Description of a calendar authorization status that is not explicitly listed.", + "isCommentAutoGenerated" : true + }, "Unlock advanced features and improve your experience. Upgrade now for more customizations!" : { "localizations" : { "ar" : { @@ -23855,6 +24198,10 @@ } } }, + "Unplugged" : { + "comment" : "Text displayed in a notification when the device is plugged in.", + "isCommentAutoGenerated" : true + }, "Update interval" : { "localizations" : { "pt-BR" : { @@ -24001,6 +24348,10 @@ }, "shouldTranslate" : false }, + "URL" : { + "comment" : "Name of a clipboard item type that represents a URL.", + "isCommentAutoGenerated" : true + }, "Usage" : { "comment" : "A label displayed above the CPU usage statistics.", "isCommentAutoGenerated" : true, @@ -24617,6 +24968,10 @@ } } }, + "W " : { + "comment" : "Label for the write data point in the disk usage graph.", + "isCommentAutoGenerated" : true + }, "Weather" : { "comment" : "A label and its accompanying text displayed in a lock screen panel.", "isCommentAutoGenerated" : true, @@ -24926,6 +25281,9 @@ } } } + }, + "White" : { + }, "Widget Updates" : { "comment" : "A label describing the number of times the extension has updated its widget.", @@ -24976,6 +25334,10 @@ } } }, + "Works with most media apps, including browsers, to detect what's playing. Note: This may be removed in a future macOS version." : { + "comment" : "Description of a media controller type when it works with most media apps, including browsers, to detect what's playing. Note: This may be removed in a future macOS version.", + "isCommentAutoGenerated" : true + }, "Write" : { "comment" : "A label for the write section of the disk overview.", "isCommentAutoGenerated" : true, @@ -25211,7 +25573,6 @@ } }, "Your calendar data is only used to show your events and is never shared." : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -25222,7 +25583,6 @@ } }, "Your camera is never used without your consent, and nothing is recorded or stored." : { - "extractionState" : "stale", "localizations" : { "pt-BR" : { "stringUnit" : { @@ -25236,6 +25596,10 @@ "comment" : "A footer note explaining the app's funding.", "isCommentAutoGenerated" : true }, + "Youtube Music" : { + "comment" : "Name for the \"Youtube Music\" media controller type in settings.", + "isCommentAutoGenerated" : true + }, "YouTube Music requires this third-party app to be installed: " : { "localizations" : { "ar" : { diff --git a/DynamicIsland/components/Clipboard/ClipboardPanel.swift b/DynamicIsland/components/Clipboard/ClipboardPanel.swift index d80ae42..6972bba 100644 --- a/DynamicIsland/components/Clipboard/ClipboardPanel.swift +++ b/DynamicIsland/components/Clipboard/ClipboardPanel.swift @@ -456,16 +456,16 @@ struct ClipboardPanelItemRow: View { let interval = Date().timeIntervalSince(date) if interval < 60 { - return "Just now" + return String(localized: "Just now") } else if interval < 3600 { let minutes = Int(interval / 60) - return "\(minutes)m ago" + return String(localized: "\(minutes)m ago") } else if interval < 86400 { let hours = Int(interval / 3600) - return "\(hours)h ago" + return String(localized: "\(hours)h ago") } else { let days = Int(interval / 86400) - return "\(days)d ago" + return String(localized: "\(days)d ago") } } } diff --git a/DynamicIsland/components/Clipboard/ClipboardShared.swift b/DynamicIsland/components/Clipboard/ClipboardShared.swift index 1bd5baf..e30acc5 100644 --- a/DynamicIsland/components/Clipboard/ClipboardShared.swift +++ b/DynamicIsland/components/Clipboard/ClipboardShared.swift @@ -28,6 +28,13 @@ enum ClipboardTab: String, CaseIterable { case .favorites: return "heart.fill" } } + + var localizedName: String { + switch self { + case .history: return String(localized: "History") + case .favorites: return String(localized: "Favorites") + } + } } struct ClipboardTabButton: View { @@ -51,7 +58,7 @@ struct ClipboardTabButton: View { Image(systemName: tab.icon) .font(.system(size: 11)) - Text(tab.rawValue) + Text(tab.localizedName) .font(.system(size: 11, weight: .medium)) if itemCount > 0 { diff --git a/DynamicIsland/components/ColorPicker/ColorPickerPanel.swift b/DynamicIsland/components/ColorPicker/ColorPickerPanel.swift index 63488c2..4e7b019 100644 --- a/DynamicIsland/components/ColorPicker/ColorPickerPanel.swift +++ b/DynamicIsland/components/ColorPicker/ColorPickerPanel.swift @@ -530,16 +530,16 @@ struct ColorListRow: View { let interval = Date().timeIntervalSince(date) if interval < 60 { - return "Just now" + return String(localized: "Just now") } else if interval < 3600 { let minutes = Int(interval / 60) - return "\(minutes)m ago" + return String(localized: "\(minutes)m ago") } else if interval < 86400 { let hours = Int(interval / 3600) - return "\(hours)h ago" + return String(localized: "\(hours)h ago") } else { let days = Int(interval / 86400) - return "\(days)d ago" + return String(localized: "\(days)d ago") } } } @@ -589,16 +589,16 @@ struct ColorDetailsView: View { let interval = Date().timeIntervalSince(date) if interval < 60 { - return "just now" + return String(localized: "just now") } else if interval < 3600 { let minutes = Int(interval / 60) - return "\(minutes) minute\(minutes == 1 ? "" : "s") ago" + return String(localized: "\(minutes) minute\(minutes == 1 ? "" : "s") ago") } else if interval < 86400 { let hours = Int(interval / 3600) - return "\(hours) hour\(hours == 1 ? "" : "s") ago" + return String(localized: "\(hours) hour\(hours == 1 ? "" : "s") ago") } else { let days = Int(interval / 86400) - return "\(days) day\(days == 1 ? "" : "s") ago" + return String(localized: "\(days) day\(days == 1 ? "" : "s") ago") } } } diff --git a/DynamicIsland/components/Live activities/InlineHUD.swift b/DynamicIsland/components/Live activities/InlineHUD.swift index 4f55720..079bb7e 100644 --- a/DynamicIsland/components/Live activities/InlineHUD.swift +++ b/DynamicIsland/components/Live activities/InlineHUD.swift @@ -497,17 +497,17 @@ struct InlineHUD: View { func Type2Name(_ type: SneakContentType) -> String { switch(type) { case .volume: - return "Volume" + return String(localized: "Volume") case .brightness: - return "Brightness" + return String(localized: "Brightness") case .backlight: - return "Backlight" + return String(localized: "Backlight") case .mic: - return "Mic" + return String(localized: "Mic") case .bluetoothAudio: return BluetoothAudioManager.shared.lastConnectedDevice?.name ?? "Bluetooth" case .capsLock: - return "Caps Lock" + return String(localized: "Caps Lock") default: return "" } diff --git a/DynamicIsland/components/Notch/ClipboardHistoryPopover.swift b/DynamicIsland/components/Notch/ClipboardHistoryPopover.swift index 0867434..530f672 100644 --- a/DynamicIsland/components/Notch/ClipboardHistoryPopover.swift +++ b/DynamicIsland/components/Notch/ClipboardHistoryPopover.swift @@ -193,16 +193,16 @@ struct ClipboardItemRow: View { let interval = Date().timeIntervalSince(date) if interval < 60 { - return "Just now" + return String(localized: "Just now") } else if interval < 3600 { let minutes = Int(interval / 60) - return "\(minutes)m ago" + return String(localized: "\(minutes)m ago") } else if interval < 86400 { let hours = Int(interval / 3600) - return "\(hours)h ago" + return String(localized: "\(hours)h ago") } else { let days = Int(interval / 86400) - return "\(days)d ago" + return String(localized: "\(days)d ago") } } } diff --git a/DynamicIsland/components/Notch/NotchColorPickerView.swift b/DynamicIsland/components/Notch/NotchColorPickerView.swift index 2a819de..674878e 100644 --- a/DynamicIsland/components/Notch/NotchColorPickerView.swift +++ b/DynamicIsland/components/Notch/NotchColorPickerView.swift @@ -288,16 +288,16 @@ struct ColorInfoPopup: View { let interval = Date().timeIntervalSince(date) if interval < 60 { - return "Just now" + return String(localized: "Just now") } else if interval < 3600 { let minutes = Int(interval / 60) - return "\(minutes)m ago" + return String(localized: "\(minutes)m ago") } else if interval < 86400 { let hours = Int(interval / 3600) - return "\(hours)h ago" + return String(localized: "\(hours)h ago") } else { let days = Int(interval / 86400) - return "\(days)d ago" + return String(localized: "\(days)d ago") } } } diff --git a/DynamicIsland/components/Notch/NotchNotesView.swift b/DynamicIsland/components/Notch/NotchNotesView.swift index 308ebfa..d78a1b8 100644 --- a/DynamicIsland/components/Notch/NotchNotesView.swift +++ b/DynamicIsland/components/Notch/NotchNotesView.swift @@ -527,9 +527,9 @@ struct NotchClipboardItemRow: View { private func timeAgoString(from date: Date) -> String { let interval = Date().timeIntervalSince(date) - if interval < 60 { return "Just now" } - if interval < 3600 { return "\(Int(interval/60))m" } - return "\(Int(interval/3600))h" + if interval < 60 { return String(localized: "Just now") } + if interval < 3600 { return String(localized: "\(Int(interval/60))m") } + return String(localized: "\(Int(interval/3600))h") } } @@ -936,9 +936,9 @@ struct NoteRow: View { private func timeAgoString(from date: Date) -> String { let interval = Date().timeIntervalSince(date) - if interval < 60 { return "Just now" } - if interval < 3600 { return "\(Int(interval/60))m" } - if interval < 86400 { return "\(Int(interval/3600))h" } + if interval < 60 { return String(localized: "Just now") } + if interval < 3600 { return String(localized: "\(Int(interval/60))m") } + if interval < 86400 { return String(localized: "\(Int(interval/3600))h") } return date.formatted(.dateTime.day().month()) } } diff --git a/DynamicIsland/components/Notch/NotchStatsView.swift b/DynamicIsland/components/Notch/NotchStatsView.swift index 545b393..dc6a7b5 100644 --- a/DynamicIsland/components/Notch/NotchStatsView.swift +++ b/DynamicIsland/components/Notch/NotchStatsView.swift @@ -82,7 +82,7 @@ struct NotchStatsView: View { if showCpuGraph { graphs.append(SingleGraphData( - title: "CPU", + title: String(localized: "CPU"), value: statsManager.cpuUsageString, data: statsManager.cpuHistory, color: .blue, @@ -92,7 +92,7 @@ struct NotchStatsView: View { if showMemoryGraph { graphs.append(SingleGraphData( - title: "Memory", + title: String(localized: "Memory"), value: statsManager.memoryUsageString, data: statsManager.memoryHistory, color: .green, @@ -102,7 +102,7 @@ struct NotchStatsView: View { if showGpuGraph { graphs.append(SingleGraphData( - title: "GPU", + title: String(localized: "GPU"), value: statsManager.gpuUsageString, data: statsManager.gpuHistory, color: .purple, @@ -112,7 +112,7 @@ struct NotchStatsView: View { if showNetworkGraph { graphs.append(DualGraphData( - title: "Network", + title: String(localized: "Network"), positiveValue: "↓" + statsManager.networkDownloadString, negativeValue: "↑" + statsManager.networkUploadString, positiveData: statsManager.networkDownloadHistory, @@ -126,9 +126,9 @@ struct NotchStatsView: View { if showDiskGraph { graphs.append(DualGraphData( - title: "Disk", - positiveValue: "R " + statsManager.diskReadString, - negativeValue: "W " + statsManager.diskWriteString, + title: String(localized: "Disk"), + positiveValue: String(localized: "R ") + statsManager.diskReadString, + negativeValue: String(localized: "W ") + statsManager.diskWriteString, positiveData: statsManager.diskReadHistory, negativeData: statsManager.diskWriteHistory, positiveColor: .cyan, diff --git a/DynamicIsland/components/Notch/NotchTimerView.swift b/DynamicIsland/components/Notch/NotchTimerView.swift index 384b86b..c64606e 100644 --- a/DynamicIsland/components/Notch/NotchTimerView.swift +++ b/DynamicIsland/components/Notch/NotchTimerView.swift @@ -461,7 +461,7 @@ struct NotchTimerView: View { private var startButton: some View { Button { withAnimation(.smooth) { - timerManager.startTimer(duration: customDurationInSeconds, name: "Custom Timer") + timerManager.startTimer(duration: customDurationInSeconds, name: String(localized: "Custom Timer")) if !enableMinimalisticUI { coordinator.currentView = .timer } diff --git a/DynamicIsland/components/Onboarding/MusicControllerSelectionView.swift b/DynamicIsland/components/Onboarding/MusicControllerSelectionView.swift index 082e428..b3dc6d0 100644 --- a/DynamicIsland/components/Onboarding/MusicControllerSelectionView.swift +++ b/DynamicIsland/components/Onboarding/MusicControllerSelectionView.swift @@ -136,13 +136,13 @@ extension MediaControllerType { var description: String { switch self { case .nowPlaying: - return "Works with most media apps, including browsers, to detect what's playing. Note: This may be removed in a future macOS version." + return String(localized: "Works with most media apps, including browsers, to detect what's playing. Note: This may be removed in a future macOS version.") case .spotify: - return "Connects directly to the Spotify app." + return String(localized: "Connects directly to the Spotify app.") case .appleMusic: - return "Connects directly to the Apple Music app." + return String(localized: "Connects directly to the Apple Music app.") case .youtubeMusic: - return "Requires a third-party client with API plugin enabled." + return String(localized: "Requires a third-party client with API plugin enabled.") } } } diff --git a/DynamicIsland/components/Onboarding/OnboardingView.swift b/DynamicIsland/components/Onboarding/OnboardingView.swift index 7c6988b..bed1fd7 100644 --- a/DynamicIsland/components/Onboarding/OnboardingView.swift +++ b/DynamicIsland/components/Onboarding/OnboardingView.swift @@ -53,9 +53,9 @@ struct OnboardingView: View { case .cameraPermission: PermissionRequestView( icon: Image(systemName: "camera.fill"), - title: "Enable Camera Access", - description: "Atoll includes a mirror feature that lets you quickly check your appearance using your camera, right from the notch. Camera access is required only to show this live preview. You can turn the mirror feature on or off at any time in the app.", - privacyNote: "Your camera is never used without your consent, and nothing is recorded or stored.", + title: String(localized: "Enable Camera Access"), + description: String(localized: "Atoll includes a mirror feature that lets you quickly check your appearance using your camera, right from the notch. Camera access is required only to show this live preview. You can turn the mirror feature on or off at any time in the app."), + privacyNote: String(localized: "Your camera is never used without your consent, and nothing is recorded or stored."), onAllow: { Task { await requestCameraPermission() @@ -75,9 +75,9 @@ struct OnboardingView: View { case .calendarPermission: PermissionRequestView( icon: Image(systemName: "calendar"), - title: "Enable Calendar Access", - description: "Atoll can show all your upcoming events in one place. Access to your calendar is needed to display your schedule.", - privacyNote: "Your calendar data is only used to show your events and is never shared.", + title: String(localized: "Enable Calendar Access"), + description: String(localized: "Atoll can show all your upcoming events in one place. Access to your calendar is needed to display your schedule."), + privacyNote: String(localized: "Your calendar data is only used to show your events and is never shared."), onAllow: { Task { await requestCalendarPermission() diff --git a/DynamicIsland/components/Onboarding/ProfileSelectionView.swift b/DynamicIsland/components/Onboarding/ProfileSelectionView.swift index 564d351..92b6594 100644 --- a/DynamicIsland/components/Onboarding/ProfileSelectionView.swift +++ b/DynamicIsland/components/Onboarding/ProfileSelectionView.swift @@ -34,30 +34,30 @@ struct ProfileSelectionView: View { let profiles: [UserProfile] = [ UserProfile( id: "developer", - name: "Developer", + name: String(localized: "Developer"), icon: "terminal.fill", - description: "Code and debug with color picker, stats monitoring, and screen assistant.", + description: String(localized: "Code and debug with color picker, stats monitoring, and screen assistant."), gradient: [Color.blue, Color.purple] ), UserProfile( id: "designer", - name: "Designer", + name: String(localized: "Designer"), icon: "paintbrush.fill", - description: "Create and design with color picker, mirror, and visual effects.", + description: String(localized: "Create and design with color picker, mirror, and visual effects."), gradient: [Color.pink, Color.orange] ), UserProfile( id: "lightuse", - name: "Light Use", + name: String(localized: "Light Use"), icon: "sparkles", - description: "Simple and minimal interface with just the essentials for everyday tasks.", + description: String(localized: "Simple and minimal interface with just the essentials for everyday tasks."), gradient: [Color.green, Color.mint] ), UserProfile( id: "student", - name: "Student", + name: String(localized: "Student"), icon: "book.fill", - description: "Stay organized with calendar, timer, and battery monitoring.", + description: String(localized: "Stay organized with calendar, timer, and battery monitoring."), gradient: [Color.indigo, Color.cyan] ) ] diff --git a/DynamicIsland/components/Settings/ExtensionsSettings.swift b/DynamicIsland/components/Settings/ExtensionsSettings.swift index 05fc9ed..cda6147 100644 --- a/DynamicIsland/components/Settings/ExtensionsSettings.swift +++ b/DynamicIsland/components/Settings/ExtensionsSettings.swift @@ -61,32 +61,32 @@ struct ExtensionsSettingsView: View { private var globalTogglesSection: some View { Section { - Defaults.Toggle("Enable third-party extensions", key: .enableThirdPartyExtensions) + Defaults.Toggle(String(localized:"Enable third-party extensions"), key: .enableThirdPartyExtensions) .settingsHighlight(id: highlightID("Enable third-party extensions")) if Defaults[.enableThirdPartyExtensions] { - Defaults.Toggle("Allow extension live activities", key: .enableExtensionLiveActivities) + Defaults.Toggle(String(localized:"Allow extension live activities"), key: .enableExtensionLiveActivities) .settingsHighlight(id: highlightID("Allow extension live activities")) - Defaults.Toggle("Allow extension lock screen widgets", key: .enableExtensionLockScreenWidgets) + Defaults.Toggle(String(localized:"Allow extension lock screen widgets"), key: .enableExtensionLockScreenWidgets) .settingsHighlight(id: highlightID("Allow extension lock screen widgets")) - Defaults.Toggle("Allow extension notch experiences", key: .enableExtensionNotchExperiences) + Defaults.Toggle(String(localized:"Allow extension notch experiences"), key: .enableExtensionNotchExperiences) .settingsHighlight(id: highlightID("Allow extension notch experiences")) if Defaults[.enableExtensionNotchExperiences] { VStack(alignment: .leading, spacing: 8) { - Defaults.Toggle("Show extension tabs", key: .enableExtensionNotchTabs) + Defaults.Toggle(String(localized:"Show extension tabs"), key: .enableExtensionNotchTabs) .tint(.accentColor) - Defaults.Toggle("Allow minimalistic overrides", key: .enableExtensionNotchMinimalisticOverrides) + Defaults.Toggle(String(localized:"Allow minimalistic overrides"), key: .enableExtensionNotchMinimalisticOverrides) .tint(.accentColor) - Defaults.Toggle("Allow interactive web content", key: .enableExtensionNotchInteractiveWebViews) + Defaults.Toggle(String(localized:"Allow interactive web content"), key: .enableExtensionNotchInteractiveWebViews) .tint(.accentColor) } .padding(.leading, 4) } - Defaults.Toggle("Enable extension diagnostics logging", key: .extensionDiagnosticsLoggingEnabled) + Defaults.Toggle(String(localized:"Enable extension diagnostics logging"), key: .extensionDiagnosticsLoggingEnabled) .settingsHighlight(id: highlightID("Enable extension diagnostics logging")) } } header: { diff --git a/DynamicIsland/components/Timer/TimerPopover.swift b/DynamicIsland/components/Timer/TimerPopover.swift index 7b27eff..4bef53d 100644 --- a/DynamicIsland/components/Timer/TimerPopover.swift +++ b/DynamicIsland/components/Timer/TimerPopover.swift @@ -100,7 +100,7 @@ struct TimerPopover: View { let duration = customDurationInSeconds guard duration > 0 else { return } withAnimation(.smooth) { - timerManager.startTimer(duration: duration, name: "Custom Timer") + timerManager.startTimer(duration: duration, name: String(localized: "Custom Timer")) } dismiss() } diff --git a/DynamicIsland/enums/TimerDisplayMode.swift b/DynamicIsland/enums/TimerDisplayMode.swift index 00835dd..b65fd56 100644 --- a/DynamicIsland/enums/TimerDisplayMode.swift +++ b/DynamicIsland/enums/TimerDisplayMode.swift @@ -27,9 +27,9 @@ public enum TimerDisplayMode: String, CaseIterable, Defaults.Serializable, Ident var displayName: String { switch self { case .tab: - return "Tab" + return String(localized:"Tab") case .popover: - return "Popover" + return String(localized:"Popover") } } diff --git a/DynamicIsland/enums/generic.swift b/DynamicIsland/enums/generic.swift index 7f7110f..f9a9b8d 100644 --- a/DynamicIsland/enums/generic.swift +++ b/DynamicIsland/enums/generic.swift @@ -83,6 +83,17 @@ enum DownloadIndicatorStyle: String, Defaults.Serializable { case progress = "Progress" case percentage = "Percentage" case circle = "Circle" + + var localizedName: String { + switch self { + case .progress: + return String(localized: "Progress") + case .percentage: + return String(localized: "Percentage") + case .circle: + return String(localized: "Circle") + } + } } enum DownloadIconStyle: String, Defaults.Serializable { @@ -106,13 +117,33 @@ enum SliderColorEnum: String, CaseIterable, Defaults.Serializable { case white = "White" case albumArt = "Match album art" case accent = "Accent color" + + var localizedName: String { + switch self { + case .white: + return String(localized: "Standard") + case .albumArt: + return String(localized: "Custom Liquid") + case .accent: + return String(localized: "Accent color") + } + } } enum LockScreenGlassStyle: String, CaseIterable, Defaults.Serializable, Identifiable { case liquid = "Liquid Glass" case frosted = "Frosted Glass" - + var id: String { rawValue } + + var localizedName: String { + switch self { + case .liquid: + return String(localized: "Liquid Glass") + case .frosted: + return String(localized: "Frosted Glass") + } + } } enum LockScreenGlassCustomizationMode: String, CaseIterable, Defaults.Serializable, Identifiable { @@ -124,6 +155,15 @@ enum LockScreenGlassCustomizationMode: String, CaseIterable, Defaults.Serializab var allowsVariantSelection: Bool { self == .customLiquid } + + var localizedName: String { + switch self { + case .standard: + return String(localized: "Standard") + case .customLiquid: + return String(localized: "Custom Liquid") + } + } } enum LockScreenTimerSurfaceMode: String, CaseIterable, Defaults.Serializable, Identifiable { @@ -131,6 +171,15 @@ enum LockScreenTimerSurfaceMode: String, CaseIterable, Defaults.Serializable, Id case glass = "Glass" var id: String { rawValue } + + var localizedName: String { + switch self { + case .classic: + return String(localized: "Classic") + case .glass: + return String(localized: "Glass") + } + } } enum LockScreenWeatherWidgetStyle: String, CaseIterable, Defaults.Serializable, Identifiable { @@ -138,6 +187,15 @@ enum LockScreenWeatherWidgetStyle: String, CaseIterable, Defaults.Serializable, case circular = "Circular" var id: String { rawValue } + + var localizedName: String { + switch self { + case .inline: + return String(localized: "Inline") + case .circular: + return String(localized: "Circular") + } + } } enum LockScreenWeatherProviderSource: String, CaseIterable, Defaults.Serializable, Identifiable { @@ -192,18 +250,18 @@ enum LockScreenWeatherAirQualityScale: String, CaseIterable, Defaults.Serializab var compactLabel: String { switch self { case .us: - return "AQI" + return String(localized: "AQI") case .european: - return "EAQI" + return String(localized: "EAQI") } } var accessibilityLabel: String { switch self { case .us: - return "AQI" + return String(localized: "AQI") case .european: - return "EAQI" + return String(localized: "EAQI") } } @@ -231,4 +289,13 @@ enum LockScreenReminderChipStyle: String, CaseIterable, Defaults.Serializable, I case monochrome = "White" var id: String { rawValue } + + var localizedName: String { + switch self { + case .eventColor: + return String(localized: "Event color") + case .monochrome: + return String(localized: "White") + } + } } diff --git a/DynamicIsland/managers/ClipboardManager.swift b/DynamicIsland/managers/ClipboardManager.swift index c6f7ba8..d3a11a6 100644 --- a/DynamicIsland/managers/ClipboardManager.swift +++ b/DynamicIsland/managers/ClipboardManager.swift @@ -155,12 +155,12 @@ enum ClipboardItemType: String, CaseIterable, Codable { var displayName: String { switch self { - case .text: return "Text" - case .url: return "URL" - case .file: return "File" - case .image: return "Image" - case .rtf: return "Rich Text" - case .unknown: return "Unknown" + case .text: return String(localized: "Text") + case .url: return String(localized: "URL") + case .file: return String(localized: "File") + case .image: return String(localized: "Image") + case .rtf: return String(localized: "Rich Text") + case .unknown: return String(localized: "Unknown") } } } diff --git a/DynamicIsland/models/BatteryStatusViewModel.swift b/DynamicIsland/models/BatteryStatusViewModel.swift index 42d4ce3..0b9e792 100644 --- a/DynamicIsland/models/BatteryStatusViewModel.swift +++ b/DynamicIsland/models/BatteryStatusViewModel.swift @@ -81,7 +81,7 @@ class BatteryStatusViewModel: ObservableObject { print("🔌 Power source: \(isPluggedIn ? "Connected" : "Disconnected")") withAnimation { self.isPluggedIn = isPluggedIn - self.statusText = isPluggedIn ? "Plugged In" : "Unplugged" + self.statusText = isPluggedIn ? String(localized: "Plugged In") : String(localized: "Unplugged") self.notifyImportanChangeStatus() } @@ -98,7 +98,7 @@ class BatteryStatusViewModel: ObservableObject { self.notifyImportanChangeStatus() withAnimation { self.isInLowPowerMode = isEnabled - self.statusText = "Low Power: \(self.isInLowPowerMode ? "On" : "Off")" + self.statusText = String(localized: "Low Power: \(self.isInLowPowerMode ? String(localized: "On") : String(localized: "Off"))") } case .isChargingChanged(let isCharging): @@ -110,8 +110,8 @@ class BatteryStatusViewModel: ObservableObject { self.isCharging = isCharging self.statusText = isCharging - ? "Charging battery" - : (self.levelBattery < self.maxCapacity ? "Not charging" : "Full charge") + ? String(localized: "Charging battery") + : (self.levelBattery < self.maxCapacity ? String(localized: "Not charging") : String(localized: "Full charge")) } case .timeToFullChargeChanged(let time): @@ -141,7 +141,7 @@ class BatteryStatusViewModel: ObservableObject { self.isInLowPowerMode = batteryInfo.isInLowPowerMode self.timeToFullCharge = batteryInfo.timeToFullCharge self.maxCapacity = batteryInfo.maxCapacity - self.statusText = batteryInfo.isPluggedIn ? "Plugged In" : "Unplugged" + self.statusText = batteryInfo.isPluggedIn ? String(localized: "Plugged In") : String(localized: "Unplugged") } } @@ -161,7 +161,7 @@ class BatteryStatusViewModel: ObservableObject { for threshold in lowBatteryAlertThresholds { if previousLevel >= threshold && newLevel < threshold { - self.statusText = "Low battery" + self.statusText = String(localized: "Low battery") notifyImportanChangeStatus() playLowBatteryAlertSound() break diff --git a/DynamicIsland/models/Constants.swift b/DynamicIsland/models/Constants.swift index d587f61..c77f251 100644 --- a/DynamicIsland/models/Constants.swift +++ b/DynamicIsland/models/Constants.swift @@ -263,9 +263,9 @@ enum ClipboardDisplayMode: String, CaseIterable, Codable, Defaults.Serializable var displayName: String { switch self { - case .popover: return "Popover" - case .panel: return "Panel" - case .separateTab: return "Separate Tab" + case .popover: return String(localized: "Popover") + case .panel: return String(localized: "Panel") + case .separateTab: return String(localized: "Separate Tab") } } @@ -284,15 +284,15 @@ enum ScreenAssistantDisplayMode: String, CaseIterable, Codable, Defaults.Seriali var displayName: String { switch self { - case .popover: return "Popover" - case .panel: return "Panel" + case .popover: return String(localized: "Popover") + case .panel: return String(localized: "Panel") } } var description: String { switch self { - case .popover: return "Shows screen assistant as a dropdown attached to the AI button" - case .panel: return "Shows screen assistant in a floating panel near the notch" + case .popover: return String(localized: "Shows screen assistant as a dropdown attached to the AI button") + case .panel: return String(localized: "Shows screen assistant in a floating panel near the notch") } } } @@ -335,6 +335,15 @@ enum MediaControllerType: String, CaseIterable, Identifiable, Defaults.Serializa case youtubeMusic = "Youtube Music" var id: String { self.rawValue } + + var localizedName: String { + switch self { + case .nowPlaying: return String(localized: "Now Playing") + case .appleMusic: return String(localized: "Apple Music") + case .spotify: return String(localized: "Spotify") + case .youtubeMusic: return String(localized: "Youtube Music") + } + } } // Sneak peek styles for selection in settings @@ -343,6 +352,13 @@ enum SneakPeekStyle: String, CaseIterable, Identifiable, Defaults.Serializable { case inline = "Inline" var id: String { self.rawValue } + + var LocalizedName : String { + switch self { + case .standard: return String(localized: "Default") + case .inline: return String(localized: "Inline") + } + } } enum CapsLockIndicatorTintMode: String, CaseIterable, Identifiable, Defaults.Serializable { @@ -355,11 +371,11 @@ enum CapsLockIndicatorTintMode: String, CaseIterable, Identifiable, Defaults.Ser var displayName: String { switch self { case .green: - return "Green" + return String(localized: "Green") case .accent: - return "Accent" + return String(localized: "Accent") case .white: - return "White" + return String(localized: "White") } } @@ -438,18 +454,18 @@ enum MusicSkipBehavior: String, CaseIterable, Identifiable, Defaults.Serializabl var displayName: String { switch self { case .track: - return "Track Skip" + return String(localized: "Track Skip") case .tenSecond: - return "±10 Seconds" + return String(localized: "±10 Seconds") } } var description: String { switch self { case .track: - return "Standard previous/next track controls" + return String(localized: "Standard previous/next track controls") case .tenSecond: - return "Skip forward or backward by ten seconds" + return String(localized: "Skip forward or backward by ten seconds") } } } @@ -462,8 +478,8 @@ enum TimerIconColorMode: String, CaseIterable, Identifiable, Defaults.Serializab var displayName: String { switch self { - case .adaptive: return "Adaptive gradient" - case .solid: return "Solid colour" + case .adaptive: return String(localized:"Adaptive gradient") + case .solid: return String(localized:"Solid colour") } } } @@ -473,6 +489,13 @@ enum TimerProgressStyle: String, CaseIterable, Identifiable, Defaults.Serializab case ring = "Ring" var id: String { rawValue } + + var localizedName: String { + switch self { + case .bar: return String(localized:"Bar") + case .ring: return String(localized:"Ring") + } + } } enum ReminderPresentationStyle: String, CaseIterable, Identifiable, Defaults.Serializable { @@ -484,9 +507,12 @@ enum ReminderPresentationStyle: String, CaseIterable, Identifiable, Defaults.Ser var displayName: String { switch self { - case .ringCountdown: return "Ring" - case .digital: return "Digital" - case .minutes: return "Minutes" + case .ringCountdown: + return String(localized: "Ring") + case .digital: + return String(localized: "Digital") + case .minutes: + return String(localized: "Minutes") } } } diff --git a/DynamicIsland/models/TimerPreset.swift b/DynamicIsland/models/TimerPreset.swift index b733459..cfd0b9f 100644 --- a/DynamicIsland/models/TimerPreset.swift +++ b/DynamicIsland/models/TimerPreset.swift @@ -97,8 +97,8 @@ struct TimerPreset: Identifiable, Codable, Hashable, Defaults.Serializable { } static let defaultPresets: [TimerPreset] = [ - TimerPreset(name: "Focus", duration: 25 * 60, color: Color.orange), - TimerPreset(name: "Break", duration: 5 * 60, color: Color.green), - TimerPreset(name: "Deep Work", duration: 45 * 60, color: Color.purple) + TimerPreset(name: String(localized:"Focus"), duration: 25 * 60, color: Color.orange), + TimerPreset(name: String(localized:"Break"), duration: 5 * 60, color: Color.green), + TimerPreset(name: String(localized:"Deep Work"), duration: 45 * 60, color: Color.purple) ] }