diff --git a/Resources/en.lproj/Localizable.strings b/Resources/en.lproj/Localizable.strings index 05401c5a2c34678f8b0703922ee5c7c802ccdd63..dababc2b04e7cb8a9eb6a44d061eb48e1fd77e06 100644 --- a/Resources/en.lproj/Localizable.strings +++ b/Resources/en.lproj/Localizable.strings @@ -549,8 +549,6 @@ "FEEDBACK_EMAIL_NOT_POSSIBLE_TITLE" = "Mail account not configured"; "FEEDBACK_EMAIL_NOT_POSSIBLE_LONG" = "Contact us through %@ from another device."; -"SETTINGS_THEME_BLACK" = "Use black background on dark mode"; -"SETTINGS_THEME_BLACK_SUBTITLE" = "Improves battery life on devices with an OLED screen"; "SETTINGS_RESET_TITLE" = "Reset the settings"; "SETTINGS_RESET_MESSAGE" = "Do you want to reset all the settings to their default values?"; diff --git a/Resources/iOS/Settings.bundle/Root.inApp.plist b/Resources/iOS/Settings.bundle/Root.inApp.plist index 2172d720bdc9e792760ec9c5eef1515bdd12c97e..8ba36216e6d659228bd1f9425fa216a4edb55f9c 100644 --- a/Resources/iOS/Settings.bundle/Root.inApp.plist +++ b/Resources/iOS/Settings.bundle/Root.inApp.plist @@ -42,14 +42,12 @@ <string>SETTINGS_THEME_BRIGHT</string> <string>SETTINGS_THEME_DARK</string> <string>SETTINGS_THEME_SYSTEM</string> - <string>SETTINGS_THEME_BLACK</string> </array> <key>Values</key> <array> <integer>0</integer> <integer>1</integer> <integer>2</integer> - <string>3</string> </array> </dict> <dict> diff --git a/Sources/App/iOS/DefaultsChangeListener.swift b/Sources/App/iOS/DefaultsChangeListener.swift new file mode 100644 index 0000000000000000000000000000000000000000..e4da299607e1064ce6e963748e72921714b8c6d6 --- /dev/null +++ b/Sources/App/iOS/DefaultsChangeListener.swift @@ -0,0 +1,106 @@ +/***************************************************************************** + * DefaultsChangeListener.swift + * VLC for iOS + ***************************************************************************** + * Copyright (c) 2025 VideoLAN. All rights reserved. + * $Id$ + * + * Authors: Craig Reyenga <craig.reyenga # gmail.com> + * + * Refer to the COPYING file of the official project for license. + *****************************************************************************/ + +/// Emits notifications or performs other actions based on updates to user defaults. +@objc(VLCDefaultsChangeListener) +final class DefaultsChangeListener: NSObject { + private let appTheme: ChangeManager<Int> + private let appThemeBlack: ChangeManager<Int> + private let disableGrouping: ChangeManager<Bool> + private let hideMediaLibrary: ChangeManager<Bool> + private let excludeFromDeviceBackup: ChangeManager<Bool> + + @objc var mediaLibraryService: MediaLibraryService? + + override init() { + let notificationCenter = NotificationCenter.default + + appTheme = ChangeManager(value: Self.readAppTheme(), action: { _ in + PresentationTheme.themeDidUpdate() + }) + + appThemeBlack = ChangeManager(value: Self.readAppThemeBlack(), action: { _ in + PresentationTheme.themeDidUpdate() + }) + + disableGrouping = ChangeManager(value: Self.readDisableGrouping(), action: { _ in + notificationCenter.post(name: .VLCDisableGroupingDidChangeNotification, object: nil) + }) + + hideMediaLibrary = ChangeManager(value: Self.readHideMediaLibrary()) + + excludeFromDeviceBackup = ChangeManager(value: Self.readExcludeFromDeviceBackup()) + + super.init() + + notificationCenter.addObserver(self, + selector: #selector(userDefaultsUpdated), + name: UserDefaults.didChangeNotification, + object: nil) + + hideMediaLibrary.action = { [weak self] hide in + self?.mediaLibraryService?.hideMediaLibrary(hide) + } + + excludeFromDeviceBackup.action = { [weak self] exclude in + self?.mediaLibraryService?.excludeFromDeviceBackup(exclude) + } + } + + @objc private func userDefaultsUpdated() { + appTheme.update(Self.readAppTheme()) + appThemeBlack.update(Self.readAppThemeBlack()) + disableGrouping.update(Self.readDisableGrouping()) + hideMediaLibrary.update(Self.readHideMediaLibrary()) + excludeFromDeviceBackup.update(Self.readExcludeFromDeviceBackup()) + } + + static func readAppTheme() -> Int { + return UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) + } + + static func readAppThemeBlack() -> Int { + return UserDefaults.standard.integer(forKey: kVLCSettingAppThemeBlack) + } + + static func readDisableGrouping() -> Bool { + return UserDefaults.standard.bool(forKey: kVLCSettingsDisableGrouping) + } + + static func readHideMediaLibrary() -> Bool { + return UserDefaults.standard.bool(forKey: kVLCSettingHideLibraryInFilesApp) + } + + static func readExcludeFromDeviceBackup() -> Bool { + // The user interface setting is for *including* in a backup, but + // user defaults and the media library refer to *exclusion*. We perform + // the inversion right here to have everything match up. + return !UserDefaults.standard.bool(forKey: kVLCSettingBackupMediaLibrary) + } +} + +/// Executes an action when the underlying value has changed. +fileprivate final class ChangeManager<T: Equatable> { + var value: T + var action: ((T) -> Void)? + + init(value: T, action: ((T) -> Void)? = nil) { + self.value = value + self.action = action + } + + func update(_ newValue: T) { + guard value != newValue else { return } + value = newValue + action?(newValue) + } +} diff --git a/Sources/App/iOS/VLCAppCoordinator.m b/Sources/App/iOS/VLCAppCoordinator.m index 0b0b8c2d8ff2a3336bebf8de010521c9e267fbe7..9a0f8906dfc7ca26a91b75148eae8ed9189658c6 100644 --- a/Sources/App/iOS/VLCAppCoordinator.m +++ b/Sources/App/iOS/VLCAppCoordinator.m @@ -28,6 +28,7 @@ VLCRemoteControlService *_remoteControlService; UIWindow *_externalWindow; VLCStripeController *_stripeController; + VLCDefaultsChangeListener *_defaultsChangeListener; #if TARGET_OS_IOS VLCRendererDiscovererManager *_rendererDiscovererManager; @@ -54,6 +55,8 @@ { self = [super init]; if (self) { + _defaultsChangeListener = [[VLCDefaultsChangeListener alloc] init]; + dispatch_async(dispatch_get_main_queue(), ^{ [VLCLibrary setSharedEventsConfiguration:[VLCEventsLegacyConfiguration new]]; [self initializeServices]; @@ -71,6 +74,8 @@ // start the remote control service _remoteControlService = [[VLCRemoteControlService alloc] init]; + + _defaultsChangeListener.mediaLibraryService = self.mediaLibraryService; } - (MediaLibraryService *)mediaLibraryService diff --git a/Sources/Playback/Player/VideoPlayer-iOS/MediaMoreOptionsActionSheet.swift b/Sources/Playback/Player/VideoPlayer-iOS/MediaMoreOptionsActionSheet.swift index 0e587c057552d0f53bd163e6069453f39b12666d..9ab18d603bba5b622a2d49d614abeb9b4bd48f6c 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/MediaMoreOptionsActionSheet.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/MediaMoreOptionsActionSheet.swift @@ -486,8 +486,7 @@ extension MediaMoreOptionsActionSheet: MediaPlayerActionSheetDataSource { } // Do not display these options in the action sheet. - if $0 == .addBookmarks || $0 == .blackBackground || - $0 == .playNextItem || $0 == .playlistPlayNextItem { + if [ .addBookmarks, .playNextItem, .playlistPlayNextItem ].contains($0) { return } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/MediaPlayerActionSheet.swift b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/MediaPlayerActionSheet.swift index 9783bb165732e21f69c53aa936c54d61a8cb8e7c..21d043f20292be941e09bf9d78d5791ad8163b0c 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/MediaPlayerActionSheet.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/MediaPlayerActionSheet.swift @@ -22,7 +22,6 @@ enum ActionSheetCellIdentifier: String, CustomStringConvertible, CaseIterable { case addBookmarks case abRepeat case interfaceLock - case blackBackground case playNextItem case playlistPlayNextItem @@ -48,8 +47,6 @@ enum ActionSheetCellIdentifier: String, CustomStringConvertible, CaseIterable { return NSLocalizedString("REPEAT_MODE", comment: "") case .abRepeat: return NSLocalizedString("AB_LOOP", comment: "") - case .blackBackground: - return NSLocalizedString("SETTINGS_THEME_BLACK", comment: "") case .playNextItem: return NSLocalizedString("SETTINGS_PLAY_ALL", comment: "") case .playlistPlayNextItem: @@ -73,8 +70,6 @@ enum ActionSheetCellIdentifier: String, CustomStringConvertible, CaseIterable { return NSLocalizedString("BOOKMARKS_HINT", comment: "") case .interfaceLock: return NSLocalizedString("INTERFACE_LOCK_HINT", comment: "") - case .blackBackground: - return NSLocalizedString("SETTINGS_THEME_BLACK_SUBTITLE", comment: "") case .playNextItem: return NSLocalizedString("SETTINGS_PLAY_ALL_HINT", comment: "") case .playlistPlayNextItem: diff --git a/Sources/Settings/Controller/SettingsController.swift b/Sources/Settings/Controller/SettingsController.swift index bd9aa32be8d81aa9d54793aa073796afd6851f6c..287bd6baf17f89788c5385539cbc886387041de4 100644 --- a/Sources/Settings/Controller/SettingsController.swift +++ b/Sources/Settings/Controller/SettingsController.swift @@ -169,7 +169,14 @@ class SettingsController: UITableViewController { #if os(iOS) setNeedsStatusBarAppearanceUpdate() #endif - reloadSettingsSections() // When theme changes hide the black theme section if needed + + tableView.visibleCells.forEach { cell in + guard let cell = cell as? SettingsCell else { return } + + cell.themeChanged() + } + + reloadSettingsSections() } @objc private func miniPlayerIsShown() { @@ -432,12 +439,6 @@ extension SettingsController: SettingsCellDelegate { switch preferenceKey { case kVLCSettingPasscodeOnKey: passcodeLockSwitchOn(state: isOn) - case kVLCSettingHideLibraryInFilesApp: - medialibraryHidingLockSwitchOn(state: isOn) - case kVLCSettingBackupMediaLibrary: - mediaLibraryBackupActivateSwitchOn(state: isOn) - case kVLCSettingsDisableGrouping: - medialibraryDisableGroupingSwitchOn(state: isOn) default: break } @@ -488,30 +489,9 @@ extension SettingsController { } } -extension SettingsController { - func medialibraryHidingLockSwitchOn(state: Bool) { - mediaLibraryService.hideMediaLibrary(state) - } -} - -extension SettingsController { - func mediaLibraryBackupActivateSwitchOn(state: Bool) { - mediaLibraryService.excludeFromDeviceBackup(state) - } -} - -extension SettingsController { - func medialibraryDisableGroupingSwitchOn(state _: Bool) { - notificationCenter.post(name: .VLCDisableGroupingDidChangeNotification, object: self) - } -} - extension SettingsController: ActionSheetSpecifierDelegate { func actionSheetSpecifierHandleToggleSwitch(for cell: ActionSheetCell, state: Bool) { switch cell.identifier { - case .blackBackground: - userDefaults.setValue(state, forKey: kVLCSettingAppThemeBlack) - PresentationTheme.themeDidUpdate() case .playNextItem: userDefaults.setValue(state, forKey: kVLCAutomaticallyPlayNextItem) case .playlistPlayNextItem: diff --git a/Sources/Settings/Model/ActionSheetSpecifier.swift b/Sources/Settings/Model/ActionSheetSpecifier.swift index ed4e4db9fa7f3b67273604649b6713ac07330b60..1b6c16b77a8a1a3bcf956b7c397668cb45e2a7a3 100644 --- a/Sources/Settings/Model/ActionSheetSpecifier.swift +++ b/Sources/Settings/Model/ActionSheetSpecifier.swift @@ -60,12 +60,6 @@ extension ActionSheetSpecifier: ActionSheetDelegate { return } - guard preferenceKey != kVLCSettingAppTheme || - (!PresentationTheme.current.isDark || indexPath.row != numberOfRows() - 1) else { - // Disable the selection for the black background option cell in the appearance action sheet - return - } - guard preferenceKey != kVLCAutomaticallyPlayNextItem else { // Disable the selection for the automatically play next item options return @@ -73,10 +67,6 @@ extension ActionSheetSpecifier: ActionSheetDelegate { userDefaults.set(settingSpecifier?.specifier[indexPath.row].value, forKey: preferenceKey) - if preferenceKey == kVLCSettingAppTheme { - PresentationTheme.themeDidUpdate() - } - #if os(iOS) NotificationFeedbackGenerator().success() #endif @@ -106,15 +96,6 @@ extension ActionSheetSpecifier: ActionSheetDataSource { return 0 } - if preferenceKey == kVLCSettingAppTheme { - let isThemeDark: Bool = PresentationTheme.current.isDark - if #available(iOS 13, *) { - return isThemeDark ? rowCount : rowCount - 1 - } else { - return isThemeDark ? rowCount - 1 : rowCount - 2 - } - } - return rowCount } @@ -128,20 +109,7 @@ extension ActionSheetSpecifier: ActionSheetDataSource { return UICollectionViewCell() } - if preferenceKey == kVLCSettingAppTheme && - PresentationTheme.current.isDark && indexPath.row == numberOfRows() - 1 { - // Update the black background option cell - cell.setAccessoryType(to: .toggleSwitch) - cell.setToggleSwitch(state: UserDefaults.standard.bool(forKey: kVLCSettingAppThemeBlack)) - cell.name.text = settingsBundle.localizedString(forKey: "SETTINGS_THEME_BLACK", value: "", table: "Root") - let cellIdentifier = ActionSheetCellIdentifier.blackBackground - cell.identifier = cellIdentifier - cell.name.accessibilityLabel = cellIdentifier.description - cell.name.accessibilityHint = cellIdentifier.accessibilityHint - cell.delegate = self - - return cell - } else if preferenceKey == kVLCAutomaticallyPlayNextItem { + if preferenceKey == kVLCAutomaticallyPlayNextItem { cell.setAccessoryType(to: .toggleSwitch) let isFirstRow: Bool = indexPath.row == 0 diff --git a/Sources/Settings/Model/SettingsSection.swift b/Sources/Settings/Model/SettingsSection.swift index a7b6ffbe598ddc6c2906c0d78aae9d2ab5a88f9c..c0c76f41edf42e2ff8b8f47601e01282b8a8000d 100644 --- a/Sources/Settings/Model/SettingsSection.swift +++ b/Sources/Settings/Model/SettingsSection.swift @@ -23,6 +23,7 @@ struct SettingsItem: Equatable { let title: String let subtitle: String? let action: Action + let isEnabled: Bool let isTitleEmphasized: Bool @available(*, deprecated, message: "access from self.action") @@ -37,15 +38,16 @@ struct SettingsItem: Equatable { } } - init(title: String, subtitle: String?, action: Action, isTitleEmphasized: Bool = false) { + init(title: String, subtitle: String?, action: Action, isEnabled: Bool = true, isTitleEmphasized: Bool = false) { self.title = Localizer.localizedTitle(key: title) self.subtitle = subtitle.flatMap(Localizer.localizedTitle(key:)) self.action = action + self.isEnabled = isEnabled self.isTitleEmphasized = isTitleEmphasized } - static func toggle(title: String, subtitle: String?, preferenceKey: String) -> Self { - return Self(title: title, subtitle: subtitle, action: .toggle(Toggle(preferenceKey: preferenceKey))) + static func toggle(title: String, subtitle: String? = nil, preferenceKey: String, isEnabled: Bool = true) -> Self { + return Self(title: title, subtitle: subtitle, action: .toggle(Toggle(preferenceKey: preferenceKey)), isEnabled: isEnabled) } enum Action: Equatable { @@ -176,10 +178,18 @@ enum MainOptions { action: .showActionSheet(title: "SETTINGS_DARKTHEME", preferenceKey: k, hasInfo: false)) } + static var blackTheme: SettingsItem { + .toggle(title: "SETTINGS_THEME_BLACK", + subtitle: "SETTINGS_THEME_BLACK_SUBTITLE", + preferenceKey: kVLCSettingAppThemeBlack, + isEnabled: UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) != kVLCSettingAppThemeBright) + } + static func section() -> SettingsSection? { .init(title: nil, items: [ privacy, appearance, + blackTheme ]) } } @@ -217,7 +227,6 @@ enum GenericOptions { static var playVideoInFullScreen: SettingsItem { .toggle(title: "SETTINGS_VIDEO_FULLSCREEN", - subtitle: nil, preferenceKey: kVLCSettingVideoFullscreenPlayback) } @@ -237,19 +246,16 @@ enum GenericOptions { static var enableTextScrollingInMediaList: SettingsItem { .toggle(title: "SETTINGS_ENABLE_MEDIA_CELL_TEXT_SCROLLING", - subtitle: nil, preferenceKey: kVLCSettingEnableMediaCellTextScrolling) } static var rememberPlayerState: SettingsItem { .toggle(title: "SETTINGS_REMEMBER_PLAYER_STATE", - subtitle: nil, preferenceKey: kVLCPlayerShouldRememberState) } static var restoreLastPlayedMedia: SettingsItem { .toggle(title: "SETTINGS_RESTORE_LAST_PLAYED_MEDIA", - subtitle: nil, preferenceKey: kVLCRestoreLastPlayedMedia) } @@ -323,43 +329,36 @@ enum PrivacyOptions { enum GestureControlOptions { static var swipeUpDownForVolume: SettingsItem { .toggle(title: "SETTINGS_GESTURES_VOLUME", - subtitle: nil, preferenceKey: kVLCSettingVolumeGesture) } static var twoFingerTap: SettingsItem { .toggle(title: "SETTINGS_GESTURES_PLAYPAUSE", - subtitle: nil, preferenceKey: kVLCSettingPlayPauseGesture) } static var swipeUpDownForBrightness: SettingsItem { .toggle(title: "SETTINGS_GESTURES_BRIGHTNESS", - subtitle: nil, preferenceKey: kVLCSettingBrightnessGesture) } static var swipeRightLeftToSeek: SettingsItem { .toggle(title: "SETTINGS_GESTURES_SEEK", - subtitle: nil, preferenceKey: kVLCSettingSeekGesture) } static var pinchToClose: SettingsItem { .toggle(title: "SETTINGS_GESTURES_CLOSE", - subtitle: nil, preferenceKey: kVLCSettingCloseGesture) } static var forwardBackwardEqual: SettingsItem { .toggle(title: "SETTINGS_GESTURES_FORWARD_BACKWARD_EQUAL", - subtitle: nil, preferenceKey: kVLCSettingPlaybackForwardBackwardEqual) } static var tapSwipeEqual: SettingsItem { .toggle(title: "SETTINGS_GESTURES_TAP_SWIPE_EQUAL", - subtitle: nil, preferenceKey: kVLCSettingPlaybackTapSwipeEqual) } @@ -393,7 +392,6 @@ enum GestureControlOptions { static var longTouchToSpeedUp: SettingsItem { .toggle(title: "SETINGS_LONG_TOUCH_SPEED_UP", - subtitle: nil, preferenceKey: kVLCSettingPlaybackLongTouchSpeedUp) } @@ -492,13 +490,11 @@ enum VideoOptions { static var rememberPlayerBrightness: SettingsItem { .toggle(title: "SETTINGS_REMEMBER_PLAYER_BRIGHTNESS", - subtitle: nil, preferenceKey: kVLCPlayerShouldRememberBrightness) } static var lockRotation: SettingsItem { .toggle(title: "SETTINGS_LOCK_ROTATION", - subtitle: nil, preferenceKey: kVLCSettingRotationLock) } @@ -538,7 +534,6 @@ enum SubtitlesOptions { static var useBoldFont: SettingsItem { .toggle(title: "SETTINGS_SUBTITLES_BOLDFONT", - subtitle: nil, preferenceKey: kVLCSettingSubtitlesBoldFont) } @@ -610,7 +605,6 @@ enum AudioOptions { static var audioPlaybackInBackground: SettingsItem { .toggle(title: "SETTINGS_BACKGROUND_AUDIO", - subtitle: nil, preferenceKey: kVLCSettingContinueAudioInBackgroundKey) } @@ -635,31 +629,26 @@ enum MediaLibraryOptions { static var optimiseItemNamesForDisplay: SettingsItem { .toggle(title: "SETTINGS_DECRAPIFY", - subtitle: nil, preferenceKey: kVLCSettingsDecrapifyTitles) } static var disableGrouping: SettingsItem { .toggle(title: "SETTINGS_DISABLE_GROUPING", - subtitle: nil, preferenceKey: kVLCSettingsDisableGrouping) } static var showVideoThumbnails: SettingsItem { .toggle(title: "SETTINGS_SHOW_THUMBNAILS", - subtitle: nil, preferenceKey: kVLCSettingShowThumbnails) } static var showAudioArtworks: SettingsItem { .toggle(title: "SETTINGS_SHOW_ARTWORKS", - subtitle: nil, preferenceKey: kVLCSettingShowArtworks) } static var includeMediaLibInDeviceBackup: SettingsItem { .toggle(title: "SETTINGS_BACKUP_MEDIA_LIBRARY", - subtitle: nil, preferenceKey: kVLCSettingBackupMediaLibrary) } @@ -698,7 +687,6 @@ enum NetworkOptions { static var ipv6SupportForWiFiSharing: SettingsItem { .toggle(title: "SETTINGS_WIFISHARING_IPv6", - subtitle: nil, preferenceKey: kVLCSettingWiFiSharingIPv6) } @@ -710,7 +698,6 @@ enum NetworkOptions { static var rtspctp: SettingsItem { .toggle(title: "SETTINGS_RTSP_TCP", - subtitle: nil, preferenceKey: kVLCSettingNetworkRTSPTCP) } @@ -736,7 +723,6 @@ enum Accessibility { static var pauseWhenShowingControls: SettingsItem { .toggle(title: "SETTINGS_PAUSE_WHEN_SHOWING_CONTROLS", - subtitle: nil, preferenceKey: kVLCSettingPauseWhenShowingControls) } @@ -753,7 +739,6 @@ enum Accessibility { enum Lab { static var debugLogging: SettingsItem { .toggle(title: "SETTINGS_DEBUG_LOG", - subtitle: nil, preferenceKey: kVLCSaveDebugLogs) } diff --git a/Sources/Settings/View/SettingsCell.swift b/Sources/Settings/View/SettingsCell.swift index 0f9a69edc21716f0a46359fadf41f10d97a63945..a529bacec27d1153897ed6773836047a3a87e71a 100644 --- a/Sources/Settings/View/SettingsCell.swift +++ b/Sources/Settings/View/SettingsCell.swift @@ -15,6 +15,7 @@ protocol SettingsCellDelegate: AnyObject { /// Implementations should only perform side effects on /// specific preferences; updating the preference itself /// is handled by the cell. + @available(*, deprecated, message: "Side effects of toggling a setting should be performed by observing changes to userdefaults") func settingsCellDidChangeSwitchState(cell: SettingsCell, preferenceKey: String, isOn: Bool) func settingsCellInfoButtonPressed(cell: SettingsCell, preferenceKey: String) @@ -30,6 +31,7 @@ class SettingsCell: UITableViewCell { static let marginBottom: CGFloat = 10 static let marginLeading: CGFloat = 20 static let marginTrailing: CGFloat = 70 + static let disabledAlpha: CGFloat = 0.3 } weak var delegate: SettingsCellDelegate? @@ -208,6 +210,15 @@ class SettingsCell: UITableViewCell { } else { activityIndicator.stopAnimating() } + + if settingsItem.isEnabled { + switchControl.isEnabled = true + contentView.alpha = 1 + } else { + switchControl.isEnabled = false + contentView.alpha = Constants.disabledAlpha + } + } } @@ -221,6 +232,10 @@ class SettingsCell: UITableViewCell { fatalError("init(coder:) has not been implemented") } + func themeChanged() { + setupTheme() + } + override func prepareForReuse() { super.prepareForReuse() backgroundColor = .clear // Required to prevent theme mismatch during setupTheme diff --git a/Sources/UI Elements/PresentationTheme.swift b/Sources/UI Elements/PresentationTheme.swift index 10585824d615117d0918763f826bdb617a6c728d..7fa2e8c3391a897b053cfec580511da8c2aa141b 100644 --- a/Sources/UI Elements/PresentationTheme.swift +++ b/Sources/UI Elements/PresentationTheme.swift @@ -43,27 +43,27 @@ extension Notification.Name { let thumbnailBackgroundColor: UIColor init(isDark: Bool, - name: String, - statusBarStyle: UIStatusBarStyle, - navigationbarColor: UIColor, - navigationbarTextColor: UIColor, - background: UIColor, - cellBackgroundA: UIColor, - cellBackgroundB: UIColor, - cellDetailTextColor: UIColor, - cellTextColor: UIColor, - lightTextColor: UIColor, - sectionHeaderTextColor: UIColor, - separatorColor: UIColor, - mediaCategorySeparatorColor: UIColor, - tabBarColor: UIColor, - orangeUI: UIColor, - orangeDarkAccent: UIColor, - toolBarStyle: UIBarStyle, - blurStyle: UIBlurEffect.Style, - textfieldBorderColor: UIColor, - textfieldPlaceholderColor: UIColor, - thumbnailBackgroundColor: UIColor) { + name: String, + statusBarStyle: UIStatusBarStyle, + navigationbarColor: UIColor, + navigationbarTextColor: UIColor, + background: UIColor, + cellBackgroundA: UIColor, + cellBackgroundB: UIColor, + cellDetailTextColor: UIColor, + cellTextColor: UIColor, + lightTextColor: UIColor, + sectionHeaderTextColor: UIColor, + separatorColor: UIColor, + mediaCategorySeparatorColor: UIColor, + tabBarColor: UIColor, + orangeUI: UIColor, + orangeDarkAccent: UIColor, + toolBarStyle: UIBarStyle, + blurStyle: UIBlurEffect.Style, + textfieldBorderColor: UIColor, + textfieldPlaceholderColor: UIColor, + thumbnailBackgroundColor: UIColor) { self.isDark = isDark self.name = name self.statusBarStyle = statusBarStyle @@ -89,6 +89,8 @@ extension Notification.Name { } } +// MARK: - Typography + @objcMembers class Typography: NSObject { let tableHeaderFont: UIFont @@ -106,6 +108,8 @@ enum PresentationThemeType: Int { case auto } +// MARK: - PresentationTheme + @objcMembers class PresentationTheme: NSObject { static let brightTheme = PresentationTheme(colors: brightPalette) @@ -182,6 +186,8 @@ enum PresentationThemeType: Int { let font = defaultFont } +// MARK: - UIColor + @objc extension UIColor { convenience init(_ rgbValue: UInt32, _ alpha: CGFloat = 1.0) { diff --git a/VLC.xcodeproj/project.pbxproj b/VLC.xcodeproj/project.pbxproj index 4f743280f4f004331d3647178a63a614cc99cd41..ee52f64ec0a9eead2951ccd6faa8e421dc91cb3f 100644 --- a/VLC.xcodeproj/project.pbxproj +++ b/VLC.xcodeproj/project.pbxproj @@ -96,6 +96,8 @@ 444E5BFA24C6081B0003B69C /* PasscodeLockController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444E5BF924C6081A0003B69C /* PasscodeLockController.swift */; }; 444E5C0024C719480003B69C /* AboutController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444E5BFF24C719480003B69C /* AboutController.swift */; }; 44B5822024E434FD001A2583 /* MediaGridCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44B5821F24E434FD001A2583 /* MediaGridCollectionCell.swift */; }; + 44BA0BD62D80CF4D004CF52E /* DefaultsChangeListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44BA0BD52D80CF20004CF52E /* DefaultsChangeListener.swift */; }; + 44BA0BD72D80CF4D004CF52E /* DefaultsChangeListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44BA0BD52D80CF20004CF52E /* DefaultsChangeListener.swift */; }; 44C8BBA324AF2B5C003F8940 /* FeedbackGenerators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBA224AF2B5C003F8940 /* FeedbackGenerators.swift */; }; 44C8BBAE24AF36F4003F8940 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBA624AF36F4003F8940 /* SettingsController.swift */; }; 44C8BBAF24AF36F4003F8940 /* SettingsSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBA824AF36F4003F8940 /* SettingsSection.swift */; }; @@ -1013,6 +1015,7 @@ 444E5BF924C6081A0003B69C /* PasscodeLockController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeLockController.swift; sourceTree = "<group>"; }; 444E5BFF24C719480003B69C /* AboutController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutController.swift; sourceTree = "<group>"; }; 44B5821F24E434FD001A2583 /* MediaGridCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaGridCollectionCell.swift; sourceTree = "<group>"; }; + 44BA0BD52D80CF20004CF52E /* DefaultsChangeListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultsChangeListener.swift; sourceTree = "<group>"; }; 44C8BBA224AF2B5C003F8940 /* FeedbackGenerators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbackGenerators.swift; sourceTree = "<group>"; }; 44C8BBA624AF36F4003F8940 /* SettingsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; }; 44C8BBA824AF36F4003F8940 /* SettingsSection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsSection.swift; sourceTree = "<group>"; }; @@ -3100,6 +3103,7 @@ 418B144C20179C74000447AA /* TabBarCoordinator.swift */, 8F9108342A67AC76007EB0D5 /* SirikitIntentCoordinator.swift */, 91562F582CAEBC1500D42986 /* PlayMediaIntent.swift */, + 44BA0BD52D80CF20004CF52E /* DefaultsChangeListener.swift */, ); path = iOS; sourceTree = "<group>"; @@ -4444,6 +4448,7 @@ 7D50C6902BBD20DF00B9F1A0 /* VLCLocalNetworkServiceNetService.m in Sources */, 7D274D582D2AE81C00ADDC41 /* LongPressPlaybackSpeedView.swift in Sources */, 7D50C6912BBD20DF00B9F1A0 /* VLCPlexWebAPI.m in Sources */, + 44BA0BD72D80CF4D004CF52E /* DefaultsChangeListener.swift in Sources */, 7D50C6922BBD20DF00B9F1A0 /* VLCDonationNagScreenViewController.m in Sources */, 7D50C6932BBD20DF00B9F1A0 /* ButtonBarView.swift in Sources */, 7D50C6942BBD20DF00B9F1A0 /* MediaPlayerActionSheet.swift in Sources */, @@ -4641,6 +4646,7 @@ DD3EFF411BDEBCE500B68579 /* VLCNetworkServerBrowserSharedLibrary.m in Sources */, 7DC1865A2A0BB0C3009E84E1 /* UIImage+Gradient.swift in Sources */, 8D15A1F022B0FB9300CFA758 /* QueueViewController.swift in Sources */, + 44BA0BD62D80CF4D004CF52E /* DefaultsChangeListener.swift in Sources */, D96C9EBC28105F5B005F13BB /* AlbumHeader.swift in Sources */, 418E88412110E51B00DDA6A7 /* URLHandler.swift in Sources */, 8DE187812105DAB100A091D2 /* VideoViewController.swift in Sources */,