diff --git a/README.md b/README.md index 16b16bc..41f7272 100644 --- a/README.md +++ b/README.md @@ -101,6 +101,7 @@ A feature-rich iOS tweak for Instagram, forked from [SCInsta](https://github.com - Manual mark story as seen — button on story overlay to selectively mark stories as seen (button or toggle mode) **\*** - Long-press the story seen button for quick actions **\*** - Per-user story seen-receipt exclusions — exclude specific users so their stories behave normally. Manage via 3-dot menu, eye button long-press, or settings list **\*** +- Story audio mute/unmute toggle — button on the story overlay and 3-dot menu to toggle audio **\*** - Stop story auto-advance — stories won't auto-skip when the timer ends **\*** - Story download button — download directly from the story overlay **\*** - Download disappearing DM media (photos + videos) **\*** @@ -132,6 +133,8 @@ A feature-rich iOS tweak for Instagram, forked from [SCInsta](https://github.com ### Tweak settings **\*** - Search bar in the main settings page — recursively finds any setting across nested pages with a breadcrumb to its location +- Pause playback when opening settings (toggleable) **\*** +- Quick-access via long-press on feed tab **\*** ### Backup & Restore **\*** - Export RyukGram settings as a JSON file diff --git a/src/Features/Reels/ReelsPlayback.xm b/src/Features/Reels/ReelsPlayback.xm index eebee89..76df5e1 100644 --- a/src/Features/Reels/ReelsPlayback.xm +++ b/src/Features/Reels/ReelsPlayback.xm @@ -67,15 +67,16 @@ } } - (void)_muteSwitchStateChanged:(id)changed { - if (![SCIUtils getBoolPref:@"disable_auto_unmuting_reels"]) { + extern BOOL sciStoryAudioBypass; + if (sciStoryAudioBypass || ![SCIUtils getBoolPref:@"disable_auto_unmuting_reels"]) { %orig(changed); } } // Block the announcer from broadcasting "audio enabled" state changes - (void)_announceForDeviceStateChangesIfNeededForAudioEnabled:(BOOL)enabled reason:(NSInteger)reason { - // When pause/play mode is on, allow unmute (our force-unmute needs this path) + extern BOOL sciStoryAudioBypass; BOOL pausePlayMode = [[SCIUtils getStringPref:@"reels_tap_control"] isEqualToString:@"pause"]; - if ([SCIUtils getBoolPref:@"disable_auto_unmuting_reels"] && enabled && !pausePlayMode) { + if ([SCIUtils getBoolPref:@"disable_auto_unmuting_reels"] && enabled && !pausePlayMode && !sciStoryAudioBypass) { return; } %orig; diff --git a/src/Features/StoriesAndMessages/ExcludeFromStorySeen.x b/src/Features/StoriesAndMessages/ExcludeFromStorySeen.x index 29c721a..535827c 100644 --- a/src/Features/StoriesAndMessages/ExcludeFromStorySeen.x +++ b/src/Features/StoriesAndMessages/ExcludeFromStorySeen.x @@ -174,11 +174,15 @@ void sciRefreshAllVisibleOverlays(UIViewController *storyVC) { if (!overlayCls) overlayCls = NSClassFromString(@"IGStoryFullscreenOverlayMetalLayerView"); if (!overlayCls) return; SEL refreshSel = @selector(sciRefreshSeenButton); + SEL audioSel = @selector(sciRefreshAudioButton); NSMutableArray *stack = [NSMutableArray arrayWithObject:storyVC.view]; while (stack.count) { UIView *v = stack.lastObject; [stack removeLastObject]; - if ([v isKindOfClass:overlayCls] && [v respondsToSelector:refreshSel]) { - ((void(*)(id, SEL))objc_msgSend)(v, refreshSel); + if ([v isKindOfClass:overlayCls]) { + if ([v respondsToSelector:refreshSel]) + ((void(*)(id, SEL))objc_msgSend)(v, refreshSel); + if ([v respondsToSelector:audioSel]) + ((void(*)(id, SEL))objc_msgSend)(v, audioSel); } for (UIView *sub in v.subviews) [stack addObject:sub]; } diff --git a/src/Features/StoriesAndMessages/OverlayButtons.xm b/src/Features/StoriesAndMessages/OverlayButtons.xm index 4c6461a..14f61a8 100644 --- a/src/Features/StoriesAndMessages/OverlayButtons.xm +++ b/src/Features/StoriesAndMessages/OverlayButtons.xm @@ -14,6 +14,10 @@ extern "C" BOOL sciStorySeenToggleEnabled; extern "C" void sciRefreshAllVisibleOverlays(UIViewController *storyVC); extern "C" void sciTriggerStoryMarkSeen(UIViewController *storyVC); extern "C" __weak UIViewController *sciActiveStoryViewerVC; +extern "C" void sciToggleStoryAudio(void); +extern "C" BOOL sciIsStoryAudioEnabled(void); +extern "C" void sciInitStoryAudioState(void); +extern "C" void sciResetStoryAudioState(void); static SCIDownloadDelegate *sciStoryVideoDl = nil; static SCIDownloadDelegate *sciStoryImageDl = nil; @@ -131,6 +135,29 @@ static void sciDownloadDMVisualMessage(UIViewController *dmVC) { ]]; } + // Audio toggle button (left side, small) + sciInitStoryAudioState(); + if ([SCIUtils getBoolPref:@"story_audio_toggle"] && ![self viewWithTag:1341]) { + UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; + btn.tag = 1341; + UIImageSymbolConfiguration *cfg = [UIImageSymbolConfiguration configurationWithPointSize:14 weight:UIImageSymbolWeightSemibold]; + NSString *icon = sciIsStoryAudioEnabled() ? @"speaker.wave.2" : @"speaker.slash"; + [btn setImage:[UIImage systemImageNamed:icon withConfiguration:cfg] forState:UIControlStateNormal]; + btn.tintColor = [UIColor whiteColor]; + btn.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.4]; + btn.layer.cornerRadius = 14; + btn.clipsToBounds = YES; + btn.translatesAutoresizingMaskIntoConstraints = NO; + [btn addTarget:self action:@selector(sciAudioToggleTapped:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:btn]; + [NSLayoutConstraint activateConstraints:@[ + [btn.bottomAnchor constraintEqualToAnchor:self.safeAreaLayoutGuide.bottomAnchor constant:-100], + [btn.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:12], + [btn.widthAnchor constraintEqualToConstant:28], + [btn.heightAnchor constraintEqualToConstant:28] + ]]; + } + // Seen button — deferred so the responder chain is wired up __weak UIView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ @@ -141,6 +168,15 @@ static void sciDownloadDMVisualMessage(UIViewController *dmVC) { // ============ Seen button lifecycle ============ +// Refresh the audio toggle icon (tag 1341) to match current state. +%new - (void)sciRefreshAudioButton { + UIButton *btn = (UIButton *)[self viewWithTag:1341]; + if (!btn) return; + UIImageSymbolConfiguration *cfg = [UIImageSymbolConfiguration configurationWithPointSize:14 weight:UIImageSymbolWeightSemibold]; + NSString *icon = sciIsStoryAudioEnabled() ? @"speaker.wave.2" : @"speaker.slash"; + [btn setImage:[UIImage systemImageNamed:icon withConfiguration:cfg] forState:UIControlStateNormal]; +} + // Rebuilds the eye button (tag 1339) based on current owner + prefs. Idempotent. %new - (void)sciRefreshSeenButton { if (![SCIUtils getBoolPref:@"no_seen_receipt"]) return; @@ -192,11 +228,11 @@ static void sciDownloadDMVisualMessage(UIViewController *dmVC) { lp.minimumPressDuration = 0.4; [btn addGestureRecognizer:lp]; [self addSubview:btn]; - UIView *dlBtn = [self viewWithTag:1340]; - if (dlBtn) { + UIView *anchor = [self viewWithTag:1340]; + if (anchor) { [NSLayoutConstraint activateConstraints:@[ - [btn.centerYAnchor constraintEqualToAnchor:dlBtn.centerYAnchor], - [btn.trailingAnchor constraintEqualToAnchor:dlBtn.leadingAnchor constant:-10], + [btn.centerYAnchor constraintEqualToAnchor:anchor.centerYAnchor], + [btn.trailingAnchor constraintEqualToAnchor:anchor.leadingAnchor constant:-10], [btn.widthAnchor constraintEqualToConstant:36], [btn.heightAnchor constraintEqualToConstant:36] ]]; @@ -210,12 +246,26 @@ static void sciDownloadDMVisualMessage(UIViewController *dmVC) { } } -// Refresh when story owner changes (overlay reuse across reels) +// Refresh when story owner changes or audio state changes - (void)layoutSubviews { %orig; - if (![SCIUtils getBoolPref:@"no_seen_receipt"]) return; static char kLastPKKey; static char kLastExclKey; + static char kLastAudioKey; + + // Audio button: check if state changed + UIButton *audioBtn = (UIButton *)[self viewWithTag:1341]; + if (audioBtn) { + BOOL audioOn = sciIsStoryAudioEnabled(); + NSNumber *prevAudio = objc_getAssociatedObject(self, &kLastAudioKey); + if (!prevAudio || [prevAudio boolValue] != audioOn) { + objc_setAssociatedObject(self, &kLastAudioKey, @(audioOn), OBJC_ASSOCIATION_RETAIN_NONATOMIC); + ((void(*)(id, SEL))objc_msgSend)(self, @selector(sciRefreshAudioButton)); + } + } + + // Seen button: check if owner/exclusion changed + if (![SCIUtils getBoolPref:@"no_seen_receipt"]) return; NSDictionary *info = sciOwnerInfoForView(self); NSString *pk = info[@"pk"] ?: @""; BOOL excluded = pk.length && [SCIExcludedStoryUsers isUserPKExcluded:pk]; @@ -228,6 +278,17 @@ static void sciDownloadDMVisualMessage(UIViewController *dmVC) { ((void(*)(id, SEL))objc_msgSend)(self, @selector(sciRefreshSeenButton)); } +// ============ Audio toggle handler ============ + +%new - (void)sciAudioToggleTapped:(UIButton *)sender { + UIImpactFeedbackGenerator *haptic = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; + [haptic impactOccurred]; + sciToggleStoryAudio(); + UIImageSymbolConfiguration *cfg = [UIImageSymbolConfiguration configurationWithPointSize:14 weight:UIImageSymbolWeightSemibold]; + NSString *icon = sciIsStoryAudioEnabled() ? @"speaker.wave.2" : @"speaker.slash"; + [sender setImage:[UIImage systemImageNamed:icon withConfiguration:cfg] forState:UIControlStateNormal]; +} + // ============ Download handler ============ %new - (void)sciDownloadTapped:(UIButton *)sender { @@ -471,10 +532,12 @@ static void sciSyncStoryButtonsAlpha(UIView *self_, CGFloat alpha) { while (cur) { for (UIView *sib in cur.superview.subviews) { if (![sib isKindOfClass:overlayCls]) continue; - UIView *seen = [sib viewWithTag:1339]; - UIView *dl = [sib viewWithTag:1340]; - if (seen) seen.alpha = alpha; - if (dl) dl.alpha = alpha; + UIView *seen = [sib viewWithTag:1339]; + UIView *dl = [sib viewWithTag:1340]; + UIView *audio = [sib viewWithTag:1341]; + if (seen) seen.alpha = alpha; + if (dl) dl.alpha = alpha; + if (audio) audio.alpha = alpha; return; } cur = cur.superview; diff --git a/src/Features/StoriesAndMessages/StoryAudioToggle.xm b/src/Features/StoriesAndMessages/StoryAudioToggle.xm new file mode 100644 index 0000000..16c26ea --- /dev/null +++ b/src/Features/StoriesAndMessages/StoryAudioToggle.xm @@ -0,0 +1,155 @@ +// Story audio mute/unmute toggle. Posts mute-switch-state-changed to toggle +// IG's audio. Reads _audioEnabled on IGAudioStatusAnnouncer for icon state. + +#import +#import "StoryHelpers.h" +#import +#import +#import + +extern "C" __weak UIViewController *sciActiveStoryViewerVC; +extern "C" void sciRefreshAllVisibleOverlays(UIViewController *); + +static id sciAudioAnnouncer = nil; + +static BOOL sciIGAudioEnabled(void) { + if (!sciAudioAnnouncer) return NO; + Ivar ivar = class_getInstanceVariable([sciAudioAnnouncer class], "_audioEnabled"); + if (!ivar) return NO; + ptrdiff_t offset = ivar_getOffset(ivar); + return *(BOOL *)((char *)(__bridge void *)sciAudioAnnouncer + offset); +} + +// ============ Volume KVO ============ + +@interface _SciVolumeObserver : NSObject +@end +@implementation _SciVolumeObserver +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object + change:(NSDictionary *)change context:(void *)context { + dispatch_async(dispatch_get_main_queue(), ^{ + if (sciActiveStoryViewerVC) sciRefreshAllVisibleOverlays(sciActiveStoryViewerVC); + }); +} +@end +static _SciVolumeObserver *sciVolumeObserver = nil; + +// ============ Public API ============ + +extern "C" { + +BOOL sciStoryAudioBypass = NO; + +void sciToggleStoryAudio(void) { + BOOL on = sciIGAudioEnabled(); + sciStoryAudioBypass = YES; + [[NSNotificationCenter defaultCenter] + postNotificationName:@"mute-switch-state-changed" + object:nil + userInfo:@{@"mute-state": @(on ? 0 : 1)}]; + sciStoryAudioBypass = NO; + if (sciActiveStoryViewerVC) sciRefreshAllVisibleOverlays(sciActiveStoryViewerVC); +} + +BOOL sciIsStoryAudioEnabled(void) { + return sciIGAudioEnabled(); +} + +void sciInitStoryAudioState(void) { + if (!sciVolumeObserver) sciVolumeObserver = [_SciVolumeObserver new]; + @try { + [[AVAudioSession sharedInstance] addObserver:sciVolumeObserver + forKeyPath:@"outputVolume" + options:NSKeyValueObservingOptionNew + context:NULL]; + } @catch (__unused id e) {} +} + +void sciResetStoryAudioState(void) { + @try { + [[AVAudioSession sharedInstance] removeObserver:sciVolumeObserver forKeyPath:@"outputVolume"]; + } @catch (__unused id e) {} +} + +} // extern "C" + +// ============ Announcer hooks ============ + +static id (*orig_announcerInit)(id, SEL); +static id new_announcerInit(id self, SEL _cmd) { + id r = orig_announcerInit(self, _cmd); + sciAudioAnnouncer = self; + return r; +} + +static void (*orig_announce)(id, SEL, BOOL, NSInteger); +static void new_announce(id self, SEL _cmd, BOOL enabled, NSInteger reason) { + orig_announce(self, _cmd, enabled, reason); + if (sciActiveStoryViewerVC) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (sciActiveStoryViewerVC) sciRefreshAllVisibleOverlays(sciActiveStoryViewerVC); + }); + } +} + +// ============ 3-dot menu item ============ + +extern "C" NSArray *sciMaybeAppendStoryAudioMenuItem(NSArray *items) { + if (!sciActiveStoryViewerVC) return items; + + BOOL looksLikeStoryHeader = NO; + for (id it in items) { + @try { + NSString *t = [NSString stringWithFormat:@"%@", [it valueForKey:@"title"] ?: @""]; + if ([t isEqualToString:@"Report"] || [t isEqualToString:@"Mute"] || + [t isEqualToString:@"Unfollow"] || [t isEqualToString:@"Follow"] || + [t isEqualToString:@"Hide"]) { looksLikeStoryHeader = YES; break; } + } @catch (__unused id e) {} + } + if (!looksLikeStoryHeader) return items; + + Class menuItemCls = NSClassFromString(@"IGDSMenuItem"); + if (!menuItemCls) return items; + + BOOL on = sciIGAudioEnabled(); + NSString *title = on ? @"Mute story audio" : @"Unmute story audio"; + void (^handler)(void) = ^{ sciToggleStoryAudio(); }; + + id newItem = nil; + @try { + typedef id (*Init)(id, SEL, id, id, id); + newItem = ((Init)objc_msgSend)([menuItemCls alloc], + @selector(initWithTitle:image:handler:), title, nil, handler); + } @catch (__unused id e) {} + + if (!newItem) return items; + NSMutableArray *newItems = [items mutableCopy]; + [newItems addObject:newItem]; + return [newItems copy]; +} + +// ============ Ringer listener ============ + +static void sciRingerChanged(CFNotificationCenterRef center, void *observer, + CFNotificationName name, const void *object, + CFDictionaryRef userInfo) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (sciActiveStoryViewerVC) sciRefreshAllVisibleOverlays(sciActiveStoryViewerVC); + }); +} + +// ============ Init ============ + +__attribute__((constructor)) static void _storyAudioInit(void) { + CFNotificationCenterAddObserver( + CFNotificationCenterGetDarwinNotifyCenter(), NULL, + sciRingerChanged, CFSTR("com.apple.springboard.ringerstate"), + NULL, CFNotificationSuspensionBehaviorDeliverImmediately); + + Class cls = NSClassFromString(@"IGAudioStatusAnnouncer"); + if (!cls) return; + MSHookMessageEx(cls, @selector(init), (IMP)new_announcerInit, (IMP *)&orig_announcerInit); + SEL s = NSSelectorFromString(@"_announceForDeviceStateChangesIfNeededForAudioEnabled:reason:"); + if (class_getInstanceMethod(cls, s)) + MSHookMessageEx(cls, s, (IMP)new_announce, (IMP *)&orig_announce); +} diff --git a/src/Settings/SCISettingsViewController.m b/src/Settings/SCISettingsViewController.m index c593b78..04f57c9 100644 --- a/src/Settings/SCISettingsViewController.m +++ b/src/Settings/SCISettingsViewController.m @@ -78,9 +78,17 @@ static char rowStaticRef[] = "row"; self.navigationItem.searchController = sc; self.navigationItem.hidesSearchBarWhenScrolling = NO; self.searchController = sc; + + self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemClose + target:self action:@selector(sciDismissSettings)]; } } +- (void)sciDismissSettings { + [self dismissViewControllerAnimated:YES completion:nil]; +} + - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tableView reloadData]; diff --git a/src/Settings/TweakSettings.m b/src/Settings/TweakSettings.m index 7984138..1f5426a 100644 --- a/src/Settings/TweakSettings.m +++ b/src/Settings/TweakSettings.m @@ -187,6 +187,12 @@ }), ] }, + @{ + @"header": @"Audio", + @"rows": @[ + [SCISetting switchCellWithTitle:@"Story audio toggle" subtitle:@"Adds a speaker button to the story overlay to unmute/mute audio. Also available in the 3-dot menu" defaultsKey:@"story_audio_toggle"], + ] + }, @{ @"header": @"Other", @"rows": @[ @@ -361,33 +367,38 @@ // } // ] // ], + [SCISetting navigationCellWithTitle:@"Advanced" + subtitle:@"" + icon:[SCISymbol symbolWithName:@"gearshape.2"] + navSections:@[@{ + @"header": @"Settings", + @"rows": @[ + [SCISetting switchCellWithTitle:@"Enable tweak settings quick-access" subtitle:@"Hold on the home tab to open RyukGram settings" defaultsKey:@"settings_shortcut" requiresRestart:YES], + [SCISetting switchCellWithTitle:@"Show tweak settings on app launch" subtitle:@"Automatically opens settings when the app launches" defaultsKey:@"tweak_settings_app_launch"], + [SCISetting switchCellWithTitle:@"Pause playback when opening settings" subtitle:@"Pauses any playing video/audio when settings opens" defaultsKey:@"settings_pause_playback"], + ] + }, + @{ + @"header": @"Instagram", + @"rows": @[ + [SCISetting switchCellWithTitle:@"Disable safe mode" subtitle:@"Prevents Instagram from resetting settings after crashes (at your own risk)" defaultsKey:@"disable_safe_mode"], + [SCISetting buttonCellWithTitle:@"Reset onboarding state" + subtitle:@"" + icon:nil + action:^(void) { [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"SCInstaFirstRun"]; [SCIUtils showRestartConfirmation];} + ], + ] + }] + ], [SCISetting navigationCellWithTitle:@"Debug" subtitle:@"" icon:[SCISymbol symbolWithName:@"ladybug"] navSections:@[@{ @"header": @"FLEX", @"rows": @[ - [SCISetting switchCellWithTitle:@"Enable FLEX gesture" subtitle:@"Allows you to hold 5 fingers on the screen to open the FLEX explorer" defaultsKey:@"flex_instagram"], - [SCISetting switchCellWithTitle:@"Open FLEX on app launch" subtitle:@"Automatically opens the FLEX explorer when the app launches" defaultsKey:@"flex_app_launch"], - [SCISetting switchCellWithTitle:@"Open FLEX on app focus" subtitle:@"Automatically opens the FLEX explorer when the app is focused" defaultsKey:@"flex_app_start"] - ] - }, - @{ - @"header": @"RyukGram", - @"rows": @[ - [SCISetting switchCellWithTitle:@"Enable tweak settings quick-access" subtitle:@"Allows you to hold on the home tab to open the RyukGram settings" defaultsKey:@"settings_shortcut" requiresRestart:YES], - [SCISetting switchCellWithTitle:@"Show tweak settings on app launch" subtitle:@"Automatically opens the RyukGram settings when the app launches" defaultsKey:@"tweak_settings_app_launch"], - [SCISetting buttonCellWithTitle:@"Reset onboarding completion state" - subtitle:@"" - icon:nil - action:^(void) { [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"SCInstaFirstRun"]; [SCIUtils showRestartConfirmation];} - ], - ] - }, - @{ - @"header": @"Instagram", - @"rows": @[ - [SCISetting switchCellWithTitle:@"Disable safe mode" subtitle:@"Makes Instagram not reset settings after subsequent crashes (at your own risk)" defaultsKey:@"disable_safe_mode"] + [SCISetting switchCellWithTitle:@"Enable FLEX gesture" subtitle:@"Hold 5 fingers on the screen to open FLEX" defaultsKey:@"flex_instagram"], + [SCISetting switchCellWithTitle:@"Open FLEX on app launch" subtitle:@"Opens FLEX when the app launches" defaultsKey:@"flex_app_launch"], + [SCISetting switchCellWithTitle:@"Open FLEX on app focus" subtitle:@"Opens FLEX when the app is focused" defaultsKey:@"flex_app_start"] ] }, @{ diff --git a/src/Tweak.x b/src/Tweak.x index d18569f..b0ce149 100644 --- a/src/Tweak.x +++ b/src/Tweak.x @@ -44,7 +44,8 @@ BOOL dmVisualMsgsViewedButtonEnabled = false; @"swipe_nav_tabs": @"default", @"enable_notes_customization": @(YES), @"custom_note_themes": @(YES), - @"disable_auto_unmuting_reels": @(YES), + @"disable_auto_unmuting_reels": @(NO), + @"settings_shortcut": @(YES), @"doom_scrolling_reel_count": @(1), @"no_seen_visual": @(YES), @"send_audio_as_file": @(YES), @@ -64,7 +65,9 @@ BOOL dmVisualMsgsViewedButtonEnabled = false; @"unexclude_inbox_button": @(YES), @"enable_story_user_exclusions": @(YES), @"story_excluded_show_unexclude_eye": @(YES), - @"story_seen_mode": @"button" + @"story_seen_mode": @"button", + @"story_audio_toggle": @(NO), + @"settings_pause_playback": @(YES) }; [[NSUserDefaults standardUserDefaults] registerDefaults:sciDefaults]; @@ -615,7 +618,9 @@ shouldPersistLastBugReportId:(id)arg6 } extern NSArray *sciMaybeAppendStoryExcludeMenuItem(NSArray *); + extern NSArray *sciMaybeAppendStoryAudioMenuItem(NSArray *); NSArray *finalObjs = sciMaybeAppendStoryExcludeMenuItem([filteredObjs copy]); + finalObjs = sciMaybeAppendStoryAudioMenuItem(finalObjs); return %orig(finalObjs, edr, headerLabelText); } %end diff --git a/src/Utils.m b/src/Utils.m index a5f07c8..8bccab8 100644 --- a/src/Utils.m +++ b/src/Utils.m @@ -114,6 +114,8 @@ UIViewController *rootController = [window rootViewController]; SCISettingsViewController *settingsViewController = [SCISettingsViewController new]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsViewController]; + if ([SCIUtils getBoolPref:@"settings_pause_playback"]) + navigationController.modalPresentationStyle = UIModalPresentationFullScreen; [rootController presentViewController:navigationController animated:YES completion:nil]; } @@ -124,6 +126,8 @@ while (rootController.presentedViewController) rootController = rootController.presentedViewController; SCISettingsViewController *root = [SCISettingsViewController new]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:root]; + if ([SCIUtils getBoolPref:@"settings_pause_playback"]) + nav.modalPresentationStyle = UIModalPresentationFullScreen; NSArray *targetNavSections = nil; for (NSDictionary *section in [SCITweakSettings sections]) {