Astro plugin star map#5528
Conversation
Buttons size and style the same we use on regular map + Liquid glass style by default
…stro_plugin_star_map
| colorIndex: int(item[keyColorIndex], fallback: nextColor % DirectionColor.allCases.count)) | ||
| }, | ||
| celestialPaths: parseItems(json?[keyCelestialPaths]) { CelestialPathConfig(id: $0) }) | ||
| celestialPaths: parseItems(json?[keyCelestialPaths]) { CelestialPathConfig(id: $0) }, |
There was a problem hiding this comment.
Is there a reason we're manually parsing [String: Any] instead of using Decodable?
| private static let keyId = "id" | ||
| private static let keyColorIndex = "colorIndex" | ||
|
|
||
| private static let keySavedMapPosition = "savedMapPosition" |
| private func commonInit() { | ||
| isUserInteractionEnabled = false | ||
| backgroundColor = .mapNightFilter | ||
| layer.compositingFilter = "multiplyBlendMode" |
There was a problem hiding this comment.
This approximately matches the astronomical red filter on Android. On Android, the effect is implemented using ColorMatrixColorFilter, which maps luminance to the red channel. UIKit does not provide a public equivalent of a color matrix filter for arbitrary UIView content, so on iOS we approximate the effect by applying a red overlay with the multiplyBlendMode compositing filter.
| func setOnDateTimeChangeListener(_ listener: @escaping (Date) -> Void) { | ||
| onDateTimeChangeListener = listener | ||
| } | ||
|
|
||
| func setDateTime(_ date: Date) { | ||
| currentDate = date | ||
| updateDisplay() | ||
| } | ||
|
|
||
| func getDateTime() -> Date { | ||
| currentDate | ||
| } |
| } | ||
|
|
||
| func setArDirectionEnabled(_ enabled: Bool) { | ||
| arDirectionEnabled = enabled |
There was a problem hiding this comment.
Could we avoid calling updateArrowIcon() when the value hasn't changed?
| } else { | ||
| color = StarMapControlTheme.foreground(active: active, nightMode: nightMode) | ||
| } | ||
| print(color, active, isHighlighted) |
| resetButton.updateTheme(nightmod: nightMode, active: active) | ||
|
|
||
| if pressed { | ||
| let pressedColorDay = UIColor(rgb: color_on_map_icon_background_color_tap_light).withAlphaComponent(StarMapControlTheme.defaultBackgroundAlpha) |
|
|
||
| if pressed { | ||
| let pressedColorDay = UIColor(rgb: color_on_map_icon_background_color_tap_light).withAlphaComponent(StarMapControlTheme.defaultBackgroundAlpha) | ||
| let pressedColorNight = UIColor(rgb: color_on_map_icon_background_color_tap_dark).withAlphaComponent(StarMapControlTheme.defaultBackgroundAlpha) |
| override func layoutSubviews() { | ||
| super.layoutSubviews() | ||
| guard bounds.width > 0, bounds.height > 0 else { return } | ||
| if #available(iOS 26.0, *) { |
| layer.shadowOpacity = 0.35 | ||
| layer.shadowRadius = 5 | ||
| layer.shadowOffset = CGSize(width: 0, height: 2) | ||
| layer.borderColor = UIColor(rgb: color_on_map_icon_border_color).cgColor |
- Add mapButtonBorderColor asset and migrate color constants to asset-based system - Make AstronomyPluginSettings and nested types Codable for simplified JSON serialization - Refactor DateTimeSelectionView to use properties instead of setter methods - Update UI components to use typed icon assets instead of string-based icon names - Simplify glass background management with weak view references - Standardize control card theme methods (add border and pressed background) - Remove redundant manual JSON parsing/serialization code
| return | ||
| } | ||
| UserDefaults.standard.set(string, forKey: Self.storageKey) | ||
| UserDefaults.standard.set(object: settings, forKey: storageKey) |
There was a problem hiding this comment.
This setting should be shared across platforms. Follow the Android implementation
|
|
||
| private func getMyDataInsertionOrderMap(_ quickPresetType: StarMapSearchQuickPresetType) -> [String: Int] { | ||
| let config = parentStarMapController?.searchStarMapConfig() ?? AstronomyPluginSettings.load().starMap | ||
| let config = parentStarMapController?.searchStarMapConfig() ?? plugin.astroSettings.getStarMapConfig() |
| .makeProfile() | ||
| .makeShared() | ||
|
|
||
| private let recentPref: OACommonString = OAAppSettings.sharedManager() |
There was a problem hiding this comment.
Is this also configured as .makeGlobal().makeShared() on Android?
There was a problem hiding this comment.
On Android, they are stored only in RAM, for a single session. On iOS, they need to be saved across sessions and shared among all profiles.
There was a problem hiding this comment.
Why does the logic differ from Android?
| let dataProvider: AstroDataDbProvider | ||
| @objc final class AstronomyPlugin: OAPlugin { | ||
| private enum PreferenceId { | ||
| static let settings = "astronomy_settings" |
There was a problem hiding this comment.
Handle Android legacy star_watcher_settings too. Android migrates it to astronomy_settings, and this key may exist in backup/cloud exports. Since this setting is now cross-platform, iOS should register star_watcher_settings as profile/shared and migrate its value to astronomy_settings when the new pref is empty.
…on iOS Register the legacy profile/shared preference so cloud and file backups can apply it, then copy into astronomy_settings only when the new pref is empty (after plugin init and profile import/sync).
| let hasProfileItems = items.contains { $0 is OAProfileSettingsItem } | ||
| if hasProfileItems, | ||
| let plugin = OAPluginsHelper.getPlugin(AstronomyPlugin.self) as? AstronomyPlugin { | ||
| plugin.migrateLegacyStarWatcherSettingsIfNeeded() |
There was a problem hiding this comment.
Why is migration needed here?
| .makeProfile() | ||
| .makeShared() | ||
|
|
||
| private let recentPref: OACommonString = OAAppSettings.sharedManager() |
There was a problem hiding this comment.
Why does the logic differ from Android?
| override init() { | ||
| super.init() | ||
| recentSearchChips = astronomySettingsStorage.getRecentChips() | ||
| migrateLegacyStarWatcherSettingsIfNeeded() |
There was a problem hiding this comment.
You are already performing the migration at startup
There was a problem hiding this comment.
removed from AstronomyPlugin.init
| private let legacySettingsPref: OACommonString = OAAppSettings.sharedManager() | ||
| .registerStringPreference(PreferenceId.legacySettings, defValue: "") | ||
| .makeProfile() | ||
| .makeShared() |
There was a problem hiding this comment.
Will this setting be included in the imported file? If so, .makeShared() should be removed
|
|
||
| private let recentPref: OACommonString = OAAppSettings.sharedManager() | ||
| .registerStringPreference(PreferenceId.recent, defValue: "") | ||
| .makeGlobal() |
| applyPillAppearance() | ||
| } | ||
|
|
||
| func setValue(_ text: String) { |
| layer.borderWidth = nightMode ? 2 : 0 | ||
| } | ||
|
|
||
| override func layoutSubviews() { |
| nav.navigationBar.prefersLargeTitles = true | ||
| searchNavigationController = nav | ||
|
|
||
| if UIDevice.current.userInterfaceIdiom == .pad { |
| let cameraSliderTopConstraint = sliderContainer.topAnchor.constraint(equalTo: cameraButton.bottomAnchor, constant: Layout.contentPadding) | ||
| cameraSliderTopConstraint.priority = .defaultHigh | ||
| addRoundButton(zoomOutButton, | ||
| iconName: "ic_custom_map_zoom_out", |
There was a problem hiding this comment.
Why not pass the icon from the asset catalog directly?
| setNeedsDisplay() | ||
| } | ||
|
|
||
| func getAltitude() -> Double { |
| return value | ||
| } | ||
|
|
||
| private func commonInit() { |
|
|
||
| @objc func showSearchDialog() { | ||
| @objc private func showSearchDialog() { | ||
| if UIDevice.current.userInterfaceIdiom == .pad, searchViewController != nil { |
No description provided.