diff --git a/Resources/iOS/Settings.bundle/Root.inApp.plist b/Resources/iOS/Settings.bundle/Root.inApp.plist index 2172d720bdc9e792760ec9c5eef1515bdd12c97e..614adcb10f39b525764739219eb10f5722defdc8 100644 --- a/Resources/iOS/Settings.bundle/Root.inApp.plist +++ b/Resources/iOS/Settings.bundle/Root.inApp.plist @@ -49,7 +49,7 @@ <integer>0</integer> <integer>1</integer> <integer>2</integer> - <string>3</string> + <integer>3</integer> </array> </dict> <dict> @@ -163,6 +163,8 @@ <string>SETTINGS_NETWORK_PLAY_ALL</string> <key>Type</key> <string>PSMultiValueSpecifier</string> + <key>DefaultValue</key> + <false/> <key>Titles</key> <array> <string>SETTINGS_PLAY_ALL</string> @@ -170,8 +172,8 @@ </array> <key>Values</key> <array> - <integer>0</integer> - <integer>1</integer> + <false/> + <true/> </array> </dict> <dict> @@ -522,7 +524,7 @@ <key>Key</key> <string>avcodec-skiploopfilter</string> <key>DefaultValue</key> - <string>1</string> + <integer>1</integer> <key>Titles</key> <array> <string>SETTINGS_SKIP_LOOP_FILTER_NONE</string> @@ -557,7 +559,7 @@ <array> <integer>1</integer> <integer>0</integer> - <string>-1</string> + <integer>-1</integer> </array> </dict> <dict> diff --git a/Sources/About/AboutController.swift b/Sources/About/AboutController.swift index 3072c947a70891d2b15edb843657bfd5cccbac9f..8175dcec6399fba71dd1e381f30b2d86e58dbf37 100644 --- a/Sources/About/AboutController.swift +++ b/Sources/About/AboutController.swift @@ -181,9 +181,26 @@ class AboutController: UIViewController, MFMailComposeViewControllerDelegate, UI func generateFeedbackEmailPrefill() -> String { let bundleShortVersionString = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String let device = UIDevice.current - let defaults = UserDefaults.standard let locale = NSLocale.autoupdatingCurrent - let prefilledFeedback = String(format: "\n\n\n----------------------------------------\n%@\nDevice: %@\nOS: %@ - %@\nLocale: %@ (%@)\nVLC app version: %@\nlibvlc version: %@\nhardware decoding: %i\nnetwork caching level: %i\nskip loop filter: %i\nRTSP over TCP: %i\nAudio time stretching: %i", + let defaults = VLCDefaults.shared + let messageFormat = """ + + + + ---------------------------------------- + %@ + Device: %@ + OS: %@ - %@ + Locale: %@ (%@) + VLC app version: %@ + libvlc version: %@ + hardware decoding: %@ + network caching level: %i + skip loop filter: %i + RTSP over TCP: %i + Audio time stretching: %i + """ + let prefilledFeedback = String(format: messageFormat, NSLocalizedString("FEEDBACK_EMAIL_BODY", comment: ""), generateDeviceIdentifier(), device.systemName, @@ -192,11 +209,11 @@ class AboutController: UIViewController, MFMailComposeViewControllerDelegate, UI locale.regionCode!, bundleShortVersionString, VLCLibrary.shared().changeset, - defaults.integer(forKey: kVLCSettingHardwareDecoding), - defaults.integer(forKey: kVLCSettingNetworkCaching), - defaults.integer(forKey: kVLCSettingSkipLoopFilter), - defaults.integer(forKey: kVLCSettingNetworkRTSPTCP), - defaults.integer(forKey: kVLCSettingStretchAudio)) + defaults.hardwareDecoding.description, + defaults.networkCaching.rawValue, + defaults.skipLoopFilter.rawValue, + defaults.networkRTSPTCP ? 1 : 0, + defaults.stretchAudio ? 1 : 0) return prefilledFeedback } diff --git a/Sources/App/iOS/TabBarCoordinator.swift b/Sources/App/iOS/TabBarCoordinator.swift index 83047c4df765d094a473d3e4f6603b08151473fe..b956f1bc0167fd3049bd59a59a14ce155e96010d 100644 --- a/Sources/App/iOS/TabBarCoordinator.swift +++ b/Sources/App/iOS/TabBarCoordinator.swift @@ -50,7 +50,7 @@ class TabBarCoordinator: NSObject { ] tabBarController.viewControllers = controllers.map { UINavigationController(rootViewController: $0) } - tabBarController.selectedIndex = UserDefaults.standard.integer(forKey: kVLCTabBarIndex) + tabBarController.selectedIndex = VLCDefaults.shared.tabBarIndex } func setupEditToolbar() { @@ -162,6 +162,6 @@ class TabBarCoordinator: NSObject { extension TabBarCoordinator: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { let viewControllerIndex: Int = tabBarController.viewControllers?.firstIndex(of: viewController) ?? 0 - UserDefaults.standard.set(viewControllerIndex, forKey: kVLCTabBarIndex) + VLCDefaults.shared.tabBarIndex = viewControllerIndex } } diff --git a/Sources/App/iOS/VLCAppDelegate.m b/Sources/App/iOS/VLCAppDelegate.m index d054b695fd72d1b4ac34b8c41ffefe250e623e0b..5d359783e7783168c7c3ad6a7f88bea0a56c155b 100644 --- a/Sources/App/iOS/VLCAppDelegate.m +++ b/Sources/App/iOS/VLCAppDelegate.m @@ -35,75 +35,7 @@ + (void)initialize { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSUInteger appThemeIndex = kVLCSettingAppThemeBright; - if (@available(iOS 13.0, *)) { - appThemeIndex = kVLCSettingAppThemeSystem; - } - - NSDictionary *appDefaults = @{kVLCSettingAppTheme : @(appThemeIndex), - kVLCSettingPasscodeEnableBiometricAuth : @(1), - kVLCSettingContinueAudioInBackgroundKey : @(YES), - kVLCSettingStretchAudio : @(YES), - kVLCSettingDefaultPreampLevel : @(6), - kVLCSettingTextEncoding : kVLCSettingTextEncodingDefaultValue, - kVLCSettingSkipLoopFilter : kVLCSettingSkipLoopFilterNonRef, - kVLCSettingSubtitlesFont : kVLCSettingSubtitlesFontDefaultValue, - kVLCSettingSubtitlesFontColor : kVLCSettingSubtitlesFontColorDefaultValue, - kVLCSettingSubtitlesFontSize : kVLCSettingSubtitlesFontSizeDefaultValue, - kVLCSettingSubtitlesBoldFont: kVLCSettingSubtitlesBoldFontDefaultValue, - kVLCSettingDeinterlace : kVLCSettingDeinterlaceDefaultValue, - kVLCSettingHardwareDecoding : kVLCSettingHardwareDecodingDefault, - kVLCSettingNetworkCaching : kVLCSettingNetworkCachingDefaultValue, - kVLCSettingVolumeGesture : @(YES), - kVLCSettingPlayPauseGesture : @(YES), - kVLCSettingBrightnessGesture : @(YES), - kVLCSettingSeekGesture : @(YES), - kVLCSettingCloseGesture : @(YES), - kVLCSettingPlaybackLongTouchSpeedUp : @(YES), - kVLCSettingVideoFullscreenPlayback : @(YES), - kVLCSettingContinuePlayback : @(1), - kVLCSettingContinueAudioPlayback : @(1), - kVLCSettingWiFiSharingIPv6 : kVLCSettingWiFiSharingIPv6DefaultValue, - kVLCSettingNetworkRTSPTCP : @(NO), - kVLCSettingNetworkSatIPChannelListUrl : @"", - kVLCSettingEqualizerProfile : kVLCSettingEqualizerProfileDefaultValue, - kVLCSettingEqualizerProfileDisabled : @(YES), - kVLCSettingPlaybackForwardBackwardEqual: @(YES), - kVLCSettingPlaybackTapSwipeEqual: @(YES), - kVLCSettingPlaybackForwardSkipLength : kVLCSettingPlaybackForwardSkipLengthDefaultValue, - kVLCSettingPlaybackBackwardSkipLength : kVLCSettingPlaybackBackwardSkipLengthDefaultValue, - kVLCSettingPlaybackForwardSkipLengthSwipe : kVLCSettingPlaybackForwardSkipLengthSwipeDefaultValue, - kVLCSettingPlaybackBackwardSkipLengthSwipe : kVLCSettingPlaybackBackwardSkipLengthSwipeDefaultValue, - kVLCSettingPlaybackLockscreenSkip : @(NO), - kVLCSettingPlaybackRemoteControlSkip : @(NO), - kVLCSettingOpenAppForPlayback : kVLCSettingOpenAppForPlaybackDefaultValue, - kVLCAutomaticallyPlayNextItem : @(YES), - kVLCPlaylistPlayNextItem: @(YES), - kVLCSettingEnableMediaCellTextScrolling : @(NO), - kVLCSettingShowThumbnails : kVLCSettingShowThumbnailsDefaultValue, - kVLCSettingShowArtworks : kVLCSettingShowArtworksDefaultValue, - kVLCSettingBackupMediaLibrary : kVLCSettingBackupMediaLibraryDefaultValue, - kVLCSettingCastingAudioPassthrough : @(NO), - kVLCSettingCastingConversionQuality : @(2), - kVLCForceSMBV1 : @(YES), - @"kVLCAudioLibraryGridLayoutALBUMS" : @(YES), - @"kVLCAudioLibraryGridLayoutARTISTS" : @(YES), - @"kVLCAudioLibraryGridLayoutGENRES" : @(YES), - @"kVLCVideoLibraryGridLayoutALL_VIDEOS" : @(YES), - @"kVLCVideoLibraryGridLayoutVIDEO_GROUPS" : @(YES), - @"kVLCVideoLibraryGridLayoutVLCMLMediaGroupCollections" : @(YES), - kVLCPlayerShouldRememberState: @(YES), - kVLCPlayerIsShuffleEnabled: kVLCPlayerIsShuffleEnabledDefaultValue, - kVLCPlayerIsRepeatEnabled: kVLCPlayerIsRepeatEnabledDefaultValue, - kVLCSettingPlaybackSpeedDefaultValue: @(1.0), - kVLCPlayerShowPlaybackSpeedShortcut: @(NO), - kVLCSettingAlwaysPlayURLs: @(NO), - kVLCRestoreLastPlayedMedia: @(YES), - kVLCSettingPlayerControlDuration: kVLCSettingPlayerControlDurationDefaultValue, - kVLCSettingPauseWhenShowingControls: @(NO) - }; - [defaults registerDefaults:appDefaults]; + [VLCDefaults.shared registerDefaults]; } - (void)setupTabBarAppearance @@ -163,8 +95,7 @@ [self configureShortCutItemsWithApplication:application]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - [defaults setInteger:([defaults integerForKey:kVLCNumberOfLaunches] + 1) forKey:kVLCNumberOfLaunches]; + [VLCDefaults.shared incrementNumberOfLaunches]; return YES; } @@ -277,7 +208,7 @@ { if ([[VLCKeychainCoordinator passcodeService] hasSecret]) { //TODO: Dismiss playback - BOOL allowBiometricAuthentication = [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingPasscodeEnableBiometricAuth]; + BOOL allowBiometricAuthentication = VLCDefaults.shared.passcodeEnableBiometricAuth; [[VLCKeychainCoordinator passcodeService] validateSecretWithAllowBiometricAuthentication:allowBiometricAuthentication @@ -332,7 +263,7 @@ - (void)recoverLastPlayingMedia { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if (![defaults boolForKey:kVLCRestoreLastPlayedMedia]) { + if (!VLCDefaults.shared.restoreLastPlayedMedia) { return; } diff --git a/Sources/App/tvOS/AppleTVAppDelegate.m b/Sources/App/tvOS/AppleTVAppDelegate.m index 4502514633e16a6eea701196e089fb459ff36b40..6aa2f8046059c23c7962042235d7f566418f5288 100644 --- a/Sources/App/tvOS/AppleTVAppDelegate.m +++ b/Sources/App/tvOS/AppleTVAppDelegate.m @@ -38,37 +38,7 @@ + (void)initialize { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - - NSDictionary *appDefaults = @{kVLCSettingContinueAudioInBackgroundKey : @(YES), - kVLCSettingStretchAudio : @(YES), - kVLCSettingDefaultPreampLevel : @(6), - kVLCSettingTextEncoding : kVLCSettingTextEncodingDefaultValue, - kVLCSettingSkipLoopFilter : kVLCSettingSkipLoopFilterNonRef, - kVLCSettingSubtitlesFont : kVLCSettingSubtitlesFontDefaultValue, - kVLCSettingSubtitlesFontColor : kVLCSettingSubtitlesFontColorDefaultValue, - kVLCSettingSubtitlesFontSize : kVLCSettingSubtitlesFontSizeDefaultValue, - kVLCSettingSubtitlesBoldFont: kVLCSettingSubtitlesBoldFontDefaultValue, - kVLCSettingDeinterlace : kVLCSettingDeinterlaceDefaultValue, - kVLCSettingHardwareDecoding : kVLCSettingHardwareDecodingDefault, - kVLCSettingNetworkCaching : kVLCSettingNetworkCachingDefaultValue, - kVLCSettingNetworkRTSPTCP : @(NO), - kVLCSettingNetworkSatIPChannelListUrl : @"", - kVLCSettingEqualizerProfileDisabled : @(YES), - kVLCSettingEqualizerProfile : kVLCSettingEqualizerProfileDefaultValue, - kVLCSettingPlaybackForwardSkipLength : kVLCSettingPlaybackForwardSkipLengthDefaultValue, - kVLCSettingPlaybackBackwardSkipLength : kVLCSettingPlaybackBackwardSkipLengthDefaultValue, - kVLCSettingPlaybackLockscreenSkip : @(NO), - kVLCSettingPlaybackRemoteControlSkip : @(NO), - kVLCSettingWiFiSharingIPv6 : kVLCSettingWiFiSharingIPv6DefaultValue, - kVLCAutomaticallyPlayNextItem : @(YES), - kVLCPlayerShouldRememberState: @(YES), - kVLCPlayerUIShouldHide : @(NO), - kVLCSettingDownloadArtwork : @(YES), - kVLCForceSMBV1 : @(YES), - kVLCSettingBackupMediaLibrary : kVLCSettingBackupMediaLibraryDefaultValue, - kVLCSettingPlaybackSpeedDefaultValue: @(1.0)}; - [defaults registerDefaults:appDefaults]; + [VLCDefaults.shared registerDefaults]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions diff --git a/Sources/CarPlay/VLCCarPlayArtistsController.m b/Sources/CarPlay/VLCCarPlayArtistsController.m index 4a21decea2485f391af3b58cd262945c1624573d..191325aa39b0f4d2c2ff4216cb513997d35a2045 100644 --- a/Sources/CarPlay/VLCCarPlayArtistsController.m +++ b/Sources/CarPlay/VLCCarPlayArtistsController.m @@ -66,7 +66,7 @@ - (NSArray *)listOfArtists { - BOOL hideFeatArtists = [[NSUserDefaults standardUserDefaults] boolForKey:kVLCAudioLibraryHideFeatArtists]; + BOOL hideFeatArtists = VLCDefaults.shared.audioLibraryHideFeatArtists; NSArray *artists = [[VLCAppCoordinator sharedInstance].mediaLibraryService artistsWithSortingCriteria:VLCMLSortingCriteriaDefault desc:NO listAll:!hideFeatArtists]; diff --git a/Sources/Cloud/Services/OneDrive/VLCOneDriveTableViewController.m b/Sources/Cloud/Services/OneDrive/VLCOneDriveTableViewController.m index 2f48bc65749cfeb1140fd048374eb48d8f39ef4e..66841cf2925bd478f485fd059a77cd23935ce64b 100644 --- a/Sources/Cloud/Services/OneDrive/VLCOneDriveTableViewController.m +++ b/Sources/Cloud/Services/OneDrive/VLCOneDriveTableViewController.m @@ -132,7 +132,7 @@ NSInteger positionIndex = 0; VLCMedia *mediaToPlay = [VLCMedia mediaWithURL:url]; mediaToPlay = [_oneDriveController setMediaNameMetadata:mediaToPlay withName:selectedItem.name]; - if (![[NSUserDefaults standardUserDefaults] boolForKey:kVLCAutomaticallyPlayNextItem]) { + if (!VLCDefaults.shared.automaticallyPlayNextItem) { mediaList = [[VLCMediaList alloc] initWithArray:@[mediaToPlay]]; subtitlePath = [_oneDriveController configureSubtitleWithFileName:selectedItem.name folderItems:items]; diff --git a/Sources/Donation/VLCStripeController.m b/Sources/Donation/VLCStripeController.m index 1e8b3e7aec7c0b7e67a370b44d19c84ab3e4eb6f..ed0f13bff59b7379cc8c56f795bde079c89b9c79 100644 --- a/Sources/Donation/VLCStripeController.m +++ b/Sources/Donation/VLCStripeController.m @@ -20,6 +20,7 @@ #import "VLCSubscription.h" #import "VLCDonationInvoicesViewController.h" #import "VLCDonationViewController.h" +#import "VLC-Swift.h" const NSString *publishableStripeAPIKey = @""; const NSString *secretStripeAPIKey = @""; @@ -708,12 +709,12 @@ NSString *callbackURLString = @"vlcpay://3ds"; nextReminderMonth = currentMonth + 3; } - [[NSUserDefaults standardUserDefaults] setInteger:nextReminderMonth forKey:kVLCHasNaggedThisMonth]; + VLCDefaults.shared.hasNaggedThisMonth = nextReminderMonth; } - (void)activeSubscription:(BOOL)bValue { - [[NSUserDefaults standardUserDefaults] setBool:bValue forKey:kVLCHasActiveSubscription]; + VLCDefaults.shared.hasActiveSubscription = bValue; } @end diff --git a/Sources/Headers/VLCConstants.h b/Sources/Headers/VLCConstants.h index c5d22a5b154c56bff82141ad42060c657cdc2bda..442157ed1ffb3c1f2d894f051cae71bef4e6fb8a 100644 --- a/Sources/Headers/VLCConstants.h +++ b/Sources/Headers/VLCConstants.h @@ -11,130 +11,25 @@ * Refer to the COPYING file of the official project for license. *****************************************************************************/ -#define kVLCSettingPasscodeOnKey @"PasscodeProtection" -#define kVLCSettingPasscodeEnableBiometricAuth @"EnableBiometricAuth" -#define kVLCSettingHideLibraryInFilesApp @"HideLibraryInFilesApp" #define kVLCThemeDidChangeNotification @"themeDidChangeNotfication" -#define kVLCSettingAppTheme @"darkMode" -#define kVLCSettingAppThemeBright 0 -#define kVLCSettingAppThemeDark 1 -#define kVLCSettingAppThemeSystem 2 -#define kVLCSettingAppThemeBlack @"blackTheme" -#define kVLCOptimizeItemNamesForDisplay @"MLDecrapifyTitles" -#define kVLCSettingAbout @"about" -#define kVLCAutomaticallyPlayNextItem @"AutomaticallyPlayNextItem" -#define kVLCPlaylistPlayNextItem @"PlaylistPlayNextItem" -#define kVLCLastPlayedPlaylist @"LastPlayedPlaylist" -#define kVLCIsCurrentlyPlayingPlaylist @"isPlaylistCurrentlyPlaying" -#define kVLCCurrentPlaylistMediasQueue @"currentPlaylistMediasQueue" -#define kVLCSettingEnableMediaCellTextScrolling @"EnableMediaCellTextScrolling" -#define kVLCSettingContinueAudioInBackgroundKey @"BackgroundAudioPlayback" -#define kVLCSettingStretchAudio @"audio-time-stretch" -#define kVLCSettingDefaultPreampLevel @"pre-amp-level" -#define kVLCSettingTextEncoding @"subsdec-encoding" -#define kVLCSettingTextEncodingDefaultValue @"Windows-1252" -#define kVLCSettingSkipLoopFilter @"avcodec-skiploopfilter" -#define kVLCSettingSkipLoopFilterNone @(0) -#define kVLCSettingSkipLoopFilterNonRef @(1) #define kVLCSettingSaveHTTPUploadServerStatus @"isHTTPServerOn" -#define kVLCSettingSubtitlesFont @"quartztext-font" -#define kVLCSettingSubtitlesFontDefaultValue @"HelveticaNeue" -#define kVLCSettingSubtitlesFontSize @"quartztext-rel-fontsize" -#define kVLCSettingSubtitlesFontSizeDefaultValue @"16" -#define kVLCSettingSubtitlesBoldFont @"quartztext-bold" -#define kVLCSettingSubtitlesBoldFontDefaultValue @NO -#define kVLCSettingSubtitlesFontColor @"quartztext-color" -#define kVLCSettingSubtitlesFontColorDefaultValue @"16777215" #define kVLCSettingSubtitlesFilePath @"sub-file" #define kVLCSubtitlesCacheFolderName @"cached-subtitles" -#define kVLCSettingDeinterlace @"deinterlace" -#define kVLCSettingDeinterlaceDefaultValue @(-1) -#define kVLCSettingHardwareDecoding @"codec" -#define kVLCSettingHardwareDecodingDefault @"" -#define kVLCSettingRotationLock @"kVLCSettingRotationLock" -#define kVLCSettingNetworkCaching @"network-caching" -#define kVLCSettingNetworkCachingDefaultValue @(999) -#define kVLCSettingNetworkRTSPTCP @"rtsp-tcp" -#define kVLCSaveDebugLogs @"kVLCSaveDebugLogs" #define kVLCSettingNetworkSatIPChannelList @"satip-channelist" #define kVLCSettingNetworkSatIPChannelListCustom @"CustomList" #define kVLCSettingNetworkSatIPChannelListUrl @"satip-channellist-url" -#define kVLCSettingsDecrapifyTitles @"MLDecrapifyTitles" -#define kVLCSettingVolumeGesture @"EnableVolumeGesture" -#define kVLCSettingPlayPauseGesture @"EnablePlayPauseGesture" -#define kVLCSettingBrightnessGesture @"EnableBrightnessGesture" -#define kVLCSettingSeekGesture @"EnableSeekGesture" -#define kVLCSettingCloseGesture @"EnableCloseGesture" -#define kVLCSettingVideoFullscreenPlayback @"AlwaysUseFullscreenForVideo" -#define kVLCSettingContinuePlayback @"ContinuePlayback" -#define kVLCSettingContinueAudioPlayback @"ContinueAudioPlayback" -#define kVLCSettingPlaybackSpeedDefaultValue @"playback-speed" -#define kVLCSettingWiFiSharingIPv6 @"wifi-sharing-ipv6" -#define kVLCSettingWiFiSharingIPv6DefaultValue @(NO) -#define kVLCSettingEqualizerProfile @"EqualizerProfile" -#define kVLCSettingEqualizerProfileDisabled @"EqualizerDisabled" -#define kVLCSettingEqualizerProfileDefaultValue @(0) -#define kVLCSettingPlaybackForwardBackwardEqual @"playback-forward-backward-equal" -#define kVLCSettingPlaybackTapSwipeEqual @"playback-tap-swipe-equal" -#define kVLCSettingPlaybackForwardSkipLength @"playback-forward-skip-length" -#define kVLCSettingPlaybackForwardSkipLengthDefaultValue @(10) -#define kVLCSettingPlaybackBackwardSkipLength @"playback-backward-skip-length" -#define kVLCSettingPlaybackBackwardSkipLengthDefaultValue @(10) -#define kVLCSettingPlaybackForwardSkipLengthSwipe @"playback-forward-skip-length-swipe" -#define kVLCSettingPlaybackForwardSkipLengthSwipeDefaultValue @(10) -#define kVLCSettingPlaybackBackwardSkipLengthSwipe @"playback-backward-skip-length-swipe" -#define kVLCSettingPlaybackLongTouchSpeedUp @"LongTouchSpeedUp" -#define kVLCSettingPlaybackBackwardSkipLengthSwipeDefaultValue @(10) -#define kVLCSettingPlaybackLockscreenSkip @"playback-lockscreen-skip" -#define kVLCSettingPlaybackRemoteControlSkip @"playback-remote-control-skip" -#define kVLCSettingOpenAppForPlayback @"open-app-for-playback" -#define kVLCSettingOpenAppForPlaybackDefaultValue @YES -#define kVLCSettingShowThumbnails @"ShowThumbnails" -#define kVLCSettingShowThumbnailsDefaultValue @YES -#define kVLCSettingShowArtworks @"ShowArtworks" -#define kVLCSettingShowArtworksDefaultValue @YES -#define kVLCSettingsDisableGrouping @"MLDisableGrouping" -#define kVLCkVLCSettingsDisableGroupingDefaultValue @NO +#define kVLCSettingLastUsedSubtitlesSearchLanguage @"kVLCSettingLastUsedSubtitlesSearchLanguage" #define kVLCSettingCastingAudioPassthrough @"sout-chromecast-audio-passthrough" #define kVLCSettingCastingConversionQuality @"sout-chromecast-conversion-quality" -#define kVLCSettingBackupMediaLibrary @"BackupMediaLibrary" -#define kVLCSettingBackupMediaLibraryDefaultValue @NO -#define kVLCSettingLastUsedSubtitlesSearchLanguage @"kVLCSettingLastUsedSubtitlesSearchLanguage" -#define kVLCResetSettings @"kVLCResetSettings" -#define kVLCSettingAlwaysPlayURLs @"kVLCSettingAlwaysPlayURLs" -#define kVLCSettingDisableSubtitles @"kVLCSettingDisableSubtitles" -#define kVLCSettingPlayerControlDuration @"kVLCSettingPlayerControlDuration" -#define kVLCSettingPlayerControlDurationDefaultValue @(4) -#define kVLCSettingPauseWhenShowingControls @"kVLCSettingPauseWhenShowingControls" - -#define kVLCForceSMBV1 @"smb-force-v1" - -#define kVLCShowRemainingTime @"show-remaining-time" #define kVLCRecentURLs @"recent-urls" #define kVLCRecentURLTitles @"recent-url-titles" #define kVLCPrivateWebStreaming @"private-streaming" #define kVLChttpScanSubtitle @"http-scan-subtitle" #define kVLCHTTPUploadDirectory @"Upload" -#define kVLCAudioLibraryGridLayout @"kVLCAudioLibraryGridLayout" -#define kVLCAudioLibraryHideFeatArtists @"kVLCAudioLibraryHideFeatArtists" -#define kVLCAudioLibraryHideTrackNumbers @"kVLCAudioLibraryHideTrackNumbers" -#define kVLCVideoLibraryGridLayout @"kVLCVideoLibraryGridLayout" - +#define kVLCSettingStretchAudio @"audio-time-stretch" #define kVLCLastPlayedMediaIdentifier @"LastPlayedMediaIdentifier" -#define kVLCRestoreLastPlayedMedia @"RestoreLastPlayedMedia" #define kVLCPlayerOpenInMiniPlayer @"OpenInMiniPlayer" -#define kVLCPlayerShouldRememberState @"PlayerShouldRememberState" -#define kVLCPlayerShouldRememberBrightness @"PlayerShouldRememberBrightness" -#define KVLCPlayerBrightness @"playerbrightness" -#define kVLCPlayerIsShuffleEnabled @"PlayerIsShuffleEnabled" -#define kVLCPlayerIsShuffleEnabledDefaultValue @NO -#define kVLCPlayerIsRepeatEnabled @"PlayerIsRepeatEnabled" -#define kVLCPlayerIsRepeatEnabledDefaultValue @(0) -#define kVLCPlayerShowPlaybackSpeedShortcut @"kVLCPlayerShowPlaybackSpeedShortcut" - -#define kVLCCustomProfileEnabled @"kVLCCustomProfileEnabled" -#define kVLCCustomEqualizerProfiles @"kVLCCustomEqualizerProfiles" #define kSupportedFileExtensions @"\\.(669|3g2|3gp|3gp2|3gpp|amv|asf|avi|bik|bin|crf|divx|drc|dv|evo|f4v|far|flv|gvi|gxf|hevc|iso|it|m1v|m2v|m2t|m2ts|m4v|mkv|mov|mp2|mp2v|mp4|mp4v|mpe|mpeg|mpeg1|mpeg2|mpeg4|mpg|mpv2|mtm|mts|mtv|mxf|mxg|nsv|nuv|ogg|ogm|ogv|ogx|ps|rec|rm|rmvb|rpl|s3m|thp|tod|ts|tts|txd|vlc|vob|vro|webm|wm|wmv|wtv|xesc|xm)$" #define kSupportedSubtitleFileExtensions @"\\.(cdg|idx|srt|sub|utf|ass|ssa|aqt|jss|psb|rt|smi|txt|smil|stl|usf|dks|pjs|mpl2|mks|vtt|ttml|dfxp)$" @@ -170,19 +65,8 @@ #define kVLCWifiAuthentificationFailure 1 #define kVLCWifiAuthentificationBanned 2 -#define kVLCSortDefault @"SortDefault" -#define kVLCSortDescendingDefault @"SortDescendingDefault" -#define kVLCHasLaunchedBefore @"hasLaunchedBefore" -#define kVLCHasNaggedThisMonth @"kVLCHasNaggedThisMonth" -#define kVLCNumberOfLaunches @"kVLCNumberOfLaunches" -#define kVLCHasActiveSubscription @"kVLCHasActiveSubscription" - -#define kVLCTabBarIndex @"TabBarIndex" - #define kVLCGroupLayout @"kVLCGroupLayout" -#define kVLCEqualizerSnapBands @"EqualizerSnapBands" - #define kVLCDonationAnonymousCustomerID @"kVLCDonationAnonymousCustomerID" /* LEGACY KEYS, DO NOT USE IN NEW CODE */ diff --git a/Sources/Headers/VLCTVConstants.h b/Sources/Headers/VLCTVConstants.h index 3d5e993b09d098c0f682f539619ac4c2575b5743..e2c9d0997d2efe9da4a03736600c947fd86ec9a9 100644 --- a/Sources/Headers/VLCTVConstants.h +++ b/Sources/Headers/VLCTVConstants.h @@ -25,71 +25,26 @@ #define kSupportedProtocolSchemes @"(rtsp|mms|mmsh|udp|rtp|rtmp|sftp|ftp|smb)$" -#define kVLCSettingPlaybackSpeedDefaultValue @"playback-speed" -#define kVLCSettingNetworkCaching @"network-caching" -#define kVLCSettingNetworkCachingDefaultValue @(999) -#define kVLCSettingNetworkRTSPTCP @"rtsp-tcp" -#define kVLCSaveDebugLogs @"kVLCSaveDebugLogs" #define kVLCSettingNetworkSatIPChannelList @"satip-channelist" #define kVLCSettingNetworkSatIPChannelListCustom @"CustomList" + #define kVLCSettingNetworkSatIPChannelListUrl @"satip-channellist-url" -#define kVLCSettingSkipLoopFilter @"avcodec-skiploopfilter" -#define kVLCSettingSkipLoopFilterNone @(0) -#define kVLCSettingSkipLoopFilterNonRef @(1) -#define kVLCSettingSkipLoopFilterNonKey @(3) -#define kVLCSettingDeinterlace @"deinterlace" -#define kVLCSettingDeinterlaceDefaultValue @(-1) -#define kVLCSettingHardwareDecoding @"codec" -#define kVLCSettingHardwareDecodingDefault @"" -#define kVLCSettingSubtitlesFont @"quartztext-font" -#define kVLCSettingSubtitlesFontDefaultValue @"HelveticaNeue" -#define kVLCSettingSubtitlesFontSize @"quartztext-rel-fontsize" -#define kVLCSettingSubtitlesFontSizeDefaultValue @"16" -#define kVLCSettingSubtitlesBoldFont @"quartztext-bold" -#define kVLCSettingSubtitlesBoldFontDefaultValue @NO -#define kVLCSettingSubtitlesFontColor @"quartztext-color" -#define kVLCSettingSubtitlesFontColorDefaultValue @"16777215" + #define kVLCSubtitlesCacheFolderName @"cached-subtitles" -#define kVLCSettingTextEncoding @"subsdec-encoding" -#define kVLCSettingTextEncodingDefaultValue @"Windows-1252" -#define kVLCSettingStretchAudio @"audio-time-stretch" -#define kVLCSettingStretchAudioOnValue @"1" -#define kVLCSettingStretchAudioOffValue @"0" -#define kVLCSettingContinueAudioInBackgroundKey @"BackgroundAudioPlayback" -#define kVLCSettingDefaultPreampLevel @"pre-amp-level" #define kVLCSettingSubtitlesFilePath @"sub-file" -#define kVLCSettingEqualizerProfile @"EqualizerProfile" -#define kVLCSettingEqualizerProfileDisabled @"EqualizerDisabled" -#define kVLCSettingEqualizerProfileDefaultValue @(0) -#define kVLCSettingPlaybackForwardSkipLength @"playback-forward-skip-length" -#define kVLCSettingPlaybackForwardSkipLengthDefaultValue @(10) -#define kVLCSettingPlaybackBackwardSkipLength @"playback-backward-skip-length" -#define kVLCSettingPlaybackBackwardSkipLengthDefaultValue @(10) -#define kVLCSettingPlaybackLockscreenSkip @"playback-lockscreen-skip" -#define kVLCSettingPlaybackRemoteControlSkip @"playback-remote-control-skip" #define kVLCSettingSaveHTTPUploadServerStatus @"isHTTPServerOn" -#define kVLCAutomaticallyPlayNextItem @"AutomaticallyPlayNextItem" -#define kVLCPlayerUIShouldHide @"PlayerUIShouldHide" -#define kVLCSettingDownloadArtwork @"download-artwork" #define kVLCSettingUseSPDIF @"kVLCSettingUseSPDIF" -#define kVLCSettingBackupMediaLibrary @"BackupMediaLibrary" -#define kVLCSettingBackupMediaLibraryDefaultValue @NO -#define kVLCSettingDisableSubtitles @"kVLCSettingDisableSubtitles" -#define kVLCSettingPlayerControlDuration @"kVLCSettingPlayerControlDuration" -#define kVLCSettingPlayerControlDurationDefaultValue @(4) + +#define kVLCSettingStretchAudio @"audio-time-stretch" #define kVLCLastPlayedMediaIdentifier @"LastPlayedMediaIdentifier" #define kVLCPlayerOpenInMiniPlayer @"OpenInMiniPlayer" -#define kVLCPlayerShouldRememberState @"PlayerShouldRememberState" -#define kVLCPlayerIsShuffleEnabled @"PlayerIsShuffleEnabled" -#define kVLCPlayerIsShuffleEnabledDefaultValue @NO -#define kVLCPlayerIsRepeatEnabled @"PlayerIsRepeatEnabled" -#define kVLCPlayerIsRepeatEnabledDefaultValue @(0) #define kVLCSettingLastUsedSubtitlesSearchLanguage @"kVLCSettingLastUsedSubtitlesSearchLanguage" -#define kVLCSettingWiFiSharingIPv6 @"wifi-sharing-ipv6" -#define kVLCSettingWiFiSharingIPv6DefaultValue @(NO) + +#define kVLCSettingCastingAudioPassthrough @"sout-chromecast-audio-passthrough" +#define kVLCSettingCastingConversionQuality @"sout-chromecast-conversion-quality" #define kVLCfortvOSMovieDBKey @"" @@ -97,9 +52,4 @@ #define kVLCHTTPUploadDirectory @"Upload" -#define kVLCSettingCastingAudioPassthrough @"sout-chromecast-audio-passthrough" -#define kVLCSettingCastingConversionQuality @"sout-chromecast-conversion-quality" - -#define kVLCForceSMBV1 @"smb-force-v1" - #define kVLCSettingReset @"kVLCSettingReset" diff --git a/Sources/Helpers/ColorThemeExtension.swift b/Sources/Helpers/ColorThemeExtension.swift index b3f07ce243aec30a0194af746d72c93cdc7942d1..160384079cf9527eab23beddc090d09cc54f1091 100644 --- a/Sources/Helpers/ColorThemeExtension.swift +++ b/Sources/Helpers/ColorThemeExtension.swift @@ -17,7 +17,7 @@ extension PresentationTheme { // there was a userInterfaceStyle change. return } - guard UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) == kVLCSettingAppThemeSystem else { + guard VLCDefaults.shared.appTheme == .system else { // Theme is specificly set, do not follow systeme theme. return } diff --git a/Sources/Helpers/Network/URLHandler.swift b/Sources/Helpers/Network/URLHandler.swift index 9ff0e7388a89172f4eecccc520f70d5e8b000e2a..d0a6e375ad21fcc7cb484995c76b9b398c202eec 100644 --- a/Sources/Helpers/Network/URLHandler.swift +++ b/Sources/Helpers/Network/URLHandler.swift @@ -173,7 +173,7 @@ extension VLCURLHandler { let alwaysPlayAction = UIAlertAction(title: NSLocalizedString("ALWAYS_STREAM_URL", comment: ""), style: .default) { _ in - UserDefaults.standard.set(true, forKey: kVLCSettingAlwaysPlayURLs) + VLCDefaults.shared.alwaysPlayURLs = true self.handlePlay() } @@ -363,7 +363,7 @@ class XCallbackURLHandler: NSObject, VLCURLHandler { return true default: #if os(iOS) - if UserDefaults.standard.bool(forKey: kVLCSettingAlwaysPlayURLs) { + if VLCDefaults.shared.alwaysPlayURLs { self.handlePlay() } else { self.createAlert() @@ -410,7 +410,7 @@ public class VLCCallbackURLHandler: NSObject, VLCURLHandler { #if os(iOS) let scheme = transformedURL.scheme if scheme == "http" || scheme == "https" || scheme == "ftp" { - if UserDefaults.standard.bool(forKey: kVLCSettingAlwaysPlayURLs) { + if VLCDefaults.shared.alwaysPlayURLs { handlePlay() } else { self.createAlert() diff --git a/Sources/Helpers/VLCDefaults.swift b/Sources/Helpers/VLCDefaults.swift new file mode 100644 index 0000000000000000000000000000000000000000..27b6fdbcc49cb2d83c059b0cebd4c721b13d6062 --- /dev/null +++ b/Sources/Helpers/VLCDefaults.swift @@ -0,0 +1,1230 @@ +/***************************************************************************** + * VLCDefaults.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. + *****************************************************************************/ + +extension Notification.Name { + static let VLCDefaultsDidUpdate = Notification.Name("VLCDefaultsDidUpdate") +} + +@objc final class VLCDefaults: NSObject { + @objc static let shared = VLCDefaults() + + private let userDefaults = UserDefaults.standard + + private override init() { + super.init() + NotificationCenter.default.addObserver(self, + selector: #selector(defaultsDidChange), + name: UserDefaults.didChangeNotification, + object: nil) + } + + @objc func registerDefaults() { + var dict: [String: Any] = [ + // bools + Keys.alwaysPlayURLs: false, + Keys.appThemeBlack: false, + Keys.audioLibraryHideFeatArtists: false, + Keys.audioLibraryHideTrackNumbers: false, + Keys.automaticallyPlayNextItem: true, + Keys.backupMediaLibrary: false, + Keys.brightnessGesture: true, + Keys.castingAudioPassthrough: false, + Keys.closeGesture: true, + Keys.continueAudioInBackground: true, + Keys.currentlyPlayingPlaylist: false, + Keys.customEqualizerProfileEnabled: false, + Keys.optimizeTitles: false, + Keys.disableGrouping: false, + Keys.disableSubtitles: false, + Keys.downloadArtwork: true, + Keys.enableMediaCellTextScrolling: false, + Keys.equalizerProfileDisabled: true, + Keys.equalizerSnapBands: false, + Keys.forceSMBV1: true, + Keys.hasActiveSubscription: false, + Keys.hasLaunchedBefore: false, + Keys.hideLibraryInFilesApp: false, + Keys.lockscreenSkip: false, + Keys.mediaLibraryServiceDidForceRescan: false, + Keys.networkRTSPTCP: false, + Keys.passcodeEnableBiometricAuth: true, + Keys.passcodeOn: false, + Keys.pauseWhenShowingControls: false, + Keys.playbackForwardBackwardEqual: true, + Keys.playbackLongTouchSpeedUp: true, + Keys.playbackTapSwipeEqual: true, + Keys.playerIsShuffleEnabled: false, + Keys.playerShouldRememberBrightness: false, + Keys.playerShouldRememberState: true, + Keys.playerShowPlaybackSpeedShortcut: false, + Keys.playerUIShouldHide: false, + Keys.playlistPlayNextItem: true, + Keys.playPauseGesture: true, + Keys.remoteControlSkip: false, + Keys.restoreLastPlayedMedia: true, + Keys.rotationLock: false, + Keys.saveDebugLogs: false, + Keys.seekGesture: true, + Keys.showRemainingTime: false, + Keys.showThumbnails: true, + Keys.stretchAudio: true, + Keys.subtitlesBoldFont: false, + Keys.videoFullscreenPlayback: true, + Keys.volumeGesture: true, + Keys.wifiSharingIPv6: false, + + // numbers + Keys.castingConversionQuality: DefaultValues.castingConversionQuality, + Keys.continueAudioPlayback: 1, + Keys.continuePlayback: 1, + Keys.defaultPreampLevel: Float(6), + Keys.deinterlace: DefaultValues.deinterlace, + Keys.equalizerProfile: DefaultValues.equalizerProfile, + Keys.hasNaggedThisMonth: 0, + Keys.numberOfLaunches: 0, + Keys.playbackBackwardSkipLength: DefaultValues.playbackBackwardSkipLength, + Keys.playbackBackwardSkipLengthSwipe: DefaultValues.playbackBackwardSkipLengthSwipe, + Keys.playbackForwardSkipLength: DefaultValues.playbackForwardSkipLength, + Keys.playbackForwardSkipLengthSwipe: DefaultValues.playbackForwardSkipLengthSwipe, + Keys.playbackSpeedDefaultValue: DefaultValues.playbackSpeedDefaultValue, + Keys.playerControlDuration: DefaultValues.playerControlDuration, + Keys.tabBarIndex: 0, + + // other + Keys.appTheme: DefaultValues.appTheme.rawValue, + Keys.hardwareDecoding: HardwareDecoding.hardware.rawValue, + Keys.networkCaching: NetworkCaching.normal.rawValue, + Keys.networkSatIPChannelListUrl: DefaultValues.networkSatIPChannelListUrl, + Keys.playerIsRepeatEnabled: DefaultValues.playerRepeatMode.rawValue, + Keys.skipLoopFilter: DefaultValues.skipLoopFilter.rawValue, + Keys.subtitlesFontColor: DefaultValues.subtitlesFontColor, + Keys.subtitlesFontSize: DefaultValues.subtitlesFontSize, + Keys.textEncoding: DefaultValues.textEncoding, + ] + + [ + "ALBUMS", + "ARTISTS", + "GENRES", + "ALL_VIDEOS", + "VIDEO_GROUPS", + "VLCMLMediaGroupCollections" + ].forEach { s in + dict[Keys.videoLibraryGridLayout(name: s)] = true + } + + userDefaults.register(defaults: dict) + } + + func reset() { + let appDomain = Bundle.main.bundleIdentifier! + UserDefaults().removePersistentDomain(forName: appDomain) + } + + @objc private func defaultsDidChange(_: Notification) { + NotificationCenter.default.post(name: .VLCDefaultsDidUpdate, object: self) + } + + // These methods are not strictly necessary, however, they help prevent a + // programmer error whereby attempts to write invalid data types will get + // past the compiler, but will cause a crash at runtime. + + fileprivate func set(bool b: Bool, forKey key: String) { + userDefaults.set(b, forKey: key) + } + + fileprivate func set(float f: Float, forKey key: String) { + userDefaults.set(f, forKey: key) + } + + fileprivate func set(integer i: Int, forKey key: String) { + userDefaults.set(i, forKey: key) + } + + fileprivate func set(string s: String, forKey key: String) { + userDefaults.set(s, forKey: key) + } +} + +// MARK: - Defaults + +extension VLCDefaults { + + // Bools + + @objc var alwaysPlayURLs: Bool { + get { + userDefaults.bool(forKey: Keys.alwaysPlayURLs) + } + set { + set(bool: newValue, forKey: Keys.alwaysPlayURLs) + } + } + + @objc var appThemeBlack: Bool { + get { + userDefaults.bool(forKey: Keys.appThemeBlack) + } + set { + set(bool: newValue, forKey: Keys.appThemeBlack) + } + } + + @objc var audioLibraryHideFeatArtists: Bool { + get { + userDefaults.bool(forKey: Keys.audioLibraryHideFeatArtists) + } + set { + set(bool: newValue, forKey: Keys.audioLibraryHideFeatArtists) + } + } + + @objc var audioLibraryHideTrackNumbers: Bool { + get { + userDefaults.bool(forKey: Keys.audioLibraryHideTrackNumbers) + } + set { + set(bool: newValue, forKey: Keys.audioLibraryHideTrackNumbers) + } + } + + @objc var automaticallyPlayNextItem: Bool { + get { + userDefaults.bool(forKey: Keys.automaticallyPlayNextItem) + } + set { + set(bool: newValue, forKey: Keys.automaticallyPlayNextItem) + } + } + + @objc var backupMediaLibrary: Bool { + get { + userDefaults.bool(forKey: Keys.backupMediaLibrary) + } + set { + set(bool: newValue, forKey: Keys.backupMediaLibrary) + } + } + + @objc var brightnessGesture: Bool { + get { + userDefaults.bool(forKey: Keys.brightnessGesture) + } + set { + set(bool: newValue, forKey: Keys.brightnessGesture) + } + } + + @objc var castingAudioPassthrough: Bool { + get { + userDefaults.bool(forKey: Keys.castingAudioPassthrough) + } + set { + set(bool: newValue, forKey: Keys.castingAudioPassthrough) + } + } + + @objc var closeGesture: Bool { + get { + userDefaults.bool(forKey: Keys.closeGesture) + } + set { + set(bool: newValue, forKey: Keys.closeGesture) + } + } + + @objc var continueAudioInBackgroundKey: Bool { + get { + userDefaults.bool(forKey: Keys.continueAudioInBackground) + } + set { + set(bool: newValue, forKey: Keys.continueAudioInBackground) + } + } + + @objc var currentlyPlayingPlaylist: Bool { + get { + userDefaults.bool(forKey: Keys.currentlyPlayingPlaylist) + } + set { + set(bool: newValue, forKey: Keys.currentlyPlayingPlaylist) + } + } + + @objc var customEqualizerProfileEnabled: Bool { + get { + userDefaults.bool(forKey: Keys.customEqualizerProfileEnabled) + } + set { + set(bool: newValue, forKey: Keys.customEqualizerProfileEnabled) + } + } + + @objc var optimizeTitles: Bool { + get { + userDefaults.bool(forKey: Keys.optimizeTitles) + } + set { + set(bool: newValue, forKey: Keys.optimizeTitles) + } + } + + @objc var disableGrouping: Bool { + get { + userDefaults.bool(forKey: Keys.disableGrouping) + } + set { + set(bool: newValue, forKey: Keys.disableGrouping) + } + } + + @objc var disableSubtitles: Bool { + get { + userDefaults.bool(forKey: Keys.disableSubtitles) + } + set { + set(bool: newValue, forKey: Keys.disableSubtitles) + } + } + + @objc var downloadArtwork: Bool { + get { + userDefaults.bool(forKey: Keys.downloadArtwork) + } + set { + set(bool: newValue, forKey: Keys.downloadArtwork) + } + } + + @objc var enableMediaCellTextScrolling: Bool { + get { + userDefaults.bool(forKey: Keys.enableMediaCellTextScrolling) + } + set { + set(bool: newValue, forKey: Keys.enableMediaCellTextScrolling) + } + } + + @objc var equalizerProfileDisabled: Bool { + get { + userDefaults.bool(forKey: Keys.equalizerProfileDisabled) + } + set { + set(bool: newValue, forKey: Keys.equalizerProfileDisabled) + } + } + + @objc var equalizerSnapBands: Bool { + get { + userDefaults.bool(forKey: Keys.equalizerSnapBands) + } + set { + set(bool: newValue, forKey: Keys.equalizerSnapBands) + } + } + + @objc var forceSMBV1: Bool { + get { + userDefaults.bool(forKey: Keys.forceSMBV1) + } + set { + set(bool: newValue, forKey: Keys.forceSMBV1) + } + } + + @objc var hasActiveSubscription: Bool { + get { + userDefaults.bool(forKey: Keys.hasActiveSubscription) + } + set { + set(bool: newValue, forKey: Keys.hasActiveSubscription) + } + } + + var hasLaunchedBefore: Bool { + userDefaults.bool(forKey: Keys.hasLaunchedBefore) + } + + func setHasLaunchedBeforeIfNeeded() { + if !hasLaunchedBefore { + userDefaults.set(true, forKey: Keys.hasLaunchedBefore) + } + } + + @objc var hideLibraryInFilesApp: Bool { + get { + userDefaults.bool(forKey: Keys.hideLibraryInFilesApp) + } + set { + set(bool: newValue, forKey: Keys.hideLibraryInFilesApp) + } + } + + @objc var lockscreenSkip: Bool { + get { + userDefaults.bool(forKey: Keys.lockscreenSkip) + } + set { + set(bool: newValue, forKey: Keys.lockscreenSkip) + } + } + + @objc var mediaLibraryServiceDidForceRescan: Bool { + get { + userDefaults.bool(forKey: Keys.mediaLibraryServiceDidForceRescan) + } + set { + set(bool: newValue, forKey: Keys.mediaLibraryServiceDidForceRescan) + } + } + + @objc var networkRTSPTCP: Bool { + get { + userDefaults.bool(forKey: Keys.networkRTSPTCP) + } + set { + set(bool: newValue, forKey: Keys.networkRTSPTCP) + } + } + + @objc var pauseWhenShowingControls: Bool { + get { + userDefaults.bool(forKey: Keys.pauseWhenShowingControls) + } + set { + set(bool: newValue, forKey: Keys.pauseWhenShowingControls) + } + } + + var playbackForwardBackwardEqual: Bool { + get { + userDefaults.bool(forKey: Keys.playbackForwardBackwardEqual) + } + set { + set(bool: newValue, forKey: Keys.playbackForwardBackwardEqual) + } + } + + @objc var playbackLongTouchSpeedUp: Bool { + get { + userDefaults.bool(forKey: Keys.playbackLongTouchSpeedUp) + } + set { + set(bool: newValue, forKey: Keys.playbackLongTouchSpeedUp) + } + } + + @objc var playbackTapSwipeEqual: Bool { + get { + userDefaults.bool(forKey: Keys.playbackTapSwipeEqual) + } + set { + set(bool: newValue, forKey: Keys.playbackTapSwipeEqual) + } + } + + @objc var playerIsShuffleEnabled: Bool { + get { + userDefaults.bool(forKey: Keys.playerIsShuffleEnabled) + } + set { + set(bool: newValue, forKey: Keys.playerIsShuffleEnabled) + } + } + + @objc var playerShouldRememberBrightness: Bool { + get { + userDefaults.bool(forKey: Keys.playerShouldRememberBrightness) + } + set { + set(bool: newValue, forKey: Keys.playerShouldRememberBrightness) + } + } + + @objc var playerShouldRememberState: Bool { + get { + userDefaults.bool(forKey: Keys.playerShouldRememberState) + } + set { + set(bool: newValue, forKey: Keys.playerShouldRememberState) + } + } + + @objc var passcodeEnableBiometricAuth: Bool { + get { + userDefaults.bool(forKey: Keys.passcodeEnableBiometricAuth) + } + set { + set(bool: newValue, forKey: Keys.passcodeEnableBiometricAuth) + } + } + + @objc var passcodeOn: Bool { + get { + userDefaults.bool(forKey: Keys.passcodeOn) + } + set { + set(bool: newValue, forKey: Keys.passcodeOn) + } + } + + @objc var playerShowPlaybackSpeedShortcut: Bool { + get { + userDefaults.bool(forKey: Keys.playerShowPlaybackSpeedShortcut) + } + set { + set(bool: newValue, forKey: Keys.playerShowPlaybackSpeedShortcut) + } + } + + /// tvOS only + @objc var playerUIShouldHide: Bool { + get { + userDefaults.bool(forKey: Keys.playerUIShouldHide) + } + set { + set(bool: newValue, forKey: Keys.playerUIShouldHide) + } + } + + @objc var playlistPlayNextItem: Bool { + get { + userDefaults.bool(forKey: Keys.playlistPlayNextItem) + } + set { + set(bool: newValue, forKey: Keys.playlistPlayNextItem) + } + } + + @objc var playPauseGesture: Bool { + get { + userDefaults.bool(forKey: Keys.playPauseGesture) + } + set { + set(bool: newValue, forKey: Keys.playPauseGesture) + } + } + + @objc var restoreLastPlayedMedia: Bool { + get { + userDefaults.bool(forKey: Keys.restoreLastPlayedMedia) + } + set { + set(bool: newValue, forKey: Keys.restoreLastPlayedMedia) + } + } + + @objc var remoteControlSkip: Bool { + get { + userDefaults.bool(forKey: Keys.remoteControlSkip) + } + set { + set(bool: newValue, forKey: Keys.remoteControlSkip) + } + } + + @objc var rotationLock: Bool { + get { + userDefaults.bool(forKey: Keys.rotationLock) + } + set { + set(bool: newValue, forKey: Keys.rotationLock) + } + } + + @objc var saveDebugLogs: Bool { + get { + userDefaults.bool(forKey: Keys.saveDebugLogs) + } + set { + set(bool: newValue, forKey: Keys.saveDebugLogs) + } + } + + @objc var seekGesture: Bool { + get { + userDefaults.bool(forKey: Keys.seekGesture) + } + set { + set(bool: newValue, forKey: Keys.seekGesture) + } + } + + @objc var showArtworks: Bool { + get { + userDefaults.bool(forKey: Keys.showArtworks) + } + set { + set(bool: newValue, forKey: Keys.showArtworks) + } + } + + @objc var showRemainingTime: Bool { + get { + userDefaults.bool(forKey: Keys.showRemainingTime) + } + set { + set(bool: newValue, forKey: Keys.showRemainingTime) + } + } + + @objc var showThumbnails: Bool { + get { + userDefaults.bool(forKey: Keys.showThumbnails) + } + set { + set(bool: newValue, forKey: Keys.showThumbnails) + } + } + + @objc var stretchAudio: Bool { + get { + userDefaults.bool(forKey: Keys.stretchAudio) + } + set { + set(bool: newValue, forKey: Keys.stretchAudio) + } + } + + @objc var subtitlesBoldFont: Bool { + get { + userDefaults.bool(forKey: Keys.subtitlesBoldFont) + } + set { + set(bool: newValue, forKey: Keys.subtitlesBoldFont) + } + } + + @objc var videoFullscreenPlayback: Bool { + get { + userDefaults.bool(forKey: Keys.videoFullscreenPlayback) + } + set { + set(bool: newValue, forKey: Keys.videoFullscreenPlayback) + } + } + + @objc var volumeGesture: Bool { + get { + userDefaults.bool(forKey: Keys.volumeGesture) + } + set { + set(bool: newValue, forKey: Keys.volumeGesture) + } + } + + @objc var wifiSharingIPv6: Bool { + get { + userDefaults.bool(forKey: Keys.wifiSharingIPv6) + } + set { + set(bool: newValue, forKey: Keys.wifiSharingIPv6) + } + } + + // Numbers + + @objc var castingConversionQuality: Int { + get { + userDefaults.integer(forKey: Keys.castingConversionQuality) + } + set { + set(integer: newValue, forKey: Keys.castingConversionQuality) + } + } + + @objc var continueAudioPlayback: Int { + get { + userDefaults.integer(forKey: Keys.continueAudioPlayback) + } + set { + set(integer: newValue, forKey: Keys.continueAudioPlayback) + } + } + + @objc var continuePlayback: Int { + get { + userDefaults.integer(forKey: Keys.continuePlayback) + } + set { + set(integer: newValue, forKey: Keys.continuePlayback) + } + } + + @objc var defaultPreampLevel: Float { + get { + userDefaults.float(forKey: Keys.defaultPreampLevel) + } + set { + set(float: newValue, forKey: Keys.defaultPreampLevel) + } + } + + @objc var deinterlace: Int { + get { + userDefaults.integer(forKey: Keys.deinterlace) + } + set { + set(integer: newValue, forKey: Keys.deinterlace) + } + } + + @objc var equalizerProfile: Int { + get { + userDefaults.integer(forKey: Keys.equalizerProfile) + } + set { + set(integer: newValue, forKey: Keys.equalizerProfile) + } + } + + @objc var hasNaggedThisMonth: Int { + get { + userDefaults.integer(forKey: Keys.hasNaggedThisMonth) + } + set { + set(integer: newValue, forKey: Keys.hasNaggedThisMonth) + } + } + + @objc var numberOfLaunches: Int { + userDefaults.integer(forKey: Keys.numberOfLaunches) + } + + @objc func incrementNumberOfLaunches() { + userDefaults.set(numberOfLaunches + 1, forKey: Keys.numberOfLaunches) + } + + @objc func resetNumberOfLaunches() { + userDefaults.set(0, forKey: Keys.numberOfLaunches) + } + + @objc var playbackBackwardSkipLength: Int { + get { + userDefaults.integer(forKey: Keys.playbackBackwardSkipLength) + } + set { + set(integer: newValue, forKey: Keys.playbackBackwardSkipLength) + } + } + + @objc var playbackBackwardSkipLengthSwipe: Int { + get { + userDefaults.integer(forKey: Keys.playbackBackwardSkipLengthSwipe) + } + set { + set(integer: newValue, forKey: Keys.playbackBackwardSkipLengthSwipe) + } + } + + @objc var playbackForwardSkipLength: Int { + get { + userDefaults.integer(forKey: Keys.playbackForwardSkipLength) + } + set { + set(integer: newValue, forKey: Keys.playbackForwardSkipLength) + } + } + + @objc var playbackForwardSkipLengthSwipe: Int { + get { + userDefaults.integer(forKey: Keys.playbackForwardSkipLengthSwipe) + } + set { + set(integer: newValue, forKey: Keys.playbackForwardSkipLengthSwipe) + } + } + + @objc var playbackSpeedDefaultValue: Float { + get { + userDefaults.float(forKey: Keys.playbackSpeedDefaultValue) + } + set { + set(float: newValue, forKey: Keys.playbackSpeedDefaultValue) + } + } + + var playerBrightness: Float? { + get { + // Use data(forKey:) to determine if a value has been set at all + userDefaults.data(forKey: Keys.playerBrightness).flatMap { _ in + userDefaults.float(forKey: Keys.playerBrightness) + } + } + set { + if let newValue = newValue { + set(float: newValue, forKey: Keys.playerBrightness) + } else { + userDefaults.removeObject(forKey: Keys.playerBrightness) + } + } + } + + @objc var playerControlDuration: Int { + get { + userDefaults.integer(forKey: Keys.playerControlDuration) + } + set { + set(integer: newValue, forKey: Keys.playerControlDuration) + } + } + + @objc var tabBarIndex: Int { + get { + userDefaults.integer(forKey: Keys.tabBarIndex) + } + set { + set(integer: newValue, forKey: Keys.tabBarIndex) + } + } + + // Other + + var appTheme: AppTheme { + get { + let v = userDefaults.integer(forKey: Keys.appTheme) + return AppTheme(rawValue: v) ?? DefaultValues.appTheme + } + set { + set(integer: newValue.rawValue, forKey: Keys.appTheme) + } + } + + @objc var appThemeIsSystem: Bool { + appTheme == .system + } + +#if os(iOS) || os(visionOS) + var customEqualizerProfiles: CustomEqualizerProfiles? { + get { + guard let encodedData = userDefaults.data(forKey: Keys.customEqualizerProfiles) else { + return nil + } + + guard let decoded = try? NSKeyedUnarchiver(forReadingFrom: encodedData) + .decodeObject(forKey: "root") as? CustomEqualizerProfiles else { + return nil + } + + return decoded + } + set { + guard let newValue = newValue else { + return + } + + guard let encoded = try? NSKeyedArchiver + .archivedData(withRootObject: newValue, requiringSecureCoding: false) else { + return + } + + userDefaults.setValue(encoded, forKey: Keys.customEqualizerProfiles) + } + } +#endif + + var hardwareDecoding: HardwareDecoding { + get { + guard let v = userDefaults.string(forKey: Keys.hardwareDecoding) else { + return HardwareDecoding.hardware + } + + return HardwareDecoding(rawValue: v) ?? .hardware + } + set { + set(string: newValue.rawValue, forKey: Keys.hardwareDecoding) + } + } + + @objc var hardwareDecodingObjC: String { + hardwareDecoding.rawValue + } + +#if os(iOS) || os(visionOS) + var lastPlayedPlaylist: LastPlayedPlaylistModel? { + get { + guard let encodedData = userDefaults.data(forKey: Keys.lastPlayedPlaylist) else { + return nil + } + + guard let decoded = try? NSKeyedUnarchiver(forReadingFrom: encodedData) + .decodeObject(forKey: "root") as? LastPlayedPlaylistModel else { + return nil + } + + return decoded + } + set { + guard let newValue = newValue else { + return + } + + guard let encoded = try? NSKeyedArchiver + .archivedData(withRootObject: newValue, requiringSecureCoding: false) else { + return + } + + userDefaults.setValue(encoded, forKey: Keys.lastPlayedPlaylist) + } + } +#endif + + var networkCaching: NetworkCaching { + get { + let v = userDefaults.integer(forKey: Keys.networkCaching) + return NetworkCaching(rawValue: v) ?? .normal + } + set { + set(integer: newValue.rawValue, forKey: Keys.networkCaching) + } + } + + @objc var networkCachingObjC: Int { + networkCaching.rawValue + } + + @objc var networkSatIPChannelListUrl: String { + get { + userDefaults.string(forKey: Keys.networkSatIPChannelListUrl) ?? DefaultValues.networkSatIPChannelListUrl + } + set { + set(string: newValue, forKey: Keys.networkSatIPChannelListUrl) + } + } + + @objc var playerIsRepeatEnabled: VLCRepeatMode { + get { + let v = userDefaults.integer(forKey: Keys.playerIsRepeatEnabled) + return VLCRepeatMode(rawValue: v) ?? DefaultValues.playerRepeatMode + } + set { + set(integer: newValue.rawValue, forKey: Keys.playerIsRepeatEnabled) + } + } + + @objc var textEncoding: String { + get { + userDefaults.string(forKey: Keys.textEncoding) ?? DefaultValues.textEncoding + } + set { + set(string: newValue, forKey: Keys.textEncoding) + } + } + + var skipLoopFilter: SkipLoopFilter { + get { + let v = userDefaults.integer(forKey: Keys.skipLoopFilter) + return SkipLoopFilter(rawValue: v) ?? DefaultValues.skipLoopFilter + } + set { + set(integer: newValue.rawValue, forKey: Keys.skipLoopFilter) + } + } + + @objc var skipLoopFilterObjC: Int { + get { + userDefaults.integer(forKey: Keys.skipLoopFilter) + } + } + + @objc var subtitlesFont: String { + get { + userDefaults.string(forKey: Keys.subtitlesFont) ?? DefaultValues.subtitlesFont + } + set { + set(string: newValue, forKey: Keys.subtitlesFont) + } + } + + @objc var subtitlesFontColor: String { + get { + userDefaults.string(forKey: Keys.subtitlesFontColor) ?? DefaultValues.subtitlesFontColor + } + set { + set(string: newValue, forKey: Keys.subtitlesFontColor) + } + } + + @objc var subtitlesFontSize: String { + get { + userDefaults.string(forKey: Keys.subtitlesFontSize) ?? DefaultValues.subtitlesFontSize + } + set { + set(string: newValue, forKey: Keys.subtitlesFontSize) + } + } + + func videoLibraryGridLayout(collectionModelName: String? = nil, name: String) -> Bool { + userDefaults.bool(forKey: Keys.videoLibraryGridLayout(collectionModelName: collectionModelName, name: name)) + } + + func setVideoLibraryGridLayout(collectionModelName: String? = nil, name: String, isGrid: Bool) { + userDefaults.set(isGrid, forKey: Keys.videoLibraryGridLayout(collectionModelName: collectionModelName, name: name)) + } + + func audioLibraryGridLayout(collectionModelName: String? = nil, name: String) -> Bool { + userDefaults.bool(forKey: Keys.audioLibraryGridLayout(collectionModelName: collectionModelName, name: name)) + } + + func setAudioLibraryGridLayout(collectionModelName: String? = nil, name: String, isGrid: Bool) { + userDefaults.set(isGrid, forKey: Keys.audioLibraryGridLayout(collectionModelName: collectionModelName, name: name)) + } + +#if os(iOS) || os(visionOS) + func sortDefault(name: String) -> VLCMLSortingCriteria? { + let k = Keys.sortDefault(name: name) + + // Use data(forKey:) to determine if a value has been set at all + return userDefaults.data(forKey: k).flatMap { _ in + let v = userDefaults.integer(forKey: k) + return VLCMLSortingCriteria(rawValue: UInt(v)) + } + } + + func setSortDefault(name: String, criteria: VLCMLSortingCriteria) { + let k = Keys.sortDefault(name: name) + userDefaults.set(criteria.rawValue, forKey: k) + } + + func sortDescendingDefault(name: String) -> Bool { + let k = Keys.sortDescendingDefault(name: name) + return userDefaults.bool(forKey: k) + } + + func setSortDescendingDefault(name: String, isDescending: Bool) { + let k = Keys.sortDescendingDefault(name: name) + userDefaults.set(isDescending, forKey: k) + } +#endif +} + +// MARK: - Compatibility + +extension VLCDefaults { + @available(*, deprecated, message: "avoid using keys to access defaults directly, instead use properties on VLCDefaults") + @objc(VLCDefaultsCompat) + final class Compat: NSObject { + static let appThemeKey: String = Keys.appTheme + static let automaticallyPlayNextItemKey: String = Keys.automaticallyPlayNextItem + static let backupMediaLibraryKey: String = Keys.backupMediaLibrary + static let castingConversionQualityKey: String = Keys.castingConversionQuality + static let continueAudioPlaybackKey: String = Keys.continueAudioPlayback + static let continuePlaybackKey: String = Keys.continuePlayback + static let defaultPreampLevelKey: String = Keys.defaultPreampLevel + static let deinterlaceKey: String = Keys.deinterlace + static let disableGroupingKey: String = Keys.disableGrouping + static let hardwareDecodingKey: String = Keys.hardwareDecoding + static let hideLibraryInFilesAppKey: String = Keys.hideLibraryInFilesApp + static let lockscreenSkipKey: String = Keys.lockscreenSkip + static let networkCachingKey: String = Keys.networkCaching + static let passcodeOnKey: String = Keys.passcodeOn + static let playbackBackwardSkipLengthKey: String = Keys.playbackBackwardSkipLength + static let playbackBackwardSkipLengthSwipeKey: String = Keys.playbackBackwardSkipLengthSwipe + static let playbackForwardSkipLengthKey: String = Keys.playbackForwardSkipLength + static let playbackForwardSkipLengthSwipeKey: String = Keys.playbackForwardSkipLengthSwipe + static let playbackSpeedDefaultValueKey: String = Keys.playbackSpeedDefaultValue + static let playerControlDurationKey: String = Keys.playerControlDuration + static let remoteControlSkipKey: String = Keys.remoteControlSkip + static let skipLoopFilterKey: String = Keys.skipLoopFilter + static let subtitlesFontColorKey: String = Keys.subtitlesFontColor + static let subtitlesFontKey: String = Keys.subtitlesFont + static let subtitlesFontSizeKey: String = Keys.subtitlesFontSize + static let textEncodingKey: String = Keys.textEncoding + + override init() { + fatalError("compat struct not intended to be instantiated") + } + } +} + +// MARK: - Value Types + +extension VLCDefaults { + enum AppTheme: Int { + case bright = 0 + case dark = 1 + case system = 2 + case black = 3 + } +} + +extension VLCDefaults { + enum HardwareDecoding: String, CustomStringConvertible { + case software = "avcodec,all" + case hardware = "" + + var description: String { + switch self { + case .software: + return "Software" + case .hardware: + return "Hardware" + } + } + } +} + +extension VLCDefaults { + enum NetworkCaching: Int { + case lowest = 333 + case low = 666 + case normal = 999 + case high = 1667 + case highest = 3333 + } +} + +extension VLCDefaults { + enum SkipLoopFilter: Int { + case none = 0 + case nonRef = 1 + case nonKey = 3 + } +} + +// MARK: - Keys + +fileprivate enum Keys { + // Avoid ever changing these values. Some are used as parameters in functions. + // Changing a value also causes the locally stored value to become unreachable. + static let alwaysPlayURLs = "kVLCSettingAlwaysPlayURLs" + static let appTheme = "darkMode" + static let appThemeBlack = "blackTheme" + static let audioLibraryHideFeatArtists = "kVLCAudioLibraryHideFeatArtists" + static let audioLibraryHideTrackNumbers = "kVLCAudioLibraryHideTrackNumbers" + static let automaticallyPlayNextItem = "AutomaticallyPlayNextItem" + static let backupMediaLibrary = "BackupMediaLibrary" + static let brightnessGesture = "EnableBrightnessGesture" + static let castingAudioPassthrough = kVLCSettingCastingAudioPassthrough + static let castingConversionQuality = kVLCSettingCastingConversionQuality + static let closeGesture = "EnableCloseGesture" + static let continueAudioInBackground = "BackgroundAudioPlayback" + static let continueAudioPlayback = "ContinueAudioPlayback" + static let continuePlayback = "ContinuePlayback" + static let currentlyPlayingPlaylist = "isPlaylistCurrentlyPlaying" + static let customEqualizerProfileEnabled = "kVLCCustomProfileEnabled" + static let customEqualizerProfiles = "kVLCCustomEqualizerProfiles" + static let optimizeTitles = "MLDecrapifyTitles" + static let defaultPreampLevel = "pre-amp-level" + static let deinterlace = "deinterlace" + static let disableGrouping = "MLDisableGrouping" + static let disableSubtitles = "kVLCSettingDisableSubtitles" + static let downloadArtwork = "download-artwork" + static let enableMediaCellTextScrolling = "EnableMediaCellTextScrolling" + static let equalizerProfile = "EqualizerProfile" + static let equalizerProfileDisabled = "EqualizerDisabled" + static let equalizerSnapBands = "EqualizerSnapBands" + static let forceSMBV1 = "smb-force-v1" + static let hardwareDecoding = "codec" + static let hasActiveSubscription = "kVLCHasActiveSubscription" + static let hasLaunchedBefore = "hasLaunchedBefore" + static let hasNaggedThisMonth = "kVLCHasNaggedThisMonth" + static let hideLibraryInFilesApp = "HideLibraryInFilesApp" + static let lastPlayedPlaylist = "LastPlayedPlaylist" + static let lockscreenSkip = "playback-lockscreen-skip" + static let mediaLibraryServiceDidForceRescan = "MediaLibraryDidForceRescan" + static let networkCaching = "network-caching" + static let networkRTSPTCP = "rtsp-tcp" + static let networkSatIPChannelListUrl = kVLCSettingNetworkSatIPChannelListUrl + static let numberOfLaunches = "kVLCNumberOfLaunches" + static let passcodeEnableBiometricAuth = "EnableBiometricAuth" + static let passcodeOn = "PasscodeProtection" + static let pauseWhenShowingControls = "kVLCSettingPauseWhenShowingControls" + static let playbackBackwardSkipLength = "playback-backward-skip-length" + static let playbackBackwardSkipLengthSwipe = "playback-backward-skip-length-swipe" + static let playbackForwardBackwardEqual = "playback-forward-backward-equal" + static let playbackForwardSkipLength = "playback-forward-skip-length" + static let playbackForwardSkipLengthSwipe = "playback-forward-skip-length-swipe" + static let playbackLongTouchSpeedUp = "LongTouchSpeedUp" + static let playbackSpeedDefaultValue = "playback-speed" + static let playbackTapSwipeEqual = "playback-tap-swipe-equal" + static let playerBrightness = "playerbrightness" + static let playerControlDuration = "kVLCSettingPlayerControlDuration" + static let playerIsRepeatEnabled = "PlayerIsRepeatEnabled" + static let playerIsShuffleEnabled = "PlayerIsShuffleEnabled" + static let playerShouldRememberBrightness = "PlayerShouldRememberBrightness" + static let playerShouldRememberState = "PlayerShouldRememberState" + static let playerShowPlaybackSpeedShortcut = "kVLCPlayerShowPlaybackSpeedShortcut" + static let playerUIShouldHide = "PlayerUIShouldHide" + static let playlistPlayNextItem = "PlaylistPlayNextItem" + static let playPauseGesture = "EnablePlayPauseGesture" + static let remoteControlSkip = "playback-remote-control-skip" + static let restoreLastPlayedMedia = "RestoreLastPlayedMedia" + static let rotationLock = "kVLCSettingRotationLock" + static let saveDebugLogs = "kVLCSaveDebugLogs" + static let seekGesture = "EnableSeekGesture" + static let showArtworks = "ShowArtworks" + static let showRemainingTime = "show-remaining-time" + static let showThumbnails = "ShowThumbnails" + static let skipLoopFilter = "avcodec-skiploopfilter" + static let stretchAudio = kVLCSettingStretchAudio + static let subtitlesBoldFont = "quartztext-bold" + static let subtitlesFont = "quartztext-font" + static let subtitlesFontColor = "quartztext-color" + static let subtitlesFontSize = "quartztext-rel-fontsize" + static let tabBarIndex = "TabBarIndex" + static let textEncoding = "subsdec-encoding" + static let videoFullscreenPlayback = "AlwaysUseFullscreenForVideo" + static let volumeGesture = "EnableVolumeGesture" + static let wifiSharingIPv6 = "wifi-sharing-ipv6" + + static func videoLibraryGridLayout(collectionModelName: String? = nil, name: String) -> String { + [ + "kVLCVideoLibraryGridLayout", collectionModelName, name + ].compactMap { $0 }.joined() + } + + static func audioLibraryGridLayout(collectionModelName: String? = nil, name: String) -> String { + [ + "kVLCAudioLibraryGridLayout", collectionModelName, name + ].compactMap { $0 }.joined() + } + + static func sortDefault(name: String) -> String { + [ + "SortDefault", name + ].joined() + } + + static func sortDescendingDefault(name: String) -> String { + [ + "SortDescendingDefault", name + ].joined() + } +} + +// MARK: - Default Values + +fileprivate enum DefaultValues { + static let appTheme: VLCDefaults.AppTheme = { + if #available(iOS 13.0, *) { + return .system + } + return .bright + }() + static let castingConversionQuality = 2 + static let deinterlace = Int(-1) + static let equalizerProfile = Int(0) + static let textEncoding = "Windows-1252" + static let networkSatIPChannelListUrl = "" + static let playbackBackwardSkipLength = 10 + static let playbackBackwardSkipLengthSwipe = 10 + static let playbackForwardSkipLength = 10 + static let playbackForwardSkipLengthSwipe = 10 + static let playbackSpeedDefaultValue = Float(1) + static let playerControlDuration = 4 + static let playerRepeatMode = VLCRepeatMode.doNotRepeat + static let skipLoopFilter = VLCDefaults.SkipLoopFilter.nonRef + static let subtitlesFont = "HelveticaNeue" + static let subtitlesFontColor = "16777215" + static let subtitlesFontSize = "16" +} diff --git a/Sources/Media Library/Discovery/VLCMediaFileDiscoverer.m b/Sources/Media Library/Discovery/VLCMediaFileDiscoverer.m index ce034844be2e7c3d9e04bcf513b22a87fabb9396..abac807374ff97945e215a917f006a16016d24c7 100644 --- a/Sources/Media Library/Discovery/VLCMediaFileDiscoverer.m +++ b/Sources/Media Library/Discovery/VLCMediaFileDiscoverer.m @@ -200,7 +200,7 @@ const float MediaTimerInterval = 2.f; } } } - BOOL backupMediaLibrary = [NSUserDefaults.standardUserDefaults boolForKey:kVLCSettingBackupMediaLibrary]; + BOOL backupMediaLibrary = VLCDefaults.shared.backupMediaLibrary; NSURL *fileURL = [NSURL fileURLWithPath:filePath]; [fileURL setExcludedFromBackup:!backupMediaLibrary recursive:NO onlyFirstLevel:NO :nil]; @@ -226,7 +226,7 @@ const float MediaTimerInterval = 2.f; - (void)didAddMedia:(NSTimer*)timer { #if TARGET_OS_IOS - BOOL hideMediaLibrary = [NSUserDefaults.standardUserDefaults boolForKey:kVLCSettingHideLibraryInFilesApp]; + BOOL hideMediaLibrary = VLCDefaults.shared.hideLibraryInFilesApp; [(NSURL*)[timer.userInfo valueForKey:@"fileURL"] setHidden:hideMediaLibrary recursive:NO onlyFirstLevel:NO :nil]; #endif [NSFileManager.defaultManager removeItemAtPath:[NSString pathWithComponents:@[_directoryPath, NSLocalizedString(@"MEDIALIBRARY_ADDING_PLACEHOLDER", "")]] error:nil]; diff --git a/Sources/Media Library/MediaCategories/MediaCategoryViewController.swift b/Sources/Media Library/MediaCategories/MediaCategoryViewController.swift index c221da347649b09f85b2e6a0c64177a52a15ceb1..0d4dfe56fa4bf9e72ceeab4d55c38e4347e47940 100644 --- a/Sources/Media Library/MediaCategories/MediaCategoryViewController.swift +++ b/Sources/Media Library/MediaCategories/MediaCategoryViewController.swift @@ -40,7 +40,6 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega private var searchBarConstraint: NSLayoutConstraint? private var searchDataSource: LibrarySearchDataSource private let searchBarSize: CGFloat = 50.0 - private let userDefaults = UserDefaults.standard #if os(iOS) private var rendererButton: UIButton #endif @@ -79,7 +78,7 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega private lazy var navItemTitle: VLCMarqueeLabel = VLCMarqueeLabel() private var hasLaunchedBefore: Bool { - return userDefaults.bool(forKey: kVLCHasLaunchedBefore) + return VLCDefaults.shared.hasLaunchedBefore } @objc private lazy var sortActionSheet: ActionSheet = { @@ -202,17 +201,12 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega }() private var lastPlaylist: LastPlayedPlaylistModel? { - let encodedLastPlaylist = userDefaults.data(forKey: kVLCLastPlayedPlaylist) - guard let encodedData = encodedLastPlaylist, - let lastPlayed = NSKeyedUnarchiver(forReadingWith: encodedData).decodeObject(forKey: "root") as? LastPlayedPlaylistModel else { - return nil - } - return lastPlayed + return VLCDefaults.shared.lastPlayedPlaylist } // Indicating that the current chosen collection to play is playlist, useful for handling Observer private var isPlaylistCurrentlyPlaying: Bool { - return userDefaults.bool(forKey: kVLCIsCurrentlyPlayingPlaylist) + return VLCDefaults.shared.currentlyPlayingPlaylist } // catch the selected index from collection view, helper for playbackDidStart @@ -234,8 +228,8 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega videoModel.secondName = model.name if model is MediaGroupViewModel { - self.model = userDefaults.bool(forKey: kVLCSettingsDisableGrouping) ? videoModel : model - self.secondModel = userDefaults.bool(forKey: kVLCSettingsDisableGrouping) ? model : videoModel + self.model = VLCDefaults.shared.disableGrouping ? videoModel : model + self.secondModel = VLCDefaults.shared.disableGrouping ? model : videoModel } else { self.model = model self.secondModel = videoModel @@ -567,13 +561,8 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega } func loadSort() { - let sortingCriteria: VLCMLSortingCriteria - if let sortingCriteriaDefault = UserDefaults.standard.value(forKey: "\(kVLCSortDefault)\(model.name)") as? UInt { - sortingCriteria = VLCMLSortingCriteria(rawValue: sortingCriteriaDefault) ?? model.sortModel.currentSort - } else { - sortingCriteria = model.sortModel.currentSort - } - let desc = UserDefaults.standard.bool(forKey: "\(kVLCSortDescendingDefault)\(model.name)") + let sortingCriteria = VLCDefaults.shared.sortDefault(name: model.name) ?? model.sortModel.currentSort + let desc = VLCDefaults.shared.sortDescendingDefault(name: model.name) self.model.sort(by: sortingCriteria, desc: desc) } @@ -604,14 +593,14 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega let navigationController = UINavigationController(rootViewController: firstStepController) navigationController.modalPresentationStyle = .formSheet self.present(navigationController, animated: true) - userDefaults.set(true, forKey: kVLCHasLaunchedBefore) + VLCDefaults.shared.setHasLaunchedBeforeIfNeeded() } else { - if userDefaults.bool(forKey: kVLCHasActiveSubscription) { + if VLCDefaults.shared.hasActiveSubscription { return } - var lastNagMonth = userDefaults.integer(forKey: kVLCHasNaggedThisMonth) - let numberOfLaunches = userDefaults.integer(forKey: kVLCNumberOfLaunches) + var lastNagMonth = VLCDefaults.shared.hasNaggedThisMonth + let numberOfLaunches = VLCDefaults.shared.numberOfLaunches let currentMonth = NSCalendar.current.component(.month, from: Date()) if lastNagMonth == 12 && currentMonth < 12 { @@ -619,8 +608,8 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega } if lastNagMonth < currentMonth && numberOfLaunches >= 5 { - userDefaults.setValue(currentMonth, forKey: kVLCHasNaggedThisMonth) - userDefaults.setValue(0, forKey: kVLCNumberOfLaunches) + VLCDefaults.shared.hasNaggedThisMonth = currentMonth + VLCDefaults.shared.resetNumberOfLaunches() let donationVC = VLCDonationNagScreenViewController(nibName: "VLCDonationNagScreenViewController", bundle: nil) let donationNC = UINavigationController(rootViewController: donationVC) donationNC.navigationBar.isHidden = true @@ -641,7 +630,7 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega saveCurrentPlaylistInfo(with: playlist.identifier(), playlistTitle: playlist.title(), media: playlist.media?[selectedIndex.row]) addPlaybackWillStopObserver() reloadData() - userDefaults.set(true, forKey: kVLCIsCurrentlyPlayingPlaylist) + VLCDefaults.shared.currentlyPlayingPlaylist = true } else if let playlists = currentDataSet as? [VLCMLPlaylist], let selectedIndex = collectionSelectedIndex { let selectedPlaylist = playlists[selectedIndex.row] guard let media = PlaybackService.sharedInstance().currentlyPlayingMedia, @@ -650,7 +639,7 @@ class MediaCategoryViewController: UICollectionViewController, UISearchBarDelega saveCurrentPlaylistInfo(with: selectedPlaylist.identifier(), playlistTitle: selectedPlaylist.title(), media: mlMedia) addPlaybackWillStopObserver() reloadData() - userDefaults.set(true, forKey: kVLCIsCurrentlyPlayingPlaylist) + VLCDefaults.shared.currentlyPlayingPlaylist = true } else if isPlaylistCurrentlyPlaying { //if the playlist media is already being played and the current model is not Playlist or playlist collection media. //This will update the value of last played media, leading to right indication if the app is suddenly closed. @@ -937,10 +926,8 @@ extension MediaCategoryViewController { @objc func executeSortAction(with sortingCriteria: VLCMLSortingCriteria, desc: Bool) { model.sort(by: sortingCriteria, desc: desc) - userDefaults.set(desc, - forKey: "\(kVLCSortDescendingDefault)\(model.name)") - userDefaults.set(sortingCriteria.rawValue, - forKey: "\(kVLCSortDefault)\(model.name)") + VLCDefaults.shared.setSortDescendingDefault(name: model.name, isDescending: desc) + VLCDefaults.shared.setSortDefault(name: model.name, criteria: sortingCriteria) sortActionSheet.removeActionSheet() reloadData() } @@ -1525,8 +1512,6 @@ extension MediaCategoryViewController: ActionSheetSortSectionHeaderDelegate { func handleLayoutChange(gridLayout: Bool) { var prefix: String = "" - var suffix: String = "" - var collectionModelName: String = "" var isVideoModel = false if let model = model as? CollectionModel { @@ -1538,9 +1523,17 @@ extension MediaCategoryViewController: ActionSheetSortSectionHeaderDelegate { isVideoModel = true } - prefix = isVideoModel ? kVLCVideoLibraryGridLayout : kVLCAudioLibraryGridLayout - suffix = collectionModelName + model.name - userDefaults.set(gridLayout, forKey: "\(prefix)\(suffix)") + switch isVideoModel { + case true: + VLCDefaults.shared.setVideoLibraryGridLayout(collectionModelName: collectionModelName, + name: model.name, + isGrid: gridLayout) + case false: + VLCDefaults.shared.setAudioLibraryGridLayout(collectionModelName: collectionModelName, + name: model.name, + isGrid: gridLayout) + } + setupCollectionView() cachedCellSize = .zero collectionView?.collectionViewLayout.invalidateLayout() @@ -1548,7 +1541,7 @@ extension MediaCategoryViewController: ActionSheetSortSectionHeaderDelegate { } func actionSheetSortSectionHeaderShouldHideFeatArtists(onSwitchIsOnChange: Bool) { - userDefaults.set(onSwitchIsOnChange, forKey: "\(kVLCAudioLibraryHideFeatArtists)") + VLCDefaults.shared.audioLibraryHideFeatArtists = onSwitchIsOnChange setupCollectionView() cachedCellSize = .zero model.sort(by: model.sortModel.currentSort, desc: model.sortModel.desc) @@ -1556,7 +1549,7 @@ extension MediaCategoryViewController: ActionSheetSortSectionHeaderDelegate { } func actionSheetSortSectionHeaderShouldHideTrackNumbers(onSwitchIsOnChange: Bool) { - userDefaults.set(onSwitchIsOnChange, forKey: "\(kVLCAudioLibraryHideTrackNumbers)") + VLCDefaults.shared.audioLibraryHideTrackNumbers = onSwitchIsOnChange setupCollectionView() cachedCellSize = .zero model.sort(by: model.sortModel.currentSort, desc: model.sortModel.desc) @@ -1564,18 +1557,17 @@ extension MediaCategoryViewController: ActionSheetSortSectionHeaderDelegate { } func actionSheetSortSectionHeader(_ header: ActionSheetSortSectionHeader, onSwitchIsOnChange: Bool, type: ActionSheetSortHeaderOptions) { - var prefix: String = "" - var suffix: String = "" - if type == .descendingOrder { + switch type { + case .descendingOrder: model.sort(by: model.sortModel.currentSort, desc: onSwitchIsOnChange) - prefix = kVLCSortDescendingDefault - suffix = model is VideoModel ? secondModel.name : model.name - userDefaults.set(onSwitchIsOnChange, forKey: "\(prefix)\(suffix)") + let name = model is VideoModel ? secondModel.name : model.name + VLCDefaults.shared.setSortDescendingDefault(name: name, isDescending: onSwitchIsOnChange) setupCollectionView() cachedCellSize = .zero collectionView?.collectionViewLayout.invalidateLayout() reloadData() - } else if type == .layoutChange { + + case .layoutChange: handleLayoutChange(gridLayout: onSwitchIsOnChange) } } @@ -1779,13 +1771,13 @@ extension MediaCategoryViewController: MediaLibraryBaseModelObserver { extension MediaCategoryViewController { func play(media: VLCMLMedia, at indexPath: IndexPath) { let playbackController = PlaybackService.sharedInstance() - var autoPlayNextItem: Bool = userDefaults.bool(forKey: kVLCAutomaticallyPlayNextItem) + var autoPlayNextItem: Bool = VLCDefaults.shared.automaticallyPlayNextItem playbackController.fullscreenSessionRequested = media.type() != .audio if let model = model as? CollectionModel, model.mediaCollection is VLCMLPlaylist { - autoPlayNextItem = userDefaults.bool(forKey: kVLCPlaylistPlayNextItem) + autoPlayNextItem = VLCDefaults.shared.playlistPlayNextItem } if !autoPlayNextItem { @@ -1836,7 +1828,7 @@ extension MediaCategoryViewController { let lastMedia = LastPlayed(identifier: media.identifier(), title: media.title) let playlistInfo = LastPlayedPlaylistModel(identifier: playlistId, title: playlistTitle, lastPlayedMedia: lastMedia) - userDefaults.setValue(NSKeyedArchiver.archivedData(withRootObject: playlistInfo), forKey: kVLCLastPlayedPlaylist) + VLCDefaults.shared.lastPlayedPlaylist = playlistInfo } private func addPlaybackWillStopObserver() { @@ -1859,7 +1851,7 @@ extension MediaCategoryViewController { reloadData() removePlaybackWillStopObserver() - userDefaults.setValue(false, forKey: kVLCIsCurrentlyPlayingPlaylist) + VLCDefaults.shared.currentlyPlayingPlaylist = false playbackCache.clearQueuePlaylistInfo() } diff --git a/Sources/Media Library/MediaCategoryCells/MediaCollectionViewCell.swift b/Sources/Media Library/MediaCategoryCells/MediaCollectionViewCell.swift index ebf09f30f3e442e2225e6bc9f7433e9c122a8e3b..43d14a1f1df3d20d79acb2a2c5e68b08d936d031 100644 --- a/Sources/Media Library/MediaCategoryCells/MediaCollectionViewCell.swift +++ b/Sources/Media Library/MediaCategoryCells/MediaCollectionViewCell.swift @@ -106,7 +106,7 @@ class MediaCollectionViewCell: BaseCollectionViewCell, UIScrollViewDelegate { } private var enableMarquee: Bool { - return !UserDefaults.standard.bool(forKey: kVLCSettingEnableMediaCellTextScrolling) + return !VLCDefaults.shared.enableMediaCellTextScrolling } // MARK: - Init @@ -260,7 +260,7 @@ class MediaCollectionViewCell: BaseCollectionViewCell, UIScrollViewDelegate { trackNumber = String(describing: media.trackNumber) + ". " } - let displayTrackNumber: Bool = !UserDefaults.standard.bool(forKey: kVLCAudioLibraryHideTrackNumbers) + let displayTrackNumber: Bool = !VLCDefaults.shared.audioLibraryHideTrackNumbers titleLabel.text = displayTrackNumber ? trackNumber + audiotrack.title() : audiotrack.title() accessibilityLabel = audiotrack.accessibilityText(editing: false) var descriptionText = audiotrack.albumTrackArtistName() @@ -617,7 +617,7 @@ class MediaCollectionViewCell: BaseCollectionViewCell, UIScrollViewDelegate { // MARK: - Handle New label Text func handleLastPlayed() { - let isCurrentlyPlayingPlaylist = UserDefaults.standard.bool(forKey: kVLCIsCurrentlyPlayingPlaylist) + let isCurrentlyPlayingPlaylist = VLCDefaults.shared.currentlyPlayingPlaylist let shouldDisplayLastPlayedLabel = (!playbackService.isPlaying && playbackService.currentlyPlayingMedia == nil) || !isCurrentlyPlayingPlaylist newLabel.isHidden = !shouldDisplayLastPlayedLabel diff --git a/Sources/Media Library/MediaCategoryCells/MediaGridCollectionCell.swift b/Sources/Media Library/MediaCategoryCells/MediaGridCollectionCell.swift index b77ae39e5d0d0266852d6365b367ab0a1b493c91..22f37e16588a6abece5c08530b8f1420ea4f989b 100644 --- a/Sources/Media Library/MediaCategoryCells/MediaGridCollectionCell.swift +++ b/Sources/Media Library/MediaCategoryCells/MediaGridCollectionCell.swift @@ -15,7 +15,6 @@ import UIKit class MediaGridCollectionCell: BaseCollectionViewCell { private let notificationCenter = NotificationCenter.default - private let userDefaults = UserDefaults.standard private let selectionOverlayColor = UIColor.orange.withAlphaComponent(0.4) private let checkboxImageView: UIImageView = { @@ -146,7 +145,7 @@ class MediaGridCollectionCell: BaseCollectionViewCell { } private var enableMarquee: Bool { - return !userDefaults.bool(forKey: kVLCSettingEnableMediaCellTextScrolling) + return !VLCDefaults.shared.enableMediaCellTextScrolling } override init(frame: CGRect) { diff --git a/Sources/Media Library/MediaCategoryCells/MovieCollectionViewCell.swift b/Sources/Media Library/MediaCategoryCells/MovieCollectionViewCell.swift index f51f579c0251ef00bc808895a4e08a4e9cdb6e84..99500d1df53dcba37895cbcd0b7c9fbc0437e614 100644 --- a/Sources/Media Library/MediaCategoryCells/MovieCollectionViewCell.swift +++ b/Sources/Media Library/MediaCategoryCells/MovieCollectionViewCell.swift @@ -169,9 +169,7 @@ class MovieCollectionViewCell: BaseCollectionViewCell { descriptionLabel.text = movie.mediaDuration() thumbnailView.image = movie.thumbnailImage() let progress = movie.progress - guard let value = UserDefaults.standard.value(forKey: kVLCSettingContinuePlayback) as? Int else { - return - } + let value = VLCDefaults.shared.continuePlayback if value <= 0 { progressView.isHidden = true } else { @@ -195,7 +193,7 @@ class MovieCollectionViewCell: BaseCollectionViewCell { let playbackService = PlaybackService.sharedInstance() if lastPlayed { - let isCurrentlyPlayingPlaylist = UserDefaults.standard.bool(forKey: kVLCIsCurrentlyPlayingPlaylist) + let isCurrentlyPlayingPlaylist = VLCDefaults.shared.currentlyPlayingPlaylist let shouldDisplayLastPlayedLabel = (!playbackService.isPlaying && playbackService.currentlyPlayingMedia == nil) || !isCurrentlyPlayingPlaylist groupLastPlayedLabel.isHidden = !shouldDisplayLastPlayedLabel groupLastPlayedLabel.text = NSLocalizedString("LAST_PLAYED_PLAYLIST_LABEL_TITLE", comment: "") diff --git a/Sources/Media Library/MediaLibraryModel/AlbumModel.swift b/Sources/Media Library/MediaLibraryModel/AlbumModel.swift index a2ccfa9f2a58cc0588d918d6cc7cafd3546a437f..ec14e4ca5ba78fea10399fdf2d87ab25fdc92b9f 100644 --- a/Sources/Media Library/MediaLibraryModel/AlbumModel.swift +++ b/Sources/Media Library/MediaLibraryModel/AlbumModel.swift @@ -22,7 +22,7 @@ class AlbumModel: AudioCollectionModel { private var artist: VLCMLArtist? = nil var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(name)") ? MediaGridCollectionCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.audioLibraryGridLayout(name: name) ? MediaGridCollectionCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryModel/ArtistModel.swift b/Sources/Media Library/MediaLibraryModel/ArtistModel.swift index 4934fab6e74f0e9e862abe0e7fdafe38c1e4c2a9..6422ec0a37622aa77eea7f1b37bb51794e23f732 100644 --- a/Sources/Media Library/MediaLibraryModel/ArtistModel.swift +++ b/Sources/Media Library/MediaLibraryModel/ArtistModel.swift @@ -20,7 +20,7 @@ class ArtistModel: AudioCollectionModel { var fileArrayLock = NSRecursiveLock() var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(name)") ? MediaGridCollectionCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.audioLibraryGridLayout(name: name) ? MediaGridCollectionCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService @@ -30,7 +30,7 @@ class ArtistModel: AudioCollectionModel { var indicatorName: String = NSLocalizedString("ARTISTS", comment: "") var hideFeatArtists: Bool { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryHideFeatArtists)") + return VLCDefaults.shared.audioLibraryHideFeatArtists } required init(medialibrary: MediaLibraryService) { diff --git a/Sources/Media Library/MediaLibraryModel/CollectionModel.swift b/Sources/Media Library/MediaLibraryModel/CollectionModel.swift index 9bd87f214be04a9b3cac52b6c72d9a0cbf5f9242..a0ac6ec3e88fd483335e7edafc0129f2b865feed 100644 --- a/Sources/Media Library/MediaLibraryModel/CollectionModel.swift +++ b/Sources/Media Library/MediaLibraryModel/CollectionModel.swift @@ -27,12 +27,16 @@ class CollectionModel: MLBaseModel { var files = [VLCMLMedia]() var cellType: BaseCollectionViewCell.Type { + let collectionModelName: String = String(describing: type(of: mediaCollection)) + if mediaCollection is VLCMLMediaGroup { - return UserDefaults.standard.bool(forKey: "\(kVLCVideoLibraryGridLayout)\(String(describing: type(of: mediaCollection)) + name)") ? - MovieCollectionViewCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared + .videoLibraryGridLayout(collectionModelName: collectionModelName, name: name) ? + MovieCollectionViewCell.self : MediaCollectionViewCell.self } else { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(String(describing: type(of: mediaCollection)) + name)") ? - MediaGridCollectionCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared + .audioLibraryGridLayout(collectionModelName: collectionModelName, name: name) ? + MediaGridCollectionCell.self : MediaCollectionViewCell.self } } diff --git a/Sources/Media Library/MediaLibraryModel/GenreModel.swift b/Sources/Media Library/MediaLibraryModel/GenreModel.swift index 6824e031eea5f28fe3d8c7dcd15e9c8d352c524f..d0f7cbb18906eee84b37fc237071c65da3e29b22 100644 --- a/Sources/Media Library/MediaLibraryModel/GenreModel.swift +++ b/Sources/Media Library/MediaLibraryModel/GenreModel.swift @@ -20,7 +20,7 @@ class GenreModel: AudioCollectionModel { var files = [VLCMLGenre]() var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(name)") ? MediaGridCollectionCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.audioLibraryGridLayout(name: name) ? MediaGridCollectionCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift b/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift index 43bdd193d32d2842cbb5edc4af7d546c7da2176f..07c9eb299e6f68e9bc316e8776b791db72473acb 100644 --- a/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift +++ b/Sources/Media Library/MediaLibraryModel/MediaGroupViewModel.swift @@ -21,7 +21,7 @@ class MediaGroupViewModel: MLBaseModel { var files: [VLCMLMediaGroup] var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCVideoLibraryGridLayout)\(name)") ? MovieCollectionViewCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.videoLibraryGridLayout(name: name) ? MovieCollectionViewCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryModel/MediaLibraryBaseModel.swift b/Sources/Media Library/MediaLibraryModel/MediaLibraryBaseModel.swift index 34360210d34ea347de2047d336e1ab25a65e6f44..c93e89dac2a66e17ae9e5edec2777d9a3ef4fa92 100644 --- a/Sources/Media Library/MediaLibraryModel/MediaLibraryBaseModel.swift +++ b/Sources/Media Library/MediaLibraryModel/MediaLibraryBaseModel.swift @@ -169,8 +169,8 @@ extension MediaCollectionModel { } } if image == nil - || (!UserDefaults.standard.bool(forKey: kVLCSettingShowThumbnails) && self is VLCMLMediaGroup) - || (!UserDefaults.standard.bool(forKey: kVLCSettingShowArtworks) && !(self is VLCMLMediaGroup)) { + || (!VLCDefaults.shared.showThumbnails && self is VLCMLMediaGroup) + || (!VLCDefaults.shared.showArtworks && !(self is VLCMLMediaGroup)) { let isDarktheme = PresentationTheme.current.isDark if self is VLCMLMediaGroup { image = isDarktheme ? UIImage(named: "movie-placeholder-dark") : UIImage(named: "movie-placeholder-white") diff --git a/Sources/Media Library/MediaLibraryModel/MediaModel.swift b/Sources/Media Library/MediaLibraryModel/MediaModel.swift index 892bcdf8a94b741b36d7f09c3a01da8a44e5d753..18b4912af8a54a60d7c70bf42142d09ded16e9c5 100644 --- a/Sources/Media Library/MediaLibraryModel/MediaModel.swift +++ b/Sources/Media Library/MediaLibraryModel/MediaModel.swift @@ -58,8 +58,8 @@ extension VLCMLMedia { @objc func thumbnailImage() -> UIImage? { var image = VLCThumbnailsCache.thumbnail(for: thumbnail()) if image == nil - || (!UserDefaults.standard.bool(forKey: kVLCSettingShowThumbnails) && subtype() != .albumTrack) - || (!UserDefaults.standard.bool(forKey: kVLCSettingShowArtworks) && subtype() == .albumTrack) { + || (!VLCDefaults.shared.showThumbnails && subtype() != .albumTrack) + || (!VLCDefaults.shared.showArtworks && subtype() == .albumTrack) { let isDarktheme = PresentationTheme.current.isDark if subtype() == .albumTrack { image = isDarktheme ? UIImage(named: "song-placeholder-dark") : UIImage(named: "song-placeholder-white") @@ -78,7 +78,7 @@ extension VLCMLMedia { } func title() -> String { - if UserDefaults.standard.bool(forKey: kVLCOptimizeItemNamesForDisplay) == true + if VLCDefaults.shared.optimizeTitles && ((subtype() == .albumTrack && title.isSupportedAudioMediaFormat()) || (subtype() != .albumTrack && title.isSupportedMediaFormat())) { return (title as NSString).deletingPathExtension diff --git a/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift b/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift index 25c1e973220ac424dfdb39742ded4d9b91322d0e..a7164ff001103d53b08a99f3632ead988e3d15b2 100644 --- a/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift +++ b/Sources/Media Library/MediaLibraryModel/PlaylistModel.swift @@ -21,7 +21,7 @@ class PlaylistModel: MLBaseModel { var files = [VLCMLPlaylist]() var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(name)") ? MovieCollectionViewCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.audioLibraryGridLayout(name: name) ? MovieCollectionViewCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryModel/TrackModel.swift b/Sources/Media Library/MediaLibraryModel/TrackModel.swift index f7cdb6b0c5f633eafd7d8e2c67ba2ea671f113d5..7623a4152a447eaec1c38c16e650aa4f3d8caf99 100644 --- a/Sources/Media Library/MediaLibraryModel/TrackModel.swift +++ b/Sources/Media Library/MediaLibraryModel/TrackModel.swift @@ -20,7 +20,7 @@ class TrackModel: MediaModel { var fileArrayLock = NSRecursiveLock() var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCAudioLibraryGridLayout)\(name)") ? MediaGridCollectionCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.audioLibraryGridLayout(name: name) ? MediaGridCollectionCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryModel/VideoModel.swift b/Sources/Media Library/MediaLibraryModel/VideoModel.swift index d438d50f4517211bb1a9a81458e8125c1c677af5..2ed299581cee3385170d297c320388740ba3bf2a 100644 --- a/Sources/Media Library/MediaLibraryModel/VideoModel.swift +++ b/Sources/Media Library/MediaLibraryModel/VideoModel.swift @@ -20,7 +20,7 @@ class VideoModel: MediaModel { var files = [VLCMLMedia]() var cellType: BaseCollectionViewCell.Type { - return UserDefaults.standard.bool(forKey: "\(kVLCVideoLibraryGridLayout)\(name)") ? MovieCollectionViewCell.self : MediaCollectionViewCell.self + return VLCDefaults.shared.videoLibraryGridLayout(name: name) ? MovieCollectionViewCell.self : MediaCollectionViewCell.self } var medialibrary: MediaLibraryService diff --git a/Sources/Media Library/MediaLibraryService.swift b/Sources/Media Library/MediaLibraryService.swift index 4a218f2e734cc7a1f75419bc1f6f498ec7dd3775..4d14094edd5c39dc72b2a8b6afa543cd36883c86 100644 --- a/Sources/Media Library/MediaLibraryService.swift +++ b/Sources/Media Library/MediaLibraryService.swift @@ -136,7 +136,6 @@ extension NSNotification { class MediaLibraryService: NSObject { private static let databaseName: String = "medialibrary.db" - private static let didForceRescan: String = "MediaLibraryDidForceRescan" private var triedToRecoverFromInitializationErrorOnce = false private var didFinishDiscovery = false @@ -189,14 +188,14 @@ private extension MediaLibraryService { } private func startMediaLibrary(on path: String) { - let excludeMediaLibrary = !UserDefaults.standard.bool(forKey: kVLCSettingBackupMediaLibrary) - let hideML = UserDefaults.standard.bool(forKey: kVLCSettingHideLibraryInFilesApp) + let excludeMediaLibrary = !VLCDefaults.shared.backupMediaLibrary + let hideML = VLCDefaults.shared.hideLibraryInFilesApp excludeFromDeviceBackup(excludeMediaLibrary) hideMediaLibrary(hideML) - if UserDefaults.standard.bool(forKey: MediaLibraryService.didForceRescan) == false { + if !VLCDefaults.shared.mediaLibraryServiceDidForceRescan { medialib.forceRescan() - UserDefaults.standard.set(true, forKey: MediaLibraryService.didForceRescan) + VLCDefaults.shared.mediaLibraryServiceDidForceRescan = true } FileManager.default.createFile(atPath: "\(path)/\(NSLocalizedString("MEDIALIBRARY_FILES_PLACEHOLDER", comment: ""))", contents: nil, attributes: nil) diff --git a/Sources/Media Library/MediaViewControllers/MediaViewController.swift b/Sources/Media Library/MediaViewControllers/MediaViewController.swift index 3077251a6fb2dc5fca449c9e3efbe69288c3257e..ff00e5e31fad94cf8652efbc32c3dea61ae169f7 100644 --- a/Sources/Media Library/MediaViewControllers/MediaViewController.swift +++ b/Sources/Media Library/MediaViewControllers/MediaViewController.swift @@ -533,7 +533,7 @@ extension MediaViewController { var additionalMenuItems: [UIAction] = [] if mediaCategoryViewController.model is ArtistModel { - let isIncludeAllArtistActive = UserDefaults.standard.bool(forKey: kVLCAudioLibraryHideFeatArtists) + let isIncludeAllArtistActive = VLCDefaults.shared.audioLibraryHideFeatArtists let includeAllArtist = UIAction(title: NSLocalizedString("HIDE_FEAT_ARTISTS", comment: ""), image: UIImage(systemName: "person.3"), state: isIncludeAllArtistActive ? .on : .off, @@ -545,7 +545,7 @@ extension MediaViewController { } else if let model = mediaCategoryViewController.model as? CollectionModel, let mediaCollection = model.mediaCollection as? VLCMLAlbum, !mediaCollection.isUnknownAlbum() { - let hideTrackNumbers = UserDefaults.standard.bool(forKey: kVLCAudioLibraryHideTrackNumbers) + let hideTrackNumbers = VLCDefaults.shared.audioLibraryHideTrackNumbers let hideTrackNumbersAction = UIAction(title: NSLocalizedString("HIDE_TRACK_NUMBERS", comment: ""), state: hideTrackNumbers ? .on : .off, handler: { _ in diff --git a/Sources/Media Library/tvOS/VLCMicroMediaLibraryService.m b/Sources/Media Library/tvOS/VLCMicroMediaLibraryService.m index 3afeffb3cb715439f957cdf52a08030813f9ef10..fd6769ec952c142e6bfae241b2d4c4eec2e2c124 100644 --- a/Sources/Media Library/tvOS/VLCMicroMediaLibraryService.m +++ b/Sources/Media Library/tvOS/VLCMicroMediaLibraryService.m @@ -113,7 +113,7 @@ ret = self.discoveredFiles.readonlycopy; } - if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCSaveDebugLogs]) { + if (VLCDefaults.shared.saveDebugLogs) { ret = [self injectLogsToMedia:ret]; } diff --git a/Sources/Network/Server Browsing/Data/Protocols/General/VLCLocalNetworkServiceBrowserMediaDiscoverer.m b/Sources/Network/Server Browsing/Data/Protocols/General/VLCLocalNetworkServiceBrowserMediaDiscoverer.m index 20b779a470438ccf463c4498b0ead104e79387f0..94ccdc73b40836ac14175ae1b5dea5068d175fc1 100644 --- a/Sources/Network/Server Browsing/Data/Protocols/General/VLCLocalNetworkServiceBrowserMediaDiscoverer.m +++ b/Sources/Network/Server Browsing/Data/Protocols/General/VLCLocalNetworkServiceBrowserMediaDiscoverer.m @@ -16,6 +16,7 @@ #import "VLCLocalNetworkServiceBrowserUPnP.h" #import "VLCAppCoordinator.h" #import "VLCHTTPUploaderController.h" +#import "VLC-Swift.h" @interface VLCLocalNetworkServiceBrowserMediaDiscoverer () <VLCMediaListDelegate> { @@ -42,8 +43,7 @@ * so it should be only if explicitly demanded by the user */ _isUPnPdiscoverer = [serviceName isEqualToString:@"upnp"]; if (_isUPnPdiscoverer) { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSString *satipURLstring = [defaults stringForKey:kVLCSettingNetworkSatIPChannelListUrl]; + NSString *satipURLstring = VLCDefaults.shared.networkSatIPChannelListUrl; NSMutableArray *libVLCOptions = [NSMutableArray array]; if (satipURLstring.length > 0) { [libVLCOptions addObject:[NSString stringWithFormat:@"--%@=%@", kVLCSettingNetworkSatIPChannelListUrl, satipURLstring]]; diff --git a/Sources/Network/Server Browsing/Data/Protocols/SMB/VLCLocalNetworkServiceBrowserDSM.m b/Sources/Network/Server Browsing/Data/Protocols/SMB/VLCLocalNetworkServiceBrowserDSM.m index dd1e48b7e118f1bcd7de7bd38dd04fb8e9f22479..d584a502934c4e4bbba269e77f9a1c09da769e13 100644 --- a/Sources/Network/Server Browsing/Data/Protocols/SMB/VLCLocalNetworkServiceBrowserDSM.m +++ b/Sources/Network/Server Browsing/Data/Protocols/SMB/VLCLocalNetworkServiceBrowserDSM.m @@ -12,6 +12,7 @@ #import "VLCLocalNetworkServiceBrowserDSM.h" #import "VLCNetworkServerLoginInformation.h" +#import "VLC-Swift.h" @interface VLCLocalNetworkServiceDSM () + (void)registerLoginInformation; @@ -110,8 +111,8 @@ static NSString *const VLCLocalNetworkServiceDSMWorkgroupIdentifier = @"VLCLocal @"smb-pwd" : password ?: @"", @"smb-domain" : workgroup?: @"WORKGROUP", }.mutableCopy; - if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCForceSMBV1]) { - mediaOptions[kVLCForceSMBV1] = [NSNull null]; + if (VLCDefaults.shared.forceSMBV1) { + mediaOptions[@"smb-force-v1"] = [NSNull null]; } [media addOptions:mediaOptions]; return [[self alloc] initWithMedia:media options:mediaOptions]; diff --git a/Sources/Network/Server Browsing/View Controllers/VLCNetworkServerBrowserViewController.m b/Sources/Network/Server Browsing/View Controllers/VLCNetworkServerBrowserViewController.m index fa54c61caf1fcae7a6593cacbc5b963ea1c66d23..81e2354dc843401ae36dc5eaa15cfee0ad8a1a89 100644 --- a/Sources/Network/Server Browsing/View Controllers/VLCNetworkServerBrowserViewController.m +++ b/Sources/Network/Server Browsing/View Controllers/VLCNetworkServerBrowserViewController.m @@ -273,7 +273,7 @@ { id<VLCNetworkServerBrowserItem> item; NSInteger row = indexPath.row; - BOOL singlePlayback = ![[NSUserDefaults standardUserDefaults] boolForKey:kVLCAutomaticallyPlayNextItem]; + BOOL singlePlayback = !VLCDefaults.shared.automaticallyPlayNextItem; if (self.searchController.isActive) { if (row < _searchArray.count) { item = _searchArray[row]; diff --git a/Sources/Network/Server Browsing/View Controllers/VLCServerBrowsingTVViewController.m b/Sources/Network/Server Browsing/View Controllers/VLCServerBrowsingTVViewController.m index d2f7355fd2747ecba5e97e7158c78da9ad411fc0..78fe65da8abeb7c9dc1c75b260c668efd538ed0e 100644 --- a/Sources/Network/Server Browsing/View Controllers/VLCServerBrowsingTVViewController.m +++ b/Sources/Network/Server Browsing/View Controllers/VLCServerBrowsingTVViewController.m @@ -18,6 +18,7 @@ #import "GRKArrayDiff+UICollectionView.h" #import "VLCFavoriteService.h" #import "VLCAppCoordinator.h" +#import "VLC-Swift.h" @interface VLCServerBrowsingTVViewController () { @@ -47,7 +48,7 @@ self.title = serverBrowser.title; - self.downloadArtwork = [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingDownloadArtwork]; + self.downloadArtwork = VLCDefaults.shared.downloadArtwork; } return self; } @@ -284,7 +285,7 @@ // would make sence if item came from search which isn't // currently the case on the TV - const BOOL singlePlayback = ![[NSUserDefaults standardUserDefaults] boolForKey:kVLCAutomaticallyPlayNextItem]; + const BOOL singlePlayback = !VLCDefaults.shared.automaticallyPlayNextItem; [self didSelectItem:item index:row singlePlayback:singlePlayback]; } diff --git a/Sources/Network/Server List/VLCServerListViewController.m b/Sources/Network/Server List/VLCServerListViewController.m index d188892635c9685751c45d0dcd1ec0d6ae6c98ce..8dbc3aeb69743f64f8ca8cb063af839d8db592e4 100644 --- a/Sources/Network/Server List/VLCServerListViewController.m +++ b/Sources/Network/Server List/VLCServerListViewController.m @@ -82,7 +82,7 @@ return; } - if ([[NSUserDefaults standardUserDefaults] integerForKey:kVLCSettingAppTheme] == kVLCSettingAppThemeSystem) { + if (VLCDefaults.shared.appThemeIsSystem) { [PresentationTheme themeDidUpdate]; } [self themeDidChange]; diff --git a/Sources/Playback/Control/VLCPlaybackService.m b/Sources/Playback/Control/VLCPlaybackService.m index 75663a087e95d917deeea1e83be741298173d960..85d8ffb85f2ad78440853bcd8e1c07b29a4de4e1 100644 --- a/Sources/Playback/Control/VLCPlaybackService.m +++ b/Sources/Playback/Control/VLCPlaybackService.m @@ -220,8 +220,6 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; return; } - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if (!self.mediaList) { APLog(@"%s: no URL and no media list set, stopping playback", __PRETTY_FUNCTION__); [_playbackSessionManagementLock unlock]; @@ -245,12 +243,11 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; /* the chromecast and audio options cannot be set per media, so we need to set it per * media player instance however, potentially initialising an additional library instance * for this is costly, so this should be done only if needed */ - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - BOOL audioTimeStretch = [[userDefaults objectForKey:kVLCSettingStretchAudio] boolValue]; + BOOL audioTimeStretch = VLCDefaults.shared.stretchAudio; NSMutableArray *libVLCOptions = [NSMutableArray array]; #if TARGET_OS_IOS - BOOL chromecastPassthrough = [[userDefaults objectForKey:kVLCSettingCastingAudioPassthrough] boolValue]; - int chromecastQuality = [[userDefaults objectForKey:kVLCSettingCastingConversionQuality] intValue]; + BOOL chromecastPassthrough = VLCDefaults.shared.castingAudioPassthrough; + int chromecastQuality = (int)VLCDefaults.shared.castingConversionQuality; if (chromecastPassthrough) { [libVLCOptions addObject:[@"--" stringByAppendingString:kVLCSettingCastingAudioPassthrough]]; } @@ -275,7 +272,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; consoleLogger.level = kVLCLogLevelDebug; [debugLoggers addObject:consoleLogger]; #endif - BOOL saveDebugLogs = [userDefaults boolForKey:kVLCSaveDebugLogs]; + BOOL saveDebugLogs = VLCDefaults.shared.saveDebugLogs; if (saveDebugLogs) { NSArray *searchPaths; #if TARGET_OS_TV @@ -315,15 +312,15 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; #endif [_mediaPlayer setDelegate:self]; - CGFloat defaultPlaybackSpeed = [[defaults objectForKey:kVLCSettingPlaybackSpeedDefaultValue] floatValue]; + CGFloat defaultPlaybackSpeed = VLCDefaults.shared.playbackSpeedDefaultValue; if (defaultPlaybackSpeed != 0.) [_mediaPlayer setRate: defaultPlaybackSpeed]; - int deinterlace = [[defaults objectForKey:kVLCSettingDeinterlace] intValue]; + int deinterlace = (int)VLCDefaults.shared.deinterlace; [_mediaPlayer setDeinterlace:deinterlace withFilter:@"blend"]; [_listPlayer setMediaList:self.mediaList]; - if ([defaults boolForKey:kVLCPlayerShouldRememberState]) { - VLCRepeatMode repeatMode = [defaults integerForKey:kVLCPlayerIsRepeatEnabled]; + if (VLCDefaults.shared.playerShouldRememberState) { + VLCRepeatMode repeatMode = VLCDefaults.shared.playerIsRepeatEnabled; [_listPlayer setRepeatMode:repeatMode]; } @@ -340,17 +337,16 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; return; } - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - BOOL equalizerEnabled = ![userDefaults boolForKey:kVLCSettingEqualizerProfileDisabled]; + BOOL equalizerEnabled = !VLCDefaults.shared.equalizerProfileDisabled; VLCAudioEqualizer *equalizer; if (equalizerEnabled) { NSArray *presets = [VLCAudioEqualizer presets]; - unsigned int profile = (unsigned int)[userDefaults integerForKey:kVLCSettingEqualizerProfile]; + unsigned int profile = (unsigned int)VLCDefaults.shared.equalizerProfile; equalizer = [[VLCAudioEqualizer alloc] initWithPreset:presets[profile]]; } else { - float preampValue = [userDefaults floatForKey:kVLCSettingDefaultPreampLevel]; + float preampValue = VLCDefaults.shared.defaultPreampLevel; equalizer = [[VLCAudioEqualizer alloc] init]; equalizer.preAmplification = preampValue; } @@ -499,13 +495,13 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; } } - if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingDisableSubtitles]) { + if (VLCDefaults.shared.disableSubtitles) { _mediaPlayer.currentVideoSubTitleIndex = -1; } else { [self selectVideoSubtitleAtIndex:media.subtitleTrackIndex]; } #else - BOOL disableSubtitles = [[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingDisableSubtitles]; + BOOL disableSubtitles = VLCDefaults.shared.disableSubtitles; NSArray *audioTracks = _mediaPlayer.audioTracks; if (media.audioTrackIndex < audioTracks.count) { @@ -580,9 +576,8 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; } [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackServicePlaybackModeUpdated object:self]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:kVLCPlayerShouldRememberState]) { - [defaults setInteger:repeatMode forKey:kVLCPlayerIsRepeatEnabled]; + if (VLCDefaults.shared.playerShouldRememberState) { + VLCDefaults.shared.playerIsRepeatEnabled = repeatMode; } } @@ -859,13 +854,12 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; _mediaPlayer.media.delegate = self; /* on-the-fly values through hidden API */ - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" - [_mediaPlayer performSelector:@selector(setTextRendererFont:) withObject:[defaults objectForKey:kVLCSettingSubtitlesFont]]; - [_mediaPlayer performSelector:@selector(setTextRendererFontSize:) withObject:[defaults objectForKey:kVLCSettingSubtitlesFontSize]]; - [_mediaPlayer performSelector:@selector(setTextRendererFontColor:) withObject:[defaults objectForKey:kVLCSettingSubtitlesFontColor]]; - [_mediaPlayer performSelector:@selector(setTextRendererFontForceBold:) withObject:[defaults objectForKey:kVLCSettingSubtitlesBoldFont]]; + [_mediaPlayer performSelector:@selector(setTextRendererFont:) withObject:VLCDefaults.shared.subtitlesFontSize]; + [_mediaPlayer performSelector:@selector(setTextRendererFontSize:) withObject:VLCDefaults.shared.subtitlesFontSize]; + [_mediaPlayer performSelector:@selector(setTextRendererFontColor:) withObject:VLCDefaults.shared.subtitlesFontColor]; + [_mediaPlayer performSelector:@selector(setTextRendererFontForceBold:) withObject:[NSNumber numberWithBool:VLCDefaults.shared.subtitlesBoldFont]]; #pragma clang diagnostic pop } break; @@ -1018,9 +1012,8 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; [[NSNotificationCenter defaultCenter] postNotificationName:VLCPlaybackServiceShuffleModeUpdated object:self]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ([[defaults valueForKey:kVLCPlayerShouldRememberState] boolValue]) { - [defaults setBool:shuffleMode forKey:kVLCPlayerIsShuffleEnabled]; + if (VLCDefaults.shared.playerShouldRememberState) { + VLCDefaults.shared.playerIsShuffleEnabled = shuffleMode; } } @@ -1080,7 +1073,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; - (BOOL)next { if (_mediaList.count == 1) { - NSNumber *skipLength = [[NSUserDefaults standardUserDefaults] valueForKey:kVLCSettingPlaybackForwardSkipLength]; + NSNumber *skipLength = [NSNumber numberWithInteger:VLCDefaults.shared.playbackForwardSkipLength]; [_mediaPlayer jumpForward:skipLength.intValue]; return YES; } @@ -1133,7 +1126,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; [_listPlayer playItemAtNumber:@(_currentIndex)]; } } else { - NSNumber *skipLength = [[NSUserDefaults standardUserDefaults] valueForKey:kVLCSettingPlaybackBackwardSkipLength]; + NSNumber *skipLength = [NSNumber numberWithInteger:VLCDefaults.shared.playbackBackwardSkipLength]; [_mediaPlayer jumpBackward:skipLength.intValue]; } return YES; @@ -1400,12 +1393,11 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; - (void)resetEqualizerFromProfile:(unsigned int)profile { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; if (profile == 0) { _mediaPlayer.equalizer = nil; - [userDefaults setBool:YES forKey:kVLCSettingEqualizerProfileDisabled]; + VLCDefaults.shared.equalizerProfileDisabled = YES; - float preampValue = [userDefaults floatForKey:kVLCSettingDefaultPreampLevel]; + float preampValue = VLCDefaults.shared.defaultPreampLevel; if (preampValue != 6.0) { APLog(@"Enforcing presumbly disabled equalizer due to custom preamp value of %f2.0", preampValue); VLCAudioEqualizer *eq = [[VLCAudioEqualizer alloc] init]; @@ -1415,10 +1407,10 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; return; } - [userDefaults setBool:NO forKey:kVLCSettingEqualizerProfileDisabled]; + VLCDefaults.shared.equalizerProfileDisabled = NO; unsigned int actualProfile = profile - 1; - [userDefaults setInteger:actualProfile forKey:kVLCSettingEqualizerProfile]; + VLCDefaults.shared.equalizerProfile = actualProfile; NSArray *presets = [VLCAudioEqualizer presets]; VLCAudioEqualizer *equalizer = [[VLCAudioEqualizer alloc] initWithPreset:presets[actualProfile]]; @@ -1442,7 +1434,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; return equalizer.preAmplification; } - return [[NSUserDefaults standardUserDefaults] floatForKey:kVLCSettingDefaultPreampLevel]; + return VLCDefaults.shared.defaultPreampLevel; } - (unsigned int)numberOfBands @@ -1471,16 +1463,16 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; { /* this is a bit complex, if the eq is off, we need to return 0 * if it is on, we need to provide the profile + 1 as the UI fakes a "Off" profile in its list */ - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - if ([userDefaults boolForKey:kVLCSettingEqualizerProfileDisabled]) { + if (VLCDefaults.shared.equalizerProfileDisabled) { return [NSIndexPath indexPathForRow:0 inSection:0]; } - unsigned int actualProfile = (unsigned int)[userDefaults integerForKey:kVLCSettingEqualizerProfile]; - if (![userDefaults boolForKey:kVLCCustomProfileEnabled]) { - return [NSIndexPath indexPathForRow:actualProfile + 1 inSection:0]; - } else { + unsigned int actualProfile = (unsigned int)VLCDefaults.shared.equalizerProfile; + + if (VLCDefaults.shared.customEqualizerProfileEnabled) { return [NSIndexPath indexPathForRow:actualProfile inSection:1]; + } else { + return [NSIndexPath indexPathForRow:actualProfile + 1 inSection:0]; } } #endif @@ -1600,9 +1592,9 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; if (!libraryMedia.isPodcast) { return; } - continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinueAudioPlayback] integerValue]; + continuePlayback = VLCDefaults.shared.continueAudioPlayback; } else { - continuePlayback = [[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinuePlayback] integerValue]; + continuePlayback = VLCDefaults.shared.continuePlayback; } if (continuePlayback == 1) { @@ -1691,7 +1683,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; - (void)disableSubtitlesIfNeeded { - if ([[NSUserDefaults standardUserDefaults] boolForKey:kVLCSettingDisableSubtitles]) { + if (VLCDefaults.shared.disableSubtitles) { [_mediaPlayer deselectAllTextTracks]; } } @@ -1721,8 +1713,7 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; #if !TARGET_OS_TV [self savePlaybackState]; #endif - if (![self isPlayingOnExternalScreen] - && ![[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingContinueAudioInBackgroundKey] boolValue]) { + if (![self isPlayingOnExternalScreen] && !VLCDefaults.shared.continueAudioInBackgroundKey) { if ([_mediaPlayer isPlaying]) { [_mediaPlayer pause]; _shouldResumePlaying = YES; @@ -1777,12 +1768,11 @@ NSString *const VLCLastPlaylistPlayedMedia = @"LastPlaylistPlayedMedia"; - (NSDictionary *)mediaOptionsDictionary { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - return @{ kVLCSettingNetworkCaching : [defaults objectForKey:kVLCSettingNetworkCaching], - kVLCSettingTextEncoding : [defaults objectForKey:kVLCSettingTextEncoding], - kVLCSettingSkipLoopFilter : [defaults objectForKey:kVLCSettingSkipLoopFilter], - kVLCSettingHardwareDecoding : [defaults objectForKey:kVLCSettingHardwareDecoding], - kVLCSettingNetworkRTSPTCP : [defaults objectForKey:kVLCSettingNetworkRTSPTCP] + return @{ @"network-caching" : [NSNumber numberWithInteger:VLCDefaults.shared.networkCachingObjC], + @"subsdec-encoding" : VLCDefaults.shared.textEncoding, + @"avcodec-skiploopfilter" : [NSNumber numberWithInteger:VLCDefaults.shared.skipLoopFilterObjC], + @"codec" : VLCDefaults.shared.hardwareDecodingObjC, + @"rtsp-tcp" : [NSNumber numberWithBool:VLCDefaults.shared.networkRTSPTCP] }; } diff --git a/Sources/Playback/Control/VLCPlayerDisplayController.m b/Sources/Playback/Control/VLCPlayerDisplayController.m index 0ce8275dcd119767c0c7bec7c3d1cea51d1246d2..8070810ac9cc8df89aa962b0992520fe00f0deb2 100644 --- a/Sources/Playback/Control/VLCPlayerDisplayController.m +++ b/Sources/Playback/Control/VLCPlayerDisplayController.m @@ -165,8 +165,7 @@ NSString *const VLCPlayerDisplayControllerHideMiniPlayer = @"VLCPlayerDisplayCon - (void)playbackDidStart:(NSNotification *)notification { - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - BOOL enforceFullscreen = [[defaults objectForKey:kVLCSettingVideoFullscreenPlayback] boolValue]; + BOOL enforceFullscreen = VLCDefaults.shared.videoFullscreenPlayback; VLCMedia *currentMedia = _playbackController.currentlyPlayingMedia; VLCMLMedia *media = [VLCMLMedia mediaForPlayingMedia:currentMedia]; @@ -484,11 +483,9 @@ NSString *const VLCPlayerDisplayControllerHideMiniPlayer = @"VLCPlayerDisplayCon } // Properly set the shuffle and repeat mode - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - if ([userDefaults boolForKey:kVLCPlayerShouldRememberState]) { - _playbackController.shuffleMode = [userDefaults boolForKey:kVLCPlayerIsShuffleEnabled]; - NSInteger repeatMode = [userDefaults integerForKey:kVLCPlayerIsRepeatEnabled]; - _playbackController.repeatMode = repeatMode; + if (VLCDefaults.shared.playerShouldRememberState) { + _playbackController.shuffleMode = VLCDefaults.shared.playerIsShuffleEnabled; + _playbackController.repeatMode = VLCDefaults.shared.playerIsRepeatEnabled; } [self addPlayqueueToMiniPlayer]; @@ -675,13 +672,13 @@ NSString *const VLCPlayerDisplayControllerHideMiniPlayer = @"VLCPlayerDisplayCon - (void)keyLeftArrow { - NSInteger seekBy = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCSettingPlaybackBackwardSkipLength]; + NSInteger seekBy = VLCDefaults.shared.playbackBackwardSkipLength; [_playbackController jumpBackward:(int)seekBy]; } - (void)keyRightArrow { - NSInteger seekBy = [[NSUserDefaults standardUserDefaults] integerForKey:kVLCSettingPlaybackForwardSkipLength]; + NSInteger seekBy = VLCDefaults.shared.playbackForwardSkipLength; [_playbackController jumpForward:(int)seekBy]; } diff --git a/Sources/Playback/OS Integration/VLCRemoteControlService.m b/Sources/Playback/OS Integration/VLCRemoteControlService.m index 4ac418525fff7fbdc52adea8be55de602e8d1553..6399251040510f82d3a4d6e2b47dc846e343a3e1 100644 --- a/Sources/Playback/OS Integration/VLCRemoteControlService.m +++ b/Sources/Playback/OS Integration/VLCRemoteControlService.m @@ -13,6 +13,7 @@ #import "VLCRemoteControlService.h" #import "VLCPlaybackService.h" +#import "VLC-Swift.h" #import <MediaPlayer/MediaPlayer.h> @implementation VLCRemoteControlService @@ -55,13 +56,12 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle(void) - (void)playbackStarted:(NSNotification *)aNotification { MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]; - NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; /* Since the control center and lockscreen shows only either skipForward/Backward * or next/previousTrack buttons but prefers skip buttons, * we only enable skip buttons if we have no medialist */ - BOOL alwaysEnableSkip = [defaults boolForKey:kVLCSettingPlaybackLockscreenSkip]; + BOOL alwaysEnableSkip = VLCDefaults.shared.lockscreenSkip; BOOL enableSkip = alwaysEnableSkip || [VLCPlaybackService sharedInstance].mediaList.count <= 1; commandCenter.skipForwardCommand.enabled = enableSkip; commandCenter.skipBackwardCommand.enabled = enableSkip; @@ -78,9 +78,9 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle(void) commandCenter.seekForwardCommand.enabled = NO; commandCenter.seekBackwardCommand.enabled = NO; - NSNumber *forwardSkip = [defaults valueForKey:kVLCSettingPlaybackForwardSkipLength]; + NSNumber *forwardSkip = [NSNumber numberWithInteger:VLCDefaults.shared.playbackForwardSkipLength]; commandCenter.skipForwardCommand.preferredIntervals = @[forwardSkip]; - NSNumber *backwardSkip = [defaults valueForKey:kVLCSettingPlaybackBackwardSkipLength]; + NSNumber *backwardSkip = [NSNumber numberWithInteger:VLCDefaults.shared.playbackBackwardSkipLength]; commandCenter.skipBackwardCommand.preferredIntervals = @[backwardSkip]; commandCenter.changePlaybackRateCommand.supportedPlaybackRates = @[@(0.5),@(0.75),@(1.0),@(1.25),@(1.5),@(1.75),@(2.0)]; @@ -122,8 +122,8 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle(void) return MPRemoteCommandHandlerStatusSuccess; } if (event.command == cc.nextTrackCommand) { - if ([defaults boolForKey:kVLCSettingPlaybackRemoteControlSkip]) { - NSInteger interval = [defaults integerForKey:kVLCSettingPlaybackForwardSkipLength]; + if (VLCDefaults.shared.remoteControlSkip) { + NSInteger interval = VLCDefaults.shared.playbackForwardSkipLength; [vps jumpForward:(int)interval]; return MPRemoteCommandHandlerStatusSuccess; } else { @@ -132,8 +132,8 @@ static inline NSArray * RemoteCommandCenterCommandsToHandle(void) } } if (event.command == cc.previousTrackCommand) { - if ([defaults boolForKey:kVLCSettingPlaybackRemoteControlSkip]) { - NSInteger interval = [defaults integerForKey:kVLCSettingPlaybackBackwardSkipLength]; + if (VLCDefaults.shared.remoteControlSkip) { + NSInteger interval = VLCDefaults.shared.playbackBackwardSkipLength; [vps jumpBackward:(int)interval]; return MPRemoteCommandHandlerStatusSuccess; diff --git a/Sources/Playback/Player/AudioPlayer/AudioPlayerView.swift b/Sources/Playback/Player/AudioPlayer/AudioPlayerView.swift index 1b94c4be28f1894c6b8b6f6ff2dcb4cb810176c3..3d1e96d45f3902b4ba8fdfd545e8c1a989738fbb 100644 --- a/Sources/Playback/Player/AudioPlayer/AudioPlayerView.swift +++ b/Sources/Playback/Player/AudioPlayer/AudioPlayerView.swift @@ -576,7 +576,7 @@ class AudioPlayerView: UIView, UIGestureRecognizerDelegate { secondaryControlStackView.addArrangedSubview(playbackSpeedButton) - let displaySecondaryStackView: Bool = UserDefaults.standard.bool(forKey: kVLCPlayerShowPlaybackSpeedShortcut) + let displaySecondaryStackView: Bool = VLCDefaults.shared.playerShowPlaybackSpeedShortcut secondaryControlStackView.isHidden = !displaySecondaryStackView } diff --git a/Sources/Playback/Player/AudioPlayer/AudioPlayerViewController.swift b/Sources/Playback/Player/AudioPlayer/AudioPlayerViewController.swift index 189fcee327eb13635b6ae4146f3daeb0e8f1c067..522f61680d8d73845962874d4893df2bdf173f7f 100644 --- a/Sources/Playback/Player/AudioPlayer/AudioPlayerViewController.swift +++ b/Sources/Playback/Player/AudioPlayer/AudioPlayerViewController.swift @@ -126,7 +126,7 @@ class AudioPlayerViewController: PlayerViewController { mediaScrubProgressBar.shouldHideScrubLabels = false #endif - let displayShortcutView: Bool = UserDefaults.standard.bool(forKey: kVLCPlayerShowPlaybackSpeedShortcut) + let displayShortcutView: Bool = VLCDefaults.shared.playerShowPlaybackSpeedShortcut audioPlayerView.shouldDisplaySecondaryStackView(displayShortcutView) } diff --git a/Sources/Playback/Player/MiniPlayer-iOS/AudioMiniPlayer.swift b/Sources/Playback/Player/MiniPlayer-iOS/AudioMiniPlayer.swift index 961431cc9d456efdc633ad7b0947205a0c8b285a..5eb0f534fc64efb03a6fbf9ecf2295888ac599f3 100644 --- a/Sources/Playback/Player/MiniPlayer-iOS/AudioMiniPlayer.swift +++ b/Sources/Playback/Player/MiniPlayer-iOS/AudioMiniPlayer.swift @@ -165,16 +165,13 @@ private extension AudioMiniPlayer { } private func applyCustomEqualizerProfileIfNeeded() { - let userDefaults = UserDefaults.standard - guard userDefaults.bool(forKey: kVLCCustomProfileEnabled) else { + guard VLCDefaults.shared.customEqualizerProfileEnabled else { return } - let profileIndex = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) - let encodedData = userDefaults.data(forKey: kVLCCustomEqualizerProfiles) + let profileIndex = VLCDefaults.shared.equalizerProfile - guard let encodedData = encodedData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: encodedData).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles, profileIndex < customProfiles.profiles.count else { return } diff --git a/Sources/Playback/Player/PlayerViewController.swift b/Sources/Playback/Player/PlayerViewController.swift index 092f048a3afc87f92fd0dff4464deaf7f319a018..8d98b0b5758e6ca5c9a4a3af2fdf62437575f6c4 100644 --- a/Sources/Playback/Player/PlayerViewController.swift +++ b/Sources/Playback/Player/PlayerViewController.swift @@ -314,8 +314,6 @@ class PlayerViewController: UIViewController { private let notificationCenter = NotificationCenter.default - private let userDefaults = UserDefaults.standard - // MARK: - Gestures lazy var panRecognizer: UIPanGestureRecognizer = { @@ -436,8 +434,8 @@ class PlayerViewController: UIViewController { super.viewDidAppear(animated) if playerController.isRememberBrightnessEnabled && self is VideoPlayerViewController { - if let brightness = userDefaults.value(forKey: KVLCPlayerBrightness) as? CGFloat { - animateBrightness(to: brightness) + if let brightness = VLCDefaults.shared.playerBrightness { + animateBrightness(to: CGFloat(brightness)) self.brightnessControl.value = Float(brightness) } } @@ -458,9 +456,9 @@ class PlayerViewController: UIViewController { super.viewDidDisappear(animated) if playerController.isRememberBrightnessEnabled && self is VideoPlayerViewController { - let currentBrightness = UIScreen.main.brightness - self.brightnessControl.value = Float(currentBrightness) // helper in indicating change in the system brightness - userDefaults.set(currentBrightness, forKey: KVLCPlayerBrightness) + let currentBrightness = Float(UIScreen.main.brightness) + self.brightnessControl.value = currentBrightness // helper in indicating change in the system brightness + VLCDefaults.shared.playerBrightness = currentBrightness } //set the value of system brightness after closing the app //even if the Player Should Remember Brightness option is disabled @@ -736,13 +734,11 @@ class PlayerViewController: UIViewController { } private func setupSeekDurations() { - let defaults = UserDefaults.standard - - tapSwipeEqual = defaults.bool(forKey: kVLCSettingPlaybackTapSwipeEqual) - forwardBackwardEqual = defaults.bool(forKey: kVLCSettingPlaybackForwardBackwardEqual) - seekForwardBy = defaults.integer(forKey: kVLCSettingPlaybackForwardSkipLength) - seekBackwardBy = forwardBackwardEqual ? seekForwardBy : defaults.integer(forKey: kVLCSettingPlaybackBackwardSkipLength) - seekForwardBySwipe = tapSwipeEqual ? seekForwardBy : defaults.integer(forKey: kVLCSettingPlaybackForwardSkipLengthSwipe) + tapSwipeEqual = VLCDefaults.shared.playbackTapSwipeEqual + forwardBackwardEqual = VLCDefaults.shared.playbackForwardBackwardEqual + seekForwardBy = VLCDefaults.shared.playbackForwardSkipLength + seekBackwardBy = forwardBackwardEqual ? seekForwardBy : VLCDefaults.shared.playbackBackwardSkipLength + seekForwardBySwipe = tapSwipeEqual ? seekForwardBy : VLCDefaults.shared.playbackForwardSkipLengthSwipe if tapSwipeEqual, forwardBackwardEqual { // if tap = swipe, and backward = forward, then backward swipe = forward tap @@ -755,21 +751,18 @@ class PlayerViewController: UIViewController { seekBackwardBySwipe = seekForwardBySwipe } else { // otherwise backward swipe = backward swipe - seekBackwardBySwipe = defaults.integer(forKey: kVLCSettingPlaybackBackwardSkipLengthSwipe) + seekBackwardBySwipe = VLCDefaults.shared.playbackBackwardSkipLengthSwipe } } private func applyCustomEqualizerProfileIfNeeded() { - let userDefaults = UserDefaults.standard - guard userDefaults.bool(forKey: kVLCCustomProfileEnabled) else { + guard VLCDefaults.shared.customEqualizerProfileEnabled else { return } - let profileIndex = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) - let encodedData = userDefaults.data(forKey: kVLCCustomEqualizerProfiles) + let profileIndex = VLCDefaults.shared.equalizerProfile - guard let encodedData = encodedData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: encodedData).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles, profileIndex < customProfiles.profiles.count else { return } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/MediaScrubProgressBar.swift b/Sources/Playback/Player/VideoPlayer-iOS/MediaScrubProgressBar.swift index 46e0832491e97094b70352de0669aaef73b3b047..ecf7f0dd1cd976dbde1aa9c4e16f694f2d3a440a 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/MediaScrubProgressBar.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/MediaScrubProgressBar.swift @@ -144,14 +144,12 @@ class MediaScrubProgressBar: UIStackView { } @objc private func handleAccessibilityForward() -> Bool { - let defaults = UserDefaults.standard - playbackService.jumpForward(Int32(defaults.integer(forKey: kVLCSettingPlaybackForwardSkipLength))) + playbackService.jumpForward(Int32(VLCDefaults.shared.playbackForwardSkipLength)) return true } @objc private func handleAccessibilityBackward() -> Bool { - let defaults = UserDefaults.standard - playbackService.jumpBackward(Int32(defaults.integer(forKey: kVLCSettingPlaybackBackwardSkipLength))) + playbackService.jumpBackward(Int32(VLCDefaults.shared.playbackBackwardSkipLength)) return true } @@ -417,8 +415,7 @@ fileprivate enum RemainingTimeMode { case remaining static var current: RemainingTimeMode { - let userDefault = UserDefaults.standard - let currentSetting = userDefault.bool(forKey: kVLCShowRemainingTime) + let currentSetting = VLCDefaults.shared.showRemainingTime switch currentSetting { case true: return .remaining @@ -428,8 +425,7 @@ fileprivate enum RemainingTimeMode { @discardableResult static func toggle() -> RemainingTimeMode { - let userDefault = UserDefaults.standard - userDefault.set(!userDefault.bool(forKey: kVLCShowRemainingTime), forKey: kVLCShowRemainingTime) + VLCDefaults.shared.showRemainingTime.toggle() return current } } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/PlayerController.swift b/Sources/Playback/Player/VideoPlayer-iOS/PlayerController.swift index 07217a3b4143fdabf3de4928861f82f0081ed154..978c7dc506ebcb2d5837afc6b573787a1873d7fd 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/PlayerController.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/PlayerController.swift @@ -38,52 +38,50 @@ class PlayerController: NSObject { var isTapSeeking: Bool = false - // MARK: - UserDefaults computed properties getters + // MARK: - Defaults computed properties getters var displayRemainingTime: Bool { - return UserDefaults.standard.bool(forKey: kVLCShowRemainingTime) + return VLCDefaults.shared.showRemainingTime } var isVolumeGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingVolumeGesture) + return VLCDefaults.shared.volumeGesture } var isPlayPauseGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingPlayPauseGesture) + return VLCDefaults.shared.playPauseGesture } var isBrightnessGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingBrightnessGesture) + return VLCDefaults.shared.brightnessGesture } var isSwipeSeekGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingSeekGesture) + return VLCDefaults.shared.seekGesture } var isCloseGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingCloseGesture) + return VLCDefaults.shared.closeGesture } var isSpeedUpGestureEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingPlaybackLongTouchSpeedUp) + return VLCDefaults.shared.playbackLongTouchSpeedUp } var isShuffleEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCPlayerIsShuffleEnabled) + return VLCDefaults.shared.playerIsShuffleEnabled } var isRepeatEnabled: VLCRepeatMode { - let storedValue = UserDefaults.standard.integer(forKey: kVLCPlayerIsRepeatEnabled) - - return VLCRepeatMode(rawValue: storedValue) ?? .doNotRepeat + return VLCDefaults.shared.playerIsRepeatEnabled } var isRememberStateEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCPlayerShouldRememberState) + return VLCDefaults.shared.playerShouldRememberState } var isRememberBrightnessEnabled: Bool { - return UserDefaults.standard.bool(forKey: kVLCPlayerShouldRememberBrightness) + return VLCDefaults.shared.playerShouldRememberBrightness } @objc override init() { @@ -91,10 +89,6 @@ class PlayerController: NSObject { setupObservers() } - func updateUserDefaults() { - - } - private func setupObservers() { let notificationCenter = NotificationCenter.default diff --git a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/CustomEqualizerProfiles.swift b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/CustomEqualizerProfiles.swift index 1ee4d69a20596083f34ec97751cc350f5189df68..657428ff19a3347089ef1c11e8fbf73dfbb8939b 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/CustomEqualizerProfiles.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/CustomEqualizerProfiles.swift @@ -87,14 +87,13 @@ class CustomEqualizerProfiles: NSObject, NSCoding { profiles.swapAt(index, index - 1) - let userDefaults = UserDefaults.standard - if userDefaults.bool(forKey: kVLCCustomProfileEnabled) { - let currentProfileIndex = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) + if VLCDefaults.shared.customEqualizerProfileEnabled { + let currentProfileIndex = VLCDefaults.shared.equalizerProfile if currentProfileIndex == index { - userDefaults.setValue(index - 1, forKeyPath: kVLCSettingEqualizerProfile) + VLCDefaults.shared.equalizerProfile = index - 1 } else if currentProfileIndex == index - 1 { - userDefaults.setValue(index, forKey: kVLCSettingEqualizerProfile) + VLCDefaults.shared.equalizerProfile = index } } } @@ -106,14 +105,13 @@ class CustomEqualizerProfiles: NSObject, NSCoding { profiles.swapAt(index, index + 1) - let userDefaults = UserDefaults.standard - if userDefaults.bool(forKey: kVLCCustomProfileEnabled) { - let currentProfileIndex = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) + if VLCDefaults.shared.customEqualizerProfileEnabled { + let currentProfileIndex = VLCDefaults.shared.equalizerProfile if currentProfileIndex == index { - userDefaults.setValue(index + 1, forKeyPath: kVLCSettingEqualizerProfile) + VLCDefaults.shared.equalizerProfile = index + 1 } else if currentProfileIndex == index + 1 { - userDefaults.setValue(index, forKey: kVLCSettingEqualizerProfile) + VLCDefaults.shared.equalizerProfile = index } } } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerPresetSelector.swift b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerPresetSelector.swift index f26875a6be87daed31e2c7f34856127a49981bc7..d1165f808a3754834a3426546f966f6d265b69b8 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerPresetSelector.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerPresetSelector.swift @@ -102,9 +102,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView // MARK: - table view data source func numberOfSections(in tableView: UITableView) -> Int { - let profilesData = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - guard let profilesData = profilesData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: profilesData).decodeObject(forKey: "root") as? CustomEqualizerProfiles else { + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles else { return 1 } @@ -117,9 +115,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView return profiles.count + 1 } - let profilesData = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - guard let profilesData = profilesData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: profilesData).decodeObject(forKey: "root") as? CustomEqualizerProfiles else { + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles else { return 0 } @@ -137,9 +133,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView cell.textLabel?.text = profiles[indexPath.row - 1].name } } else { - let profilesData = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - guard let profilesData = profilesData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: profilesData).decodeObject(forKey: "root") as? CustomEqualizerProfiles else { + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles else { return cell } @@ -179,7 +173,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: false) let isCustomProfile: Bool = indexPath.section == 0 ? false : true - UserDefaults.standard.setValue(isCustomProfile, forKey: kVLCCustomProfileEnabled) + VLCDefaults.shared.customEqualizerProfileEnabled = isCustomProfile delegate?.equalizerPresetSelector(self, didSelectPreset: indexPath.row, isCustom: isCustomProfile) presetsTableView.reloadData() toggleHiddenView() @@ -232,10 +226,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView } func moveProfile(_ moveIdentifier: MoveEventIdentifier, at index: IndexPath) { - let userDefaults = UserDefaults.standard - let profilesData = userDefaults.data(forKey: kVLCCustomEqualizerProfiles) - guard let profilesData = profilesData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: profilesData).decodeObject(forKey: "root") as? CustomEqualizerProfiles else { + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles else { return } @@ -245,7 +236,7 @@ class EqualizerPresetSelector: SpoilerButton, UITableViewDataSource, UITableView customProfiles.moveDown(index: index.row) } - userDefaults.setValue(NSKeyedArchiver.archivedData(withRootObject: customProfiles), forKey: kVLCCustomEqualizerProfiles) + VLCDefaults.shared.customEqualizerProfiles = customProfiles } } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerView.swift b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerView.swift index 21eed831aa28e6020e07a551ba75f67e2e8747a0..3d39b2732679efa5a4417e0711161399f7589349 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerView.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/EqualizerView.swift @@ -214,7 +214,7 @@ import UIKit snapBandsLabel.text = NSLocalizedString("SNAP_BANDS", comment: "") snapBandsLabel.textAlignment = .right snapBandsLabel.setContentHuggingPriority(.required, for: .vertical) - snapBandsSwitch.isOn = UserDefaults.standard.bool(forKey: kVLCEqualizerSnapBands) + snapBandsSwitch.isOn = VLCDefaults.shared.equalizerSnapBands snapBandsSwitch.addTarget(self, action: #selector(snapBandsSwitchDidChangeValue), for: .valueChanged) snapBandsSwitch.setContentHuggingPriority(.required, for: .vertical) snapBandsStackView.addArrangedSubview(snapBandsLabel) @@ -419,7 +419,7 @@ extension EqualizerView { extension EqualizerView { @objc func snapBandsSwitchDidChangeValue(sender: UISwitch) { - UserDefaults.standard.setValue(sender.isOn, forKey: kVLCEqualizerSnapBands) + VLCDefaults.shared.equalizerSnapBands = sender.isOn } } @@ -447,11 +447,9 @@ extension EqualizerView { let preAmplification = self.playbackService.preAmplification let customProfile = CustomEqualizerProfile(name: name, preAmpLevel: Float(preAmplification), frequencies: frequencies) - let encodedProfiles = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - var customProfiles: CustomEqualizerProfiles + let customProfiles: CustomEqualizerProfiles - if let encodedProfiles = encodedProfiles, - let profiles = NSKeyedUnarchiver(forReadingWith: encodedProfiles).decodeObject(forKey: "root") as? CustomEqualizerProfiles { + if let profiles = VLCDefaults.shared.customEqualizerProfiles { profiles.profiles.append(customProfile) customProfiles = profiles } else { @@ -459,11 +457,10 @@ extension EqualizerView { } let index = customProfiles.profiles.count - 1 - let userDefaults = UserDefaults.standard - userDefaults.setValue(NSKeyedArchiver.archivedData(withRootObject: customProfiles), forKey: kVLCCustomEqualizerProfiles) - userDefaults.setValue(true, forKey: kVLCCustomProfileEnabled) - userDefaults.setValue(false, forKey: kVLCSettingEqualizerProfileDisabled) - userDefaults.setValue(index, forKey: kVLCSettingEqualizerProfile) + VLCDefaults.shared.customEqualizerProfiles = customProfiles + VLCDefaults.shared.customEqualizerProfileEnabled = true + VLCDefaults.shared.equalizerProfileDisabled = false + VLCDefaults.shared.equalizerProfile = index self.presetSelectorView?.presetsTableView.reloadData() self.shouldDisplaySaveButton(false) @@ -479,16 +476,15 @@ extension EqualizerView { } @objc func resetEqualizer() { - let userDefaults = UserDefaults.standard - let isEqualizerDisabled = userDefaults.bool(forKey: kVLCSettingEqualizerProfileDisabled) - let isCustomProfile = userDefaults.bool(forKey: kVLCCustomProfileEnabled) + let isEqualizerDisabled = VLCDefaults.shared.equalizerProfileDisabled + let isCustomProfile = VLCDefaults.shared.customEqualizerProfileEnabled let profile: Int if !isCustomProfile { - profile = isEqualizerDisabled ? 0 : userDefaults.integer(forKey: kVLCSettingEqualizerProfile) + 1 + profile = isEqualizerDisabled ? 0 : VLCDefaults.shared.equalizerProfile + 1 delegate?.resetEqualizer(fromProfile: UInt32(profile)) } else { - profile = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) + profile = VLCDefaults.shared.equalizerProfile applyCustomProfile(profile) } @@ -502,11 +498,7 @@ extension EqualizerView { } private func applyCustomProfile(_ index: Int) { - let userDefaults = UserDefaults.standard - let encodedData = userDefaults.data(forKey: kVLCCustomEqualizerProfiles) - - guard let encodedData = encodedData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: encodedData).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles, index < customProfiles.profiles.count else { return } @@ -518,9 +510,9 @@ extension EqualizerView { playbackService.setAmplification(CGFloat(frequency), forBand: UInt32(bandIndex)) } - userDefaults.setValue(index, forKey: kVLCSettingEqualizerProfile) - userDefaults.setValue(false, forKey: kVLCSettingEqualizerProfileDisabled) - userDefaults.setValue(true, forKey: kVLCCustomProfileEnabled) + VLCDefaults.shared.equalizerProfile = index + VLCDefaults.shared.equalizerProfileDisabled = false + VLCDefaults.shared.customEqualizerProfileEnabled = true } private func shouldDisplaySaveButton(_ display: Bool) { @@ -558,15 +550,13 @@ extension EqualizerView: EqualizerPresetSelectorDelegate { if type == .delete { action = UIAlertAction(title: NSLocalizedString("BUTTON_DELETE", comment: ""), style: .destructive) { _ in - let customEncodedProfiles = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - guard let customEncodedProfiles = customEncodedProfiles, - var customProfiles = NSKeyedUnarchiver(forReadingWith: customEncodedProfiles).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard var customProfiles = VLCDefaults.shared.customEqualizerProfiles, index.row < customProfiles.profiles.count else { return } customProfiles.profiles.remove(at: index.row) - UserDefaults.standard.setValue(NSKeyedArchiver.archivedData(withRootObject: customProfiles), forKey: kVLCCustomEqualizerProfiles) + VLCDefaults.shared.customEqualizerProfiles = customProfiles self.presetSelectorView?.presetsTableView.reloadData() } } else { @@ -576,9 +566,7 @@ extension EqualizerView: EqualizerPresetSelectorDelegate { } action = UIAlertAction(title: NSLocalizedString("BUTTON_RENAME", comment: ""), style: .default) { _ in - let customEncodedProfiles = UserDefaults.standard.data(forKey: kVLCCustomEqualizerProfiles) - guard let customEncodedProfiles = customEncodedProfiles, - let customProfiles = NSKeyedUnarchiver(forReadingWith: customEncodedProfiles).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles, index.row < customProfiles.profiles.count else { return } @@ -589,7 +577,7 @@ extension EqualizerView: EqualizerPresetSelectorDelegate { } customProfiles.profiles[index.row].name = newName - UserDefaults.standard.setValue(NSKeyedArchiver.archivedData(withRootObject: customProfiles), forKey: kVLCCustomEqualizerProfiles) + VLCDefaults.shared.customEqualizerProfiles = customProfiles self.presetSelectorView?.presetsTableView.reloadData() } } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/PlaybackSpeedView.swift b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/PlaybackSpeedView.swift index d81e91b2e96835c6d49b78d6cdaed7135fc655c3..d53050b291b2926ff06092904f64b4465cec663c 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/Subviews/PlaybackSpeedView.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/Subviews/PlaybackSpeedView.swift @@ -50,7 +50,7 @@ class PlaybackSpeedView: UIView { private var currentSpeed: Float = 1.0 private let defaultDelay: Float = 0.0 - private var defaultSpeed: Float = UserDefaults.standard.float(forKey: kVLCSettingPlaybackSpeedDefaultValue) + private var defaultSpeed: Float = VLCDefaults.shared.playbackSpeedDefaultValue let vpc = PlaybackService.sharedInstance() let notificationCenter = NotificationCenter.default @@ -164,7 +164,7 @@ class PlaybackSpeedView: UIView { shortcutLabel.text = NSLocalizedString("DISPLAY_PLAYBACK_SPEED_SHORTCUT", comment: "") shortcutLabel.accessibilityLabel = NSLocalizedString("DISPLAY_PLAYBACK_SPEED_SHORTCUT", comment: "") shortcutLabel.accessibilityHint = NSLocalizedString("DISPLAY_PLAYBACK_SPEED_SHORTCUT_HINT", comment: "") - shortcutSwitch.isOn = UserDefaults.standard.bool(forKey: kVLCPlayerShowPlaybackSpeedShortcut) + shortcutSwitch.isOn = VLCDefaults.shared.playerShowPlaybackSpeedShortcut } @objc func playbackSpeedHasChanged(_ notification: NSNotification) { @@ -264,7 +264,7 @@ class PlaybackSpeedView: UIView { } func reset() { - defaultSpeed = UserDefaults.standard.float(forKey: kVLCSettingPlaybackSpeedDefaultValue) + defaultSpeed = VLCDefaults.shared.playbackSpeedDefaultValue currentSpeed = defaultSpeed vpc.playbackRate = currentSpeed notificationCenter.post(name: Notification.Name("ChangePlaybackSpeed"), object: nil) @@ -345,7 +345,7 @@ class PlaybackSpeedView: UIView { @IBAction func handleShortcutSwitch(_ sender: Any) { let isSwitchOn: Bool = shortcutSwitch.isOn - UserDefaults.standard.setValue(isSwitchOn, forKey: kVLCPlayerShowPlaybackSpeedShortcut) + VLCDefaults.shared.playerShowPlaybackSpeedShortcut = isSwitchOn delegate?.playbackSpeedViewHandleShortcutSwitchChange(displayView: isSwitchOn) } } diff --git a/Sources/Playback/Player/VideoPlayer-iOS/VideoPlayerViewController.swift b/Sources/Playback/Player/VideoPlayer-iOS/VideoPlayerViewController.swift index 33dde55a82f41e053a65dac71833a35e1e15fed4..bab5c9a09114893c6a24a8561200fddabe934ae7 100644 --- a/Sources/Playback/Player/VideoPlayer-iOS/VideoPlayerViewController.swift +++ b/Sources/Playback/Player/VideoPlayer-iOS/VideoPlayerViewController.swift @@ -401,11 +401,10 @@ class VideoPlayerViewController: PlayerViewController { super.viewDidAppear(animated) #if os(iOS) - let defaults = UserDefaults.standard - if defaults.bool(forKey: kVLCPlayerShouldRememberBrightness) { - if let brightness = defaults.value(forKey: KVLCPlayerBrightness) as? CGFloat { - animateBrightness(to: brightness) - self.brightnessControl.value = Float(brightness) + if VLCDefaults.shared.playerShouldRememberBrightness { + if let brightness = VLCDefaults.shared.playerBrightness { + animateBrightness(to: CGFloat(brightness)) + self.brightnessControl.value = brightness } } #endif @@ -468,11 +467,10 @@ class VideoPlayerViewController: PlayerViewController { super.viewDidDisappear(animated) deviceMotion.stopDeviceMotion() #if os(iOS) - let defaults = UserDefaults.standard - if defaults.bool(forKey: kVLCPlayerShouldRememberBrightness) { - let currentBrightness = UIScreen.main.brightness - self.brightnessControl.value = Float(currentBrightness) // helper in indicating change in the system brightness - defaults.set(currentBrightness, forKey: KVLCPlayerBrightness) + if VLCDefaults.shared.playerShouldRememberBrightness { + let currentBrightness = Float(UIScreen.main.brightness) + self.brightnessControl.value = currentBrightness // helper in indicating change in the system brightness + VLCDefaults.shared.playerBrightness = currentBrightness } //set the value of system brightness after closing the app x @@ -865,13 +863,11 @@ class VideoPlayerViewController: PlayerViewController { } private func setupSeekDurations() { - let defaults = UserDefaults.standard - - tapSwipeEqual = defaults.bool(forKey: kVLCSettingPlaybackTapSwipeEqual) - forwardBackwardEqual = defaults.bool(forKey: kVLCSettingPlaybackForwardBackwardEqual) - seekForwardBy = defaults.integer(forKey: kVLCSettingPlaybackForwardSkipLength) - seekBackwardBy = forwardBackwardEqual ? seekForwardBy : defaults.integer(forKey: kVLCSettingPlaybackBackwardSkipLength) - seekForwardBySwipe = tapSwipeEqual ? seekForwardBy : defaults.integer(forKey: kVLCSettingPlaybackForwardSkipLengthSwipe) + tapSwipeEqual = VLCDefaults.shared.playbackTapSwipeEqual + forwardBackwardEqual = VLCDefaults.shared.playbackForwardBackwardEqual + seekForwardBy = VLCDefaults.shared.playbackForwardSkipLength + seekBackwardBy = forwardBackwardEqual ? seekForwardBy : VLCDefaults.shared.playbackBackwardSkipLength + seekForwardBySwipe = tapSwipeEqual ? seekForwardBy : VLCDefaults.shared.playbackForwardSkipLengthSwipe if tapSwipeEqual, forwardBackwardEqual { // if tap = swipe, and backward = forward, then backward swipe = forward tap @@ -884,7 +880,7 @@ class VideoPlayerViewController: PlayerViewController { seekBackwardBySwipe = seekForwardBySwipe } else { // otherwise backward swipe = backward swipe - seekBackwardBySwipe = defaults.integer(forKey: kVLCSettingPlaybackBackwardSkipLengthSwipe) + seekBackwardBySwipe = VLCDefaults.shared.playbackBackwardSkipLengthSwipe } } @@ -992,7 +988,7 @@ class VideoPlayerViewController: PlayerViewController { } @objc func handleTapOnVideo() { - if UserDefaults.standard.bool(forKey: kVLCSettingPauseWhenShowingControls) && playbackService.isPlaying { + if VLCDefaults.shared.pauseWhenShowingControls && playbackService.isPlaying { playbackService.pause() } @@ -1349,8 +1345,7 @@ class VideoPlayerViewController: PlayerViewController { } private func resetIdleTimer() { - let intervalSetting = UserDefaults.standard - .integer(forKey: kVLCSettingPlayerControlDuration) + let intervalSetting = VLCDefaults.shared.playerControlDuration let interval = TimeInterval(max(intervalSetting, 4)) @@ -1385,16 +1380,13 @@ class VideoPlayerViewController: PlayerViewController { } private func applyCustomEqualizerProfileIfNeeded() { - let userDefaults = UserDefaults.standard - guard userDefaults.bool(forKey: kVLCCustomProfileEnabled) else { + guard VLCDefaults.shared.customEqualizerProfileEnabled else { return } - let profileIndex = userDefaults.integer(forKey: kVLCSettingEqualizerProfile) - let encodedData = userDefaults.data(forKey: kVLCCustomEqualizerProfiles) + let profileIndex = VLCDefaults.shared.equalizerProfile - guard let encodedData = encodedData, - let customProfiles = NSKeyedUnarchiver(forReadingWith: encodedData).decodeObject(forKey: "root") as? CustomEqualizerProfiles, + guard let customProfiles = VLCDefaults.shared.customEqualizerProfiles, profileIndex < customProfiles.profiles.count else { return } @@ -1535,7 +1527,7 @@ extension VideoPlayerViewController { if currentState == .opening { updateAudioInterface(with: playbackService.metadata) - if UserDefaults.standard.bool(forKey: kVLCSettingRotationLock) { + if VLCDefaults.shared.rotationLock { videoPlayerControls.handleRotationLockButton(videoPlayerControls) } } diff --git a/Sources/Playback/Player/VideoPlayer-tvOS/Playback Info/VLCPlaybackInfoPlaybackTVViewController.m b/Sources/Playback/Player/VideoPlayer-tvOS/Playback Info/VLCPlaybackInfoPlaybackTVViewController.m index 51f2fa49c4f8489148c6379afed543f40d1040a9..201fc1410699337ca979fd9c43ba199e42b5cfec 100644 --- a/Sources/Playback/Player/VideoPlayer-tvOS/Playback Info/VLCPlaybackInfoPlaybackTVViewController.m +++ b/Sources/Playback/Player/VideoPlayer-tvOS/Playback Info/VLCPlaybackInfoPlaybackTVViewController.m @@ -12,6 +12,7 @@ *****************************************************************************/ #import "VLCPlaybackInfoPlaybackTVViewController.h" +#import "VLC-Swift.h" @interface VLCPlaybackInfoPlaybackTVViewController () @property (nonatomic) VLCPlaybackService *playbackService; @@ -93,7 +94,7 @@ _decreaseSpeed = -0.05; _defaultDelay = 0.0; - _defaultSpeed = [[[NSUserDefaults standardUserDefaults] valueForKey:kVLCSettingPlaybackSpeedDefaultValue] doubleValue]; + _defaultSpeed = (double)VLCDefaults.shared.playbackSpeedDefaultValue; _titleLabel.textColor = UIColor.VLCLightTextColor; _valueLabel.textColor = UIColor.VLCLightTextColor; diff --git a/Sources/Playback/Player/VideoPlayer-tvOS/VLCFullscreenMovieTVViewController.m b/Sources/Playback/Player/VideoPlayer-tvOS/VLCFullscreenMovieTVViewController.m index c1d89fe983b830fb73976a37d7279654675b25ed..acb41cefcae7d3a5fe27d65f6262b4d32c662478 100644 --- a/Sources/Playback/Player/VideoPlayer-tvOS/VLCFullscreenMovieTVViewController.m +++ b/Sources/Playback/Player/VideoPlayer-tvOS/VLCFullscreenMovieTVViewController.m @@ -18,6 +18,7 @@ #import "VLCNetworkImageView.h" #import "VLCMetaData.h" #import "VLCActivityManager.h" +#import "VLC-Swift.h" typedef NS_ENUM(NSInteger, VLCPlayerScanState) { @@ -172,12 +173,12 @@ typedef NS_ENUM(NSInteger, VLCPlayerScanState) vpc.delegate = self; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:kVLCPlayerShouldRememberState]) { - vpc.shuffleMode = [defaults boolForKey:kVLCPlayerIsShuffleEnabled]; - vpc.repeatMode = [defaults integerForKey:kVLCPlayerIsRepeatEnabled]; + if (VLCDefaults.shared.playerShouldRememberState) { + vpc.shuffleMode = VLCDefaults.shared.playerIsShuffleEnabled; + vpc.repeatMode = VLCDefaults.shared.playerIsRepeatEnabled; } - self.playbackUIShouldHide = [defaults boolForKey:kVLCPlayerUIShouldHide]; + self.playbackUIShouldHide = VLCDefaults.shared.playerUIShouldHide; if (self.playbackUIShouldHide) { self.activityIndicator.alpha = 0.; [self.activityIndicator stopAnimating]; diff --git a/Sources/Playback/Subtitles Downloading/VLCPlaybackInfoSubtitlesFetcherViewController.m b/Sources/Playback/Subtitles Downloading/VLCPlaybackInfoSubtitlesFetcherViewController.m index 8320861dd724d9416963bf3af87a0c9297c92ad8..144e28ad3635d5406f9dc9d3288d44d3ca45dc28 100644 --- a/Sources/Playback/Subtitles Downloading/VLCPlaybackInfoSubtitlesFetcherViewController.m +++ b/Sources/Playback/Subtitles Downloading/VLCPlaybackInfoSubtitlesFetcherViewController.m @@ -231,7 +231,7 @@ return; } - if ([[NSUserDefaults standardUserDefaults] integerForKey:kVLCSettingAppTheme] == kVLCSettingAppThemeSystem) { + if (VLCDefaults.shared.appThemeIsSystem) { [PresentationTheme themeDidUpdate]; } [self themeDidChange]; diff --git a/Sources/Settings/Controller/PasscodeLockController.swift b/Sources/Settings/Controller/PasscodeLockController.swift index 6bfedb1a38c9a6ab1bc756063ada5682d57a77fd..dc76f785539dad814aaa29b5381659cc6a54b0cd 100644 --- a/Sources/Settings/Controller/PasscodeLockController.swift +++ b/Sources/Settings/Controller/PasscodeLockController.swift @@ -24,7 +24,6 @@ enum PasscodeAction { class PasscodeLockController: UIViewController { // - MARK: Properties - private let userDefaults = UserDefaults.standard private let notificationCenter = NotificationCenter.default let action: PasscodeAction diff --git a/Sources/Settings/Controller/SettingsController.swift b/Sources/Settings/Controller/SettingsController.swift index bd9aa32be8d81aa9d54793aa073796afd6851f6c..14ccd5584fdf2fc8c8f5e420d411a682510937c3 100644 --- a/Sources/Settings/Controller/SettingsController.swift +++ b/Sources/Settings/Controller/SettingsController.swift @@ -11,6 +11,7 @@ * Diogo Simao Marques <dogo@videolabs.io> * Felix Paul Kühne <fkuehne # videolan.org> * Andrew Breckenridge <asbreckenridge@me.com> + * Craig Reyenga <craig.reyenga # gmail.com> * * Refer to the COPYING file of the official project for license. *****************************************************************************/ @@ -20,13 +21,13 @@ import UIKit extension Notification.Name { static let VLCDisableGroupingDidChangeNotification = Notification.Name("disableGroupingDidChangeNotfication") + static let VLCSettingsShouldReloadNotification = Notification.Name("settingsShouldReloadNotification") } class SettingsController: UITableViewController { private let cellReuseIdentifier = "settingsCell" private let sectionHeaderReuseIdentifier = "sectionHeaderReuseIdentifier" private let sectionFooterReuseIdentifier = "sectionFooterReuseIdentifier" - private let userDefaults = UserDefaults.standard private let notificationCenter = NotificationCenter.default private let actionSheet = ActionSheet() private let specifierManager = ActionSheetSpecifier() @@ -95,7 +96,11 @@ class SettingsController: UITableViewController { private func addObservers() { notificationCenter.addObserver(self, selector: #selector(reloadSettingsSections), - name: UserDefaults.didChangeNotification, + name: .VLCDefaultsDidUpdate, + object: nil) + notificationCenter.addObserver(self, + selector: #selector(reloadSettingsSections), + name: .VLCSettingsShouldReloadNotification, object: nil) notificationCenter.addObserver(self, selector: #selector(themeDidChange), @@ -256,7 +261,7 @@ class SettingsController: UITableViewController { actionSheet.numberOfColums = numberOfColumns present(actionSheet, animated: false) { - if preferenceKey != kVLCAutomaticallyPlayNextItem { + if preferenceKey != VLCDefaults.Compat.automaticallyPlayNextItemKey { self.actionSheet.collectionView.selectItem(at: self.specifierManager.selectedIndex, animated: false, scrollPosition: .centeredVertically) } } @@ -296,19 +301,18 @@ class SettingsController: UITableViewController { } private func resetOptions() { - // note that [NSUserDefaults resetStandardUserDefaults] will NOT correctly reset to the defaults - let appDomain = Bundle.main.bundleIdentifier! - UserDefaults().removePersistentDomain(forName: appDomain) + VLCDefaults.shared.reset() } } extension SettingsController { @objc func reloadSettingsSections() { settingsSections = SettingsSection - .sections(isLabActivated: isLabActivated, + .sections(mediaLibraryService: mediaLibraryService, + isLabActivated: isLabActivated, isBackingUp: isBackingUp, - isForwardBackwardEqual: userDefaults.bool(forKey: kVLCSettingPlaybackForwardBackwardEqual), - isTapSwipeEqual: userDefaults.bool(forKey: kVLCSettingPlaybackTapSwipeEqual)) + isForwardBackwardEqual: VLCDefaults.shared.playbackForwardBackwardEqual, + isTapSwipeEqual: VLCDefaults.shared.playbackTapSwipeEqual) } override func numberOfSections(in _: UITableView) -> Int { @@ -428,21 +432,6 @@ extension SettingsController: MediaLibraryHidingDelegate { // MARK: - SwitchOn Delegates extension SettingsController: SettingsCellDelegate { - func settingsCellDidChangeSwitchState(cell _: SettingsCell, preferenceKey: String, isOn: Bool) { - switch preferenceKey { - case kVLCSettingPasscodeOnKey: - passcodeLockSwitchOn(state: isOn) - case kVLCSettingHideLibraryInFilesApp: - medialibraryHidingLockSwitchOn(state: isOn) - case kVLCSettingBackupMediaLibrary: - mediaLibraryBackupActivateSwitchOn(state: isOn) - case kVLCSettingsDisableGrouping: - medialibraryDisableGroupingSwitchOn(state: isOn) - default: - break - } - } - func settingsCellInfoButtonPressed(cell: SettingsCell, preferenceKey: String) { guard let settingSpecifier = getSettingsSpecifier(for: preferenceKey) else { return @@ -466,56 +455,16 @@ extension SettingsController: SettingsCellDelegate { } } -extension SettingsController { - func passcodeLockSwitchOn(state: Bool) { - if state { - KeychainCoordinator.passcodeService.setSecret { success in - // If the user cancels setting the password, the toggle should revert to the unset state. - // This ensures the UI reflects the correct state. - UserDefaults.standard.set(success, forKey: kVLCSettingPasscodeOnKey) - self.reloadSettingsSections() // To show/hide biometric row - } - } else { - // When disabled any existing passcode should be removed. - // If user previously set a passcode and then disable and enable it - // the new passcode view will be showed, but if user terminates the app - // passcode will remain open even if the user doesn't set the new passcode. - // So, this may cause the app being locked. - try? KeychainCoordinator.passcodeService.removeSecret() - - reloadSettingsSections() - } - } -} - -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) + VLCDefaults.shared.appThemeBlack = state PresentationTheme.themeDidUpdate() case .playNextItem: - userDefaults.setValue(state, forKey: kVLCAutomaticallyPlayNextItem) + VLCDefaults.shared.automaticallyPlayNextItem = state case .playlistPlayNextItem: - userDefaults.setValue(state, forKey: kVLCPlaylistPlayNextItem) + VLCDefaults.shared.playlistPlayNextItem = state default: break } diff --git a/Sources/Settings/Model/ActionSheetSpecifier.swift b/Sources/Settings/Model/ActionSheetSpecifier.swift index ed4e4db9fa7f3b67273604649b6713ac07330b60..e1b5dd369698686982e528444186b13b6392cb3c 100644 --- a/Sources/Settings/Model/ActionSheetSpecifier.swift +++ b/Sources/Settings/Model/ActionSheetSpecifier.swift @@ -60,20 +60,20 @@ extension ActionSheetSpecifier: ActionSheetDelegate { return } - guard preferenceKey != kVLCSettingAppTheme || + guard preferenceKey != VLCDefaults.Compat.appThemeKey || (!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 { + guard preferenceKey != VLCDefaults.Compat.automaticallyPlayNextItemKey else { // Disable the selection for the automatically play next item options return } userDefaults.set(settingSpecifier?.specifier[indexPath.row].value, forKey: preferenceKey) - if preferenceKey == kVLCSettingAppTheme { + if preferenceKey == VLCDefaults.Compat.appThemeKey { PresentationTheme.themeDidUpdate() } @@ -106,7 +106,7 @@ extension ActionSheetSpecifier: ActionSheetDataSource { return 0 } - if preferenceKey == kVLCSettingAppTheme { + if preferenceKey == VLCDefaults.Compat.appThemeKey { let isThemeDark: Bool = PresentationTheme.current.isDark if #available(iOS 13, *) { return isThemeDark ? rowCount : rowCount - 1 @@ -128,11 +128,11 @@ extension ActionSheetSpecifier: ActionSheetDataSource { return UICollectionViewCell() } - if preferenceKey == kVLCSettingAppTheme && + if preferenceKey == VLCDefaults.Compat.appThemeKey && 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.setToggleSwitch(state: VLCDefaults.shared.appThemeBlack) cell.name.text = settingsBundle.localizedString(forKey: "SETTINGS_THEME_BLACK", value: "", table: "Root") let cellIdentifier = ActionSheetCellIdentifier.blackBackground cell.identifier = cellIdentifier @@ -141,14 +141,14 @@ extension ActionSheetSpecifier: ActionSheetDataSource { cell.delegate = self return cell - } else if preferenceKey == kVLCAutomaticallyPlayNextItem { + } else if preferenceKey == VLCDefaults.Compat.automaticallyPlayNextItemKey { cell.setAccessoryType(to: .toggleSwitch) let isFirstRow: Bool = indexPath.row == 0 if isFirstRow { - cell.setToggleSwitch(state: userDefaults.bool(forKey: kVLCAutomaticallyPlayNextItem)) + cell.setToggleSwitch(state: VLCDefaults.shared.automaticallyPlayNextItem) } else { - cell.setToggleSwitch(state: userDefaults.bool(forKey: kVLCPlaylistPlayNextItem)) + cell.setToggleSwitch(state: VLCDefaults.shared.playlistPlayNextItem) } let cellIdentifier: ActionSheetCellIdentifier = isFirstRow ? .playNextItem : .playlistPlayNextItem @@ -166,7 +166,7 @@ extension ActionSheetSpecifier: ActionSheetDataSource { extension ActionSheetSpecifier: ActionSheetCellDelegate { func actionSheetCellShouldUpdateColors() -> Bool { - guard preferenceKey != kVLCAutomaticallyPlayNextItem else { + guard preferenceKey != VLCDefaults.Compat.automaticallyPlayNextItemKey else { return false } diff --git a/Sources/Settings/Model/SettingsSection.swift b/Sources/Settings/Model/SettingsSection.swift index a7b6ffbe598ddc6c2906c0d78aae9d2ab5a88f9c..5283340e14b075136092ae92b4539dc60e4bfacb 100644 --- a/Sources/Settings/Model/SettingsSection.swift +++ b/Sources/Settings/Model/SettingsSection.swift @@ -10,6 +10,7 @@ * Diogo Simao Marques <dogo@videolabs.io> * Felix Paul Kühne <fkuehne # videolan.org> * Eshan Singh <eeeshan789@icloud.com> + * Craig Reyenga <craig.reyenga # gmail.com> * * Refer to the COPYING file of the official project for license. *****************************************************************************/ @@ -28,8 +29,6 @@ struct SettingsItem: Equatable { @available(*, deprecated, message: "access from self.action") var preferenceKey: String? { switch action { - case let .toggle(toggle): - return toggle.preferenceKey case let .showActionSheet(_, preferenceKey, _): return preferenceKey default: @@ -44,8 +43,8 @@ struct SettingsItem: Equatable { 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, keyPath: WritableKeyPath<VLCDefaults, Bool>, onChange: ((Bool) -> Void)? = nil) -> Self { + return Self(title: title, subtitle: subtitle, action: .toggle(Toggle(keyPath: keyPath, onChange: onChange))) } enum Action: Equatable { @@ -62,10 +61,11 @@ struct SettingsItem: Equatable { final class Toggle: Equatable { typealias Observer = (Bool) -> Void - let preferenceKey: String + private let keyPath: WritableKeyPath<VLCDefaults, Bool> + private let onChange: ((Bool) -> Void)? var isOn: Bool { - UserDefaults.standard.bool(forKey: preferenceKey) + VLCDefaults.shared[keyPath: keyPath] } private var observers: [Int: Observer] = [:] @@ -77,13 +77,19 @@ struct SettingsItem: Equatable { set { lock.withLock { _lastId = newValue } } } - init(preferenceKey: String) { - self.preferenceKey = preferenceKey - NotificationCenter.default.addObserver(self, selector: #selector(didChange), name: UserDefaults.didChangeNotification, object: nil) + init(keyPath: WritableKeyPath<VLCDefaults, Bool>, onChange: ((Bool) -> Void)? = nil) { + self.keyPath = keyPath + self.onChange = onChange + NotificationCenter.default.addObserver(self, + selector: #selector(defaultsDidUpdate), + name: .VLCDefaultsDidUpdate, + object: nil) } func set(isOn: Bool) { - UserDefaults.standard.set(isOn, forKey: preferenceKey) + var defaults = VLCDefaults.shared + defaults[keyPath: keyPath] = isOn + onChange?(isOn) } // does not call out initially. @@ -98,12 +104,12 @@ struct SettingsItem: Equatable { observers.removeValue(forKey: Int) } - @objc private func didChange(_: Notification) { + @objc private func defaultsDidUpdate(_: Notification) { notifyObservers() } private func notifyObservers() { - precondition(!isNotifyingObservers, "[\(preferenceKey)] updating the toggle switch from an observer is illegal") + precondition(!isNotifyingObservers, "updating the toggle switch from an observer is illegal") isNotifyingObservers = true @@ -120,7 +126,7 @@ struct SettingsItem: Equatable { } static func == (lhs: SettingsItem.Toggle, rhs: SettingsItem.Toggle) -> Bool { - lhs.preferenceKey == rhs.preferenceKey + lhs.keyPath == rhs.keyPath } } } @@ -140,18 +146,22 @@ struct SettingsSection: Equatable { self.items = items } - static func sections(isLabActivated: Bool, isBackingUp: Bool, isForwardBackwardEqual: Bool, isTapSwipeEqual: Bool) -> [SettingsSection] { + static func sections(mediaLibraryService: MediaLibraryService, + isLabActivated: Bool, + isBackingUp: Bool, + isForwardBackwardEqual: Bool, + isTapSwipeEqual: Bool) -> [SettingsSection] { [ MainOptions.section(), DonationOptions.section(), GenericOptions.section(), - PrivacyOptions.section(), + PrivacyOptions.section(mediaLibraryService: mediaLibraryService), GestureControlOptions.section(isForwardBackwardEqual: isForwardBackwardEqual, isTapSwipeEqual: isTapSwipeEqual), VideoOptions.section(), SubtitlesOptions.section(), AudioOptions.section(), CastingOptions.section(), - MediaLibraryOptions.section(isBackingUp: isBackingUp), + MediaLibraryOptions.section(mediaLibraryService: mediaLibraryService, isBackingUp: isBackingUp), NetworkOptions.section(), Accessibility.section(), Lab.section(isLabActivated: isLabActivated), @@ -170,7 +180,7 @@ enum MainOptions { } static var appearance: SettingsItem { - let k = kVLCSettingAppTheme + let k = VLCDefaults.Compat.appThemeKey return .init(title: "SETTINGS_DARKTHEME", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_DARKTHEME", preferenceKey: k, hasInfo: false)) @@ -202,14 +212,14 @@ enum DonationOptions { enum GenericOptions { static var defaultPlaybackSpeed: SettingsItem { - let k = kVLCSettingPlaybackSpeedDefaultValue + let k = VLCDefaults.Compat.playbackSpeedDefaultValueKey return .init(title: "SETTINGS_PLAYBACK_SPEED_DEFAULT", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_PLAYBACK_SPEED_DEFAULT", preferenceKey: k, hasInfo: false)) } static var continueAudioPlayback: SettingsItem { - let k = kVLCSettingContinueAudioPlayback + let k = VLCDefaults.Compat.continueAudioPlaybackKey return .init(title: "SETTINGS_CONTINUE_AUDIO_PLAYBACK", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_CONTINUE_AUDIO_PLAYBACK", preferenceKey: k, hasInfo: true)) @@ -217,19 +227,18 @@ enum GenericOptions { static var playVideoInFullScreen: SettingsItem { .toggle(title: "SETTINGS_VIDEO_FULLSCREEN", - subtitle: nil, - preferenceKey: kVLCSettingVideoFullscreenPlayback) + keyPath: \.videoFullscreenPlayback) } static var continueVideoPlayback: SettingsItem { - let k = kVLCSettingContinuePlayback + let k = VLCDefaults.Compat.continuePlaybackKey return .init(title: "SETTINGS_CONTINUE_VIDEO_PLAYBACK", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_CONTINUE_VIDEO_PLAYBACK", preferenceKey: k, hasInfo: true)) } static var automaticallyPlayNextItem: SettingsItem { - let k = kVLCAutomaticallyPlayNextItem + let k = VLCDefaults.Compat.automaticallyPlayNextItemKey return .init(title: "SETTINGS_NETWORK_PLAY_ALL", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_NETWORK_PLAY_ALL", preferenceKey: k, hasInfo: false)) @@ -237,20 +246,17 @@ enum GenericOptions { static var enableTextScrollingInMediaList: SettingsItem { .toggle(title: "SETTINGS_ENABLE_MEDIA_CELL_TEXT_SCROLLING", - subtitle: nil, - preferenceKey: kVLCSettingEnableMediaCellTextScrolling) + keyPath: \.enableMediaCellTextScrolling) } static var rememberPlayerState: SettingsItem { .toggle(title: "SETTINGS_REMEMBER_PLAYER_STATE", - subtitle: nil, - preferenceKey: kVLCPlayerShouldRememberState) + keyPath: \.playerShouldRememberState) } static var restoreLastPlayedMedia: SettingsItem { .toggle(title: "SETTINGS_RESTORE_LAST_PLAYED_MEDIA", - subtitle: nil, - preferenceKey: kVLCRestoreLastPlayedMedia) + keyPath: \.restoreLastPlayedMedia) } static func section() -> SettingsSection? { @@ -273,7 +279,25 @@ enum PrivacyOptions { static var passcodeLock: SettingsItem { .toggle(title: "SETTINGS_PASSCODE_LOCK", subtitle: "SETTINGS_PASSCODE_LOCK_SUBTITLE", - preferenceKey: kVLCSettingPasscodeOnKey) + keyPath: \.passcodeOn) { isOn in + if isOn { + KeychainCoordinator.passcodeService.setSecret { success in + // If the user cancels setting the password, the toggle should revert to the unset state. + // This ensures the UI reflects the correct state. + VLCDefaults.shared.passcodeOn = success + NotificationCenter.default.post(name: .VLCSettingsShouldReloadNotification, object: nil) // To show/hide biometric row + } + } else { + // When disabled any existing passcode should be removed. + // If user previously set a passcode and then disable and enable it + // the new passcode view will be showed, but if user terminates the app + // passcode will remain open even if the user doesn't set the new passcode. + // So, this may cause the app being locked. + try? KeychainCoordinator.passcodeService.removeSecret() + + NotificationCenter.default.post(name: .VLCSettingsShouldReloadNotification, object: nil) + } + } } static var enableBiometrics: SettingsItem? { @@ -283,16 +307,13 @@ enum PrivacyOptions { switch authContext.biometryType { case .touchID: return .toggle(title: "SETTINGS_PASSCODE_LOCK_ALLOWTOUCHID", - subtitle: nil, - preferenceKey: kVLCSettingPasscodeEnableBiometricAuth) + keyPath: \.passcodeEnableBiometricAuth) case .faceID: return .toggle(title: "SETTINGS_PASSCODE_LOCK_ALLOWFACEID", - subtitle: nil, - preferenceKey: kVLCSettingPasscodeEnableBiometricAuth) + keyPath: \.passcodeEnableBiometricAuth) case .opticID: return .toggle(title: "SETTINGS_PASSCODE_LOCK_ALLOWOPTICID", - subtitle: nil, - preferenceKey: kVLCSettingPasscodeEnableBiometricAuth) + keyPath: \.passcodeEnableBiometricAuth) case .none: fallthrough @unknown default: @@ -303,17 +324,19 @@ enum PrivacyOptions { return nil } - static var hideLibraryInFilesApp: SettingsItem { + static func hideLibraryInFilesApp(mediaLibraryService: MediaLibraryService) -> SettingsItem { .toggle(title: "SETTINGS_HIDE_LIBRARY_IN_FILES_APP", subtitle: "SETTINGS_HIDE_LIBRARY_IN_FILES_APP_SUBTITLE", - preferenceKey: kVLCSettingHideLibraryInFilesApp) + keyPath: \.hideLibraryInFilesApp) { isOn in + mediaLibraryService.hideMediaLibrary(isOn) + } } - static func section() -> SettingsSection? { + static func section(mediaLibraryService: MediaLibraryService) -> SettingsSection? { .init(title: "SETTINGS_PRIVACY_TITLE", items: [ passcodeLock, enableBiometrics, - hideLibraryInFilesApp, + hideLibraryInFilesApp(mediaLibraryService: mediaLibraryService), ].compactMap { $0 }) } } @@ -323,69 +346,62 @@ enum PrivacyOptions { enum GestureControlOptions { static var swipeUpDownForVolume: SettingsItem { .toggle(title: "SETTINGS_GESTURES_VOLUME", - subtitle: nil, - preferenceKey: kVLCSettingVolumeGesture) + keyPath: \.volumeGesture) } static var twoFingerTap: SettingsItem { .toggle(title: "SETTINGS_GESTURES_PLAYPAUSE", - subtitle: nil, - preferenceKey: kVLCSettingPlayPauseGesture) + keyPath: \.playPauseGesture) } static var swipeUpDownForBrightness: SettingsItem { .toggle(title: "SETTINGS_GESTURES_BRIGHTNESS", - subtitle: nil, - preferenceKey: kVLCSettingBrightnessGesture) + keyPath: \.brightnessGesture) } static var swipeRightLeftToSeek: SettingsItem { .toggle(title: "SETTINGS_GESTURES_SEEK", - subtitle: nil, - preferenceKey: kVLCSettingSeekGesture) + keyPath: \.seekGesture) } static var pinchToClose: SettingsItem { .toggle(title: "SETTINGS_GESTURES_CLOSE", - subtitle: nil, - preferenceKey: kVLCSettingCloseGesture) + keyPath: \.closeGesture) } static var forwardBackwardEqual: SettingsItem { .toggle(title: "SETTINGS_GESTURES_FORWARD_BACKWARD_EQUAL", - subtitle: nil, - preferenceKey: kVLCSettingPlaybackForwardBackwardEqual) + keyPath: \.playbackForwardBackwardEqual) } static var tapSwipeEqual: SettingsItem { .toggle(title: "SETTINGS_GESTURES_TAP_SWIPE_EQUAL", - subtitle: nil, - preferenceKey: kVLCSettingPlaybackTapSwipeEqual) + keyPath: \.playbackTapSwipeEqual) } static var forwardSkipLength: SettingsItem { - let k = kVLCSettingPlaybackForwardSkipLength + let k = VLCDefaults.Compat.playbackForwardSkipLengthKey return .init(title: dynamicForwardSkipDescription(), subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: dynamicForwardSkipDescription(), preferenceKey: k, hasInfo: false)) } static var backwardSkipLength: SettingsItem { - let k = kVLCSettingPlaybackBackwardSkipLength + let k = VLCDefaults.Compat.playbackBackwardSkipLengthKey return .init(title: dynamicBackwardSkipDescription(), subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: dynamicBackwardSkipDescription(), preferenceKey: k, hasInfo: false)) } static var forwardSkipLengthSwipe: SettingsItem { - let k = kVLCSettingPlaybackForwardSkipLengthSwipe + let k = VLCDefaults.Compat.playbackForwardSkipLengthSwipeKey return .init(title: dynamicForwardSwipeDescription(), subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: dynamicForwardSwipeDescription(), preferenceKey: k, hasInfo: false)) } static var backwardSkipLengthSwipe: SettingsItem { - let k = kVLCSettingPlaybackBackwardSkipLengthSwipe + let k = VLCDefaults.Compat.playbackBackwardSkipLengthSwipeKey return .init(title: "SETTINGS_PLAYBACK_SKIP_BACKWARD_SWIPE", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_PLAYBACK_SKIP_BACKWARD_SWIPE", preferenceKey: k, hasInfo: false)) @@ -393,19 +409,18 @@ enum GestureControlOptions { static var longTouchToSpeedUp: SettingsItem { .toggle(title: "SETINGS_LONG_TOUCH_SPEED_UP", - subtitle: nil, - preferenceKey: kVLCSettingPlaybackLongTouchSpeedUp) + keyPath: \.playbackLongTouchSpeedUp) } static var lockScreenSkip: SettingsItem { - let k = kVLCSettingPlaybackLockscreenSkip + let k = VLCDefaults.Compat.lockscreenSkipKey return .init(title: "SETTINGS_PLAYBACK_LOCKSCREEN_SKIP", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_PLAYBACK_LOCKSCREEN_SKIP", preferenceKey: k, hasInfo: false)) } static var externalControlsSkip: SettingsItem { - let k = kVLCSettingPlaybackRemoteControlSkip + let k = VLCDefaults.Compat.remoteControlSkipKey return .init(title: "SETTINGS_PLAYBACK_EXTERNAL_CONTROLS_SKIP", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_PLAYBACK_EXTERNAL_CONTROLS_SKIP", preferenceKey: k, hasInfo: false)) @@ -431,8 +446,8 @@ enum GestureControlOptions { } private static func dynamicForwardSkipDescription() -> String { - let forwardBackwardEqual = UserDefaults.standard.bool(forKey: kVLCSettingPlaybackForwardBackwardEqual) - let tapSwipeEqual = UserDefaults.standard.bool(forKey: kVLCSettingPlaybackTapSwipeEqual) + let forwardBackwardEqual = VLCDefaults.shared.playbackForwardBackwardEqual + let tapSwipeEqual = VLCDefaults.shared.playbackTapSwipeEqual if forwardBackwardEqual && tapSwipeEqual { return "SETTINGS_PLAYBACK_SKIP_GENERIC" @@ -446,7 +461,7 @@ enum GestureControlOptions { } private static func dynamicBackwardSkipDescription() -> String { - let tapSwipeEqual = UserDefaults.standard.bool(forKey: kVLCSettingPlaybackTapSwipeEqual) + let tapSwipeEqual = VLCDefaults.shared.playbackTapSwipeEqual if tapSwipeEqual { return "SETTINGS_PLAYBACK_SKIP_BACKWARD" @@ -456,7 +471,7 @@ enum GestureControlOptions { } private static func dynamicForwardSwipeDescription() -> String { - let forwardBackwardEqual = UserDefaults.standard.bool(forKey: kVLCSettingPlaybackForwardBackwardEqual) + let forwardBackwardEqual = VLCDefaults.shared.playbackForwardBackwardEqual if forwardBackwardEqual { return "SETTINGS_PLAYBACK_SKIP_SWIPE" @@ -470,21 +485,21 @@ enum GestureControlOptions { enum VideoOptions { static var deBlockingFilter: SettingsItem { - let k = kVLCSettingSkipLoopFilter + let k = VLCDefaults.Compat.skipLoopFilterKey return .init(title: "SETTINGS_SKIP_LOOP_FILTER", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_SKIP_LOOP_FILTER", preferenceKey: k, hasInfo: true)) } static var deInterlace: SettingsItem { - let k = kVLCSettingDeinterlace + let k = VLCDefaults.Compat.deinterlaceKey return .init(title: "SETTINGS_DEINTERLACE", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_DEINTERLACE", preferenceKey: k, hasInfo: true)) } static var hardwareDecoding: SettingsItem { - let k = kVLCSettingHardwareDecoding + let k = VLCDefaults.Compat.hardwareDecodingKey return .init(title: "SETTINGS_HWDECODING", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_HWDECODING", preferenceKey: k, hasInfo: true)) @@ -492,14 +507,12 @@ enum VideoOptions { static var rememberPlayerBrightness: SettingsItem { .toggle(title: "SETTINGS_REMEMBER_PLAYER_BRIGHTNESS", - subtitle: nil, - preferenceKey: kVLCPlayerShouldRememberBrightness) + keyPath: \.playerShouldRememberBrightness) } static var lockRotation: SettingsItem { .toggle(title: "SETTINGS_LOCK_ROTATION", - subtitle: nil, - preferenceKey: kVLCSettingRotationLock) + keyPath: \.rotationLock) } static func section() -> SettingsSection? { @@ -519,18 +532,18 @@ enum SubtitlesOptions { static var disableSubtitles: SettingsItem { .toggle(title: "SETTINGS_SUBTITLES_DISABLE", subtitle: "SETTINGS_SUBTITLES_DISABLE_LONG", - preferenceKey: kVLCSettingDisableSubtitles) + keyPath: \.disableSubtitles) } static var font: SettingsItem { - let k = kVLCSettingSubtitlesFont + let k = VLCDefaults.Compat.subtitlesFontKey return .init(title: "SETTINGS_SUBTITLES_FONT", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_SUBTITLES_FONT", preferenceKey: k, hasInfo: true)) } static var relativeFontSize: SettingsItem { - let k = kVLCSettingSubtitlesFontSize + let k = VLCDefaults.Compat.subtitlesFontSizeKey return .init(title: "SETTINGS_SUBTITLES_FONTSIZE", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_SUBTITLES_FONTSIZE", preferenceKey: k, hasInfo: true)) @@ -538,19 +551,18 @@ enum SubtitlesOptions { static var useBoldFont: SettingsItem { .toggle(title: "SETTINGS_SUBTITLES_BOLDFONT", - subtitle: nil, - preferenceKey: kVLCSettingSubtitlesBoldFont) + keyPath: \.subtitlesBoldFont) } static var fontColor: SettingsItem { - let k = kVLCSettingSubtitlesFontColor + let k = VLCDefaults.Compat.subtitlesFontColorKey return .init(title: "SETTINGS_SUBTITLES_FONTCOLOR", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_SUBTITLES_FONTCOLOR", preferenceKey: k, hasInfo: true)) } static var textEncoding: SettingsItem { - let k = kVLCSettingTextEncoding + let k = VLCDefaults.Compat.textEncodingKey return .init(title: "SETTINGS_SUBTITLES_TEXT_ENCODING", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_SUBTITLES_TEXT_ENCODING", preferenceKey: k, hasInfo: true)) @@ -574,11 +586,11 @@ enum CastingOptions { static var audioPassThrough: SettingsItem { .toggle(title: "SETTINGS_PTCASTING", subtitle: "SETTINGS_PTCASTINGLONG", - preferenceKey: kVLCSettingCastingAudioPassthrough) + keyPath: \.castingAudioPassthrough) } static var conversionQuality: SettingsItem { - let k = kVLCSettingCastingConversionQuality + let k = VLCDefaults.Compat.castingConversionQualityKey return .init(title: "SETTINGS_CASTING_CONVERSION_QUALITY", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_CASTING_CONVERSION_QUALITY", preferenceKey: k, hasInfo: false)) @@ -596,7 +608,7 @@ enum CastingOptions { enum AudioOptions { static var preampLevel: SettingsItem { - let k = kVLCSettingDefaultPreampLevel + let k = VLCDefaults.Compat.defaultPreampLevelKey return .init(title: "SETTINGS_AUDIO_PREAMP_LEVEL", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_AUDIO_PREAMP_LEVEL", preferenceKey: k, hasInfo: false)) @@ -605,13 +617,12 @@ enum AudioOptions { static var timeStretchingAudio: SettingsItem { .toggle(title: "SETTINGS_TIME_STRETCH_AUDIO", subtitle: "SETTINGS_TIME_STRETCH_AUDIO_LONG", - preferenceKey: kVLCSettingStretchAudio) + keyPath: \.stretchAudio) } static var audioPlaybackInBackground: SettingsItem { .toggle(title: "SETTINGS_BACKGROUND_AUDIO", - subtitle: nil, - preferenceKey: kVLCSettingContinueAudioInBackgroundKey) + keyPath: \.continueAudioInBackgroundKey) } static func section() -> SettingsSection? { @@ -635,32 +646,31 @@ enum MediaLibraryOptions { static var optimiseItemNamesForDisplay: SettingsItem { .toggle(title: "SETTINGS_DECRAPIFY", - subtitle: nil, - preferenceKey: kVLCSettingsDecrapifyTitles) + keyPath: \.optimizeTitles) } static var disableGrouping: SettingsItem { .toggle(title: "SETTINGS_DISABLE_GROUPING", - subtitle: nil, - preferenceKey: kVLCSettingsDisableGrouping) + keyPath: \.disableGrouping) { isOn in + NotificationCenter.default.post(name: .VLCDisableGroupingDidChangeNotification, object: nil) + } } static var showVideoThumbnails: SettingsItem { .toggle(title: "SETTINGS_SHOW_THUMBNAILS", - subtitle: nil, - preferenceKey: kVLCSettingShowThumbnails) + keyPath: \.showThumbnails) } static var showAudioArtworks: SettingsItem { .toggle(title: "SETTINGS_SHOW_ARTWORKS", - subtitle: nil, - preferenceKey: kVLCSettingShowArtworks) + keyPath: \.showArtworks) } - static var includeMediaLibInDeviceBackup: SettingsItem { + static func includeMediaLibInDeviceBackup(mediaLibraryService: MediaLibraryService) -> SettingsItem { .toggle(title: "SETTINGS_BACKUP_MEDIA_LIBRARY", - subtitle: nil, - preferenceKey: kVLCSettingBackupMediaLibrary) + keyPath: \.backupMediaLibrary) { isOn in + mediaLibraryService.excludeFromDeviceBackup(isOn) + } } static var includeMediaLibInDeviceBackupWhenBackingUp: SettingsItem { @@ -669,7 +679,7 @@ enum MediaLibraryOptions { action: .isLoading) } - static func section(isBackingUp: Bool) -> SettingsSection? { + static func section(mediaLibraryService: MediaLibraryService, isBackingUp: Bool) -> SettingsSection? { var options = [forceVLCToRescanTheMediaLibrary, optimiseItemNamesForDisplay, disableGrouping, @@ -679,7 +689,7 @@ enum MediaLibraryOptions { if isBackingUp { options.append(includeMediaLibInDeviceBackupWhenBackingUp) } else { - options.append(includeMediaLibInDeviceBackup) + options.append(includeMediaLibInDeviceBackup(mediaLibraryService: mediaLibraryService)) } return .init(title: "SETTINGS_MEDIA_LIBRARY", items: options) @@ -690,7 +700,7 @@ enum MediaLibraryOptions { enum NetworkOptions { static var networkCachingLevel: SettingsItem { - let k = kVLCSettingNetworkCaching + let k = VLCDefaults.Compat.networkCachingKey return .init(title: "SETTINGS_NETWORK_CACHING_TITLE", subtitle: Localizer.getSubtitle(for: k), action: .showActionSheet(title: "SETTINGS_NETWORK_CACHING_TITLE", preferenceKey: k, hasInfo: true)) @@ -698,20 +708,18 @@ enum NetworkOptions { static var ipv6SupportForWiFiSharing: SettingsItem { .toggle(title: "SETTINGS_WIFISHARING_IPv6", - subtitle: nil, - preferenceKey: kVLCSettingWiFiSharingIPv6) + keyPath: \.wifiSharingIPv6) } static var forceSMBv1: SettingsItem { .toggle(title: "SETTINGS_FORCE_SMBV1", subtitle: "SETTINGS_FORCE_SMBV1_LONG", - preferenceKey: kVLCForceSMBV1) + keyPath: \.forceSMBV1) } static var rtspctp: SettingsItem { .toggle(title: "SETTINGS_RTSP_TCP", - subtitle: nil, - preferenceKey: kVLCSettingNetworkRTSPTCP) + keyPath: \.networkRTSPTCP) } static func section() -> SettingsSection? { @@ -728,16 +736,15 @@ enum NetworkOptions { enum Accessibility { static var playerControlDuration: SettingsItem { - let k = kVLCSettingPlayerControlDuration + let k = VLCDefaults.Compat.playerControlDurationKey return .init(title: "SETTINGS_PLAYER_CONTROL_DURATION", subtitle: Localizer.getSubtitle(for: k), - action: .showActionSheet(title: "SETTINGS_PLAYER_CONTROL_DURATION", preferenceKey: kVLCSettingPlayerControlDuration, hasInfo: false)) + action: .showActionSheet(title: "SETTINGS_PLAYER_CONTROL_DURATION", preferenceKey: k, hasInfo: false)) } static var pauseWhenShowingControls: SettingsItem { .toggle(title: "SETTINGS_PAUSE_WHEN_SHOWING_CONTROLS", - subtitle: nil, - preferenceKey: kVLCSettingPauseWhenShowingControls) + keyPath: \.pauseWhenShowingControls) } static func section() -> SettingsSection? { @@ -753,8 +760,7 @@ enum Accessibility { enum Lab { static var debugLogging: SettingsItem { .toggle(title: "SETTINGS_DEBUG_LOG", - subtitle: nil, - preferenceKey: kVLCSaveDebugLogs) + keyPath: \.saveDebugLogs) } static var exportLibrary: SettingsItem { diff --git a/Sources/Settings/View/SettingsCell.swift b/Sources/Settings/View/SettingsCell.swift index 0f9a69edc21716f0a46359fadf41f10d97a63945..c244d7c33d7316ea58f8509cdd1bb8f8672a58fb 100644 --- a/Sources/Settings/View/SettingsCell.swift +++ b/Sources/Settings/View/SettingsCell.swift @@ -5,6 +5,7 @@ * Copyright (c) 2020 VideoLAN. All rights reserved. * * Authors: Swapnanil Dhol <swapnanildhol # gmail.com> + * Craig Reyenga <craig.reyenga # gmail.com> * * Refer to the COPYING file of the official project for license. *****************************************************************************/ @@ -12,11 +13,6 @@ import UIKit protocol SettingsCellDelegate: AnyObject { - /// Implementations should only perform side effects on - /// specific preferences; updating the preference itself - /// is handled by the cell. - func settingsCellDidChangeSwitchState(cell: SettingsCell, preferenceKey: String, isOn: Bool) - func settingsCellInfoButtonPressed(cell: SettingsCell, preferenceKey: String) } @@ -288,7 +284,6 @@ class SettingsCell: UITableViewCell { switch settingsItem.action { case let .toggle(toggle): toggle.set(isOn: sender.isOn) - delegate?.settingsCellDidChangeSwitchState(cell: self, preferenceKey: toggle.preferenceKey, isOn: sender.isOn) default: // we should never get here; only toggles have a switch diff --git a/Sources/Settings/tvOS/VLCSettingsViewController.m b/Sources/Settings/tvOS/VLCSettingsViewController.m index 74834c75207f9cb3487532b84caa70ecdcf1f33d..09bea9240bec34205ea19890d55ddfbbb29f9149 100644 --- a/Sources/Settings/tvOS/VLCSettingsViewController.m +++ b/Sources/Settings/tvOS/VLCSettingsViewController.m @@ -14,6 +14,7 @@ #import "IASKSettingsReader.h" #import "IASKSpecifier.h" #import "VLCAboutViewController.h" +#import "VLC-Swift.h" #define SettingsReUseIdentifier @"SettingsReUseIdentifier" @@ -45,7 +46,7 @@ self.tableView.opaque = NO; self.tableView.backgroundColor = [UIColor clearColor]; - _debugLoggingOn = [self.userDefaults boolForKey:kVLCSaveDebugLogs]; + _debugLoggingOn = VLCDefaults.shared.saveDebugLogs; } - (NSString *)title @@ -58,13 +59,11 @@ [super viewWillDisappear:animated]; /* if debug logging was disabled in this session of the settings screen, delete all the logs */ - if (_debugLoggingOn) { - if (![self.userDefaults boolForKey:kVLCSaveDebugLogs]) { - NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - NSString* logFilePath = [searchPaths.firstObject stringByAppendingPathComponent:@"Logs"]; - NSFileManager *fileManager = [NSFileManager defaultManager]; - [fileManager removeItemAtPath:logFilePath error:nil]; - } + if (_debugLoggingOn && !VLCDefaults.shared.saveDebugLogs) { + NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + NSString* logFilePath = [searchPaths.firstObject stringByAppendingPathComponent:@"Logs"]; + NSFileManager *fileManager = [NSFileManager defaultManager]; + [fileManager removeItemAtPath:logFilePath error:nil]; } } diff --git a/Sources/UI Elements/ActionSheet/ActionSheetSortSectionHeader.swift b/Sources/UI Elements/ActionSheet/ActionSheetSortSectionHeader.swift index 0e277e7861afb8db57ee9a9b515b837ce7760e81..1b2bbd8dc3ca11c9109a77071603a1320e209986 100644 --- a/Sources/UI Elements/ActionSheet/ActionSheetSortSectionHeader.swift +++ b/Sources/UI Elements/ActionSheet/ActionSheetSortSectionHeader.swift @@ -30,7 +30,6 @@ class ActionSheetSortSectionHeader: ActionSheetSectionHeader { private var sortModel: SortModel private var secondSortModel: SortModel? - private let userDefaults = UserDefaults.standard private var isAdditionalOptionShown: Bool = false private let descendingStackView: UIStackView = { @@ -251,8 +250,12 @@ class ActionSheetSortSectionHeader: ActionSheetSectionHeader { } private func setSwitchIsOnFromUserDefaults() { - let key = isVideoModel ? kVLCVideoLibraryGridLayout : kVLCAudioLibraryGridLayout - layoutChangeSwitch.isOn = UserDefaults.standard.bool(forKey: key + modelType) + switch isVideoModel { + case true: + layoutChangeSwitch.isOn = VLCDefaults.shared.videoLibraryGridLayout(name: modelType) + case false: + layoutChangeSwitch.isOn = VLCDefaults.shared.audioLibraryGridLayout(name: modelType) + } } private func setupStackView() { @@ -296,7 +299,7 @@ class ActionSheetSortSectionHeader: ActionSheetSectionHeader { secondaryStackView.addArrangedSubview(hideFeatArtistsStackView) - hideFeatArtistsSwitch.isOn = UserDefaults.standard.bool(forKey: kVLCAudioLibraryHideFeatArtists) + hideFeatArtistsSwitch.isOn = VLCDefaults.shared.audioLibraryHideFeatArtists } func updateHeaderForAlbums() { @@ -306,6 +309,6 @@ class ActionSheetSortSectionHeader: ActionSheetSectionHeader { secondaryStackView.addArrangedSubview(hideTrackNumbersStackView) - hideTrackNumbersSwitch.isOn = UserDefaults.standard.bool(forKey: kVLCAudioLibraryHideTrackNumbers) + hideTrackNumbersSwitch.isOn = VLCDefaults.shared.audioLibraryHideTrackNumbers } } diff --git a/Sources/UI Elements/PresentationTheme.swift b/Sources/UI Elements/PresentationTheme.swift index 10585824d615117d0918763f826bdb617a6c728d..bbf2e92f1f97f43c7b27232b749471564118c1f0 100644 --- a/Sources/UI Elements/PresentationTheme.swift +++ b/Sources/UI Elements/PresentationTheme.swift @@ -104,6 +104,17 @@ enum PresentationThemeType: Int { case bright = 0 case dark case auto + + static func from(appTheme: VLCDefaults.AppTheme) -> PresentationThemeType { + switch appTheme { + case .dark, .black: + return .dark + case .bright: + return .bright + case .system: + return .auto + } + } } @objcMembers class PresentationTheme: NSObject { @@ -117,12 +128,11 @@ enum PresentationThemeType: Int { } var isBlack: Bool { - return UserDefaults.standard.bool(forKey: kVLCSettingAppThemeBlack) + VLCDefaults.shared.appThemeBlack } static var current: PresentationTheme = { - let themeSettings = UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) - return PresentationTheme.respectiveTheme(for: PresentationThemeType(rawValue: themeSettings)) + return PresentationTheme.respectiveTheme(for: PresentationThemeType.from(appTheme: VLCDefaults.shared.appTheme)) }() { didSet { AppearanceManager.setupAppearance(theme: self.current) @@ -144,9 +154,7 @@ enum PresentationThemeType: Int { } @objc static func themeDidUpdate() { - let themeSettings = UserDefaults.standard.integer(forKey: kVLCSettingAppTheme) - PresentationTheme.current = PresentationTheme.respectiveTheme(for: - PresentationThemeType(rawValue: themeSettings)) + PresentationTheme.current = PresentationTheme.respectiveTheme(for: PresentationThemeType.from(appTheme: VLCDefaults.shared.appTheme)) } static func respectiveTheme(for theme: PresentationThemeType?, excludingBlackTheme: Bool = false) -> PresentationTheme { @@ -157,7 +165,7 @@ enum PresentationThemeType: Int { var presentationTheme = PresentationTheme.brightTheme var darkTheme: PresentationTheme - if UserDefaults.standard.bool(forKey: kVLCSettingAppThemeBlack) { + if VLCDefaults.shared.appThemeBlack { darkTheme = PresentationTheme.blackTheme } else { darkTheme = PresentationTheme.darkTheme diff --git a/Sources/WiFi Sharing/VLCHTTPUploaderController.m b/Sources/WiFi Sharing/VLCHTTPUploaderController.m index 866c7f3fce2039ed0df0a253bf5a9361dbd7a47f..1a168c4cf2f6d9cb3ec88284514f17d5ef26c56e 100644 --- a/Sources/WiFi Sharing/VLCHTTPUploaderController.m +++ b/Sources/WiFi Sharing/VLCHTTPUploaderController.m @@ -27,8 +27,9 @@ #import "NSString+SupportedMedia.h" -#if TARGET_OS_IOS || TARGET_OS_VISION #import "VLC-Swift.h" + +#if TARGET_OS_IOS || TARGET_OS_VISION #import "VLCMediaFileDiscoverer.h" #endif @@ -256,7 +257,7 @@ NSString *VLCHTTPUploaderBackgroundTaskName = @"VLCHTTPUploaderBackgroundTaskNam [_httpServer setInterface:_nameOfUsedNetworkInterface]; [_httpServer setIPv4Enabled:YES]; - [_httpServer setIPv6Enabled:[[[NSUserDefaults standardUserDefaults] objectForKey:kVLCSettingWiFiSharingIPv6] boolValue]]; + [_httpServer setIPv6Enabled:VLCDefaults.shared.wifiSharingIPv6]; // Tell the server to broadcast its presence via Bonjour. // This allows browsers such as Safari to automatically discover our service. diff --git a/VLC.xcodeproj/project.pbxproj b/VLC.xcodeproj/project.pbxproj index 4f743280f4f004331d3647178a63a614cc99cd41..ce107c77084308237bbea231ef15142826b59662 100644 --- a/VLC.xcodeproj/project.pbxproj +++ b/VLC.xcodeproj/project.pbxproj @@ -95,6 +95,9 @@ 4342C3C327474CA000E52334 /* SortedMediaFiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4342C3C227474CA000E52334 /* SortedMediaFiles.swift */; }; 444E5BFA24C6081B0003B69C /* PasscodeLockController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444E5BF924C6081A0003B69C /* PasscodeLockController.swift */; }; 444E5C0024C719480003B69C /* AboutController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 444E5BFF24C719480003B69C /* AboutController.swift */; }; + 446AA2322D6A91620026F3C8 /* VLCDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 446AA2312D6A91520026F3C8 /* VLCDefaults.swift */; }; + 446AA2332D6A91620026F3C8 /* VLCDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 446AA2312D6A91520026F3C8 /* VLCDefaults.swift */; }; + 446AA2342D6C08C50026F3C8 /* VLCDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 446AA2312D6A91520026F3C8 /* VLCDefaults.swift */; }; 44B5822024E434FD001A2583 /* MediaGridCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44B5821F24E434FD001A2583 /* MediaGridCollectionCell.swift */; }; 44C8BBA324AF2B5C003F8940 /* FeedbackGenerators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBA224AF2B5C003F8940 /* FeedbackGenerators.swift */; }; 44C8BBAE24AF36F4003F8940 /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44C8BBA624AF36F4003F8940 /* SettingsController.swift */; }; @@ -1012,6 +1015,7 @@ 4342C3C227474CA000E52334 /* SortedMediaFiles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SortedMediaFiles.swift; sourceTree = "<group>"; }; 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>"; }; + 446AA2312D6A91520026F3C8 /* VLCDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VLCDefaults.swift; sourceTree = "<group>"; }; 44B5821F24E434FD001A2583 /* MediaGridCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaGridCollectionCell.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>"; }; @@ -1898,6 +1902,7 @@ 44C8BBA124AF2B5C003F8940 /* Helpers */ = { isa = PBXGroup; children = ( + 446AA2312D6A91520026F3C8 /* VLCDefaults.swift */, 419A2C651F37A4B70069D224 /* VLCStringsForLocalization.m */, 4152F1611FEF19BD00F1908B /* KeychainCoordinator.swift */, 7D0C209A28C89F5400CCFFEF /* Network */, @@ -4240,6 +4245,7 @@ 6C5B0C9E27A43098005AE25B /* PlaybackServiceAdjustFilter.swift in Sources */, 7DC869B828CB794A00EE99F8 /* VLCDeletionCapableViewController.m in Sources */, DD4089F21BF6467E0022745E /* VLCPlaybackInfoTVCollectionViewCell.m in Sources */, + 446AA2342D6C08C50026F3C8 /* VLCDefaults.swift in Sources */, 4342C3C327474CA000E52334 /* SortedMediaFiles.swift in Sources */, DD3EAC0A1BE2192A003668DA /* VLCServerBrowsingController.m in Sources */, D9B36AF62AF4020000A10C99 /* AspectRatio.swift in Sources */, @@ -4462,6 +4468,7 @@ 7D50C6A42BBD20DF00B9F1A0 /* VLCDownloadController.m in Sources */, 7D50C6A52BBD20DF00B9F1A0 /* RemoteNetworkCell.swift in Sources */, 7D50C6A62BBD20DF00B9F1A0 /* VLCNetworkLoginDataSourceLogin.m in Sources */, + 446AA2332D6A91620026F3C8 /* VLCDefaults.swift in Sources */, 7D50C6A72BBD20DF00B9F1A0 /* VLCAccessibilityIdentifier.swift in Sources */, 7D50C6A82BBD20DF00B9F1A0 /* VLCPagingViewController.swift in Sources */, 7D50C6A92BBD20DF00B9F1A0 /* VLCLocalNetworkServiceBrowserBonjour.m in Sources */, @@ -4563,6 +4570,7 @@ 7DBF605C2B5D652900F16BB4 /* VLCFirstStepsDonateViewController.m in Sources */, 7D1471752B88A7BA00AB642B /* VLCCharge.m in Sources */, DD3EFF451BDEBCE500B68579 /* VLCLocalNetworkServiceBrowserManualConnect.m in Sources */, + 446AA2322D6A91620026F3C8 /* VLCDefaults.swift in Sources */, 8DF966B121188BDB00D0FCD6 /* EditController.swift in Sources */, 8D144D6322298E8E00984C46 /* AudioMiniPlayer.swift in Sources */, 7DC7BAB528C8958900109F28 /* UIColor+Presets.m in Sources */,