Skip to content

Commit 8a7dbf0

Browse files
committed
Add feature to remove suggested accounts from feed & other improvements
1 parent c11e03f commit 8a7dbf0

14 files changed

Lines changed: 308 additions & 195 deletions

‎src/Controllers/SettingsViewController.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ typedef NS_ENUM(NSInteger, DynamicSpecifierOperatorType) {
2323
- (PSSpecifier *)newSwitchCellWithTitle:(NSString *)titleText detailTitle:(NSString *)detailText key:(NSString *)keyText defaultValue:(BOOL)defValue changeAction:(SEL)changeAction;
2424
- (PSSpecifier *)newButtonCellWithTitle:(NSString *)titleText detailTitle:(NSString *)detailText dynamicRule:(NSString *)rule action:(SEL)action;
2525
- (PSSpecifier *)newHBLinkCellWithTitle:(NSString *)titleText detailTitle:(NSString *)detailText url:(NSString *)url;
26+
- (PSSpecifier *)newHBButtonCellWithTitle:(NSString *)titleText action:(SEL)action;
2627
- (PSSpecifier *)newHBTwitterCellWithTitle:(NSString *)titleText twitterUsername:(NSString *)user customAvatarURL:(NSString *)avatarURL;
28+
- (void)_clearCache;
2729
- (void)reloadSpecifiers;
2830
- (void)collectDynamicSpecifiersFromArray:(NSArray *)array;
2931
- (BOOL)shouldHideSpecifier:(PSSpecifier *)specifier;

‎src/Controllers/SettingsViewController.m‎

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ - (PSSpecifier *)newHBLinkCellWithTitle:(NSString *)titleText detailTitle:(NSStr
6767
}
6868
return HBLinkCell;
6969
}
70+
- (PSSpecifier *)newHBButtonCellWithTitle:(NSString *)titleText action:(SEL)action {
71+
PSSpecifier *HBButtonCell = [PSSpecifier preferenceSpecifierNamed:titleText target:self set:@selector(setPreferenceValue:specifier:) get:@selector(readPreferenceValue:) detail:nil cell:PSButtonCell edit:nil];
72+
73+
[HBButtonCell setButtonAction:@selector(action:)];
74+
[HBButtonCell setProperty:HBTintedTableCell.class forKey:@"cellClass"];
75+
return HBButtonCell;
76+
}
7077
- (PSSpecifier *)newHBTwitterCellWithTitle:(NSString *)titleText twitterUsername:(NSString *)user customAvatarURL:(NSString *)avatarURL {
7178
PSSpecifier *TwitterCell = [PSSpecifier preferenceSpecifierNamed:titleText target:self set:@selector(setPreferenceValue:specifier:) get:@selector(readPreferenceValue:) detail:nil cell:1 edit:nil];
7279

@@ -83,13 +90,14 @@ - (NSArray *)specifiers {
8390
_specifiers = [NSMutableArray arrayWithArray:@[
8491
// Section 1: General
8592
[self newSectionWithTitle:@"General" footer:nil],
86-
[self newSwitchCellWithTitle:@"Hide Ads" detailTitle:@"Remove all ads from the Instagram app" key:@"hide_ads" defaultValue:true changeAction:nil],
8793
[self newSwitchCellWithTitle:@"Show Like count" detailTitle:@"Show like count in the post" key:@"show_like_count" defaultValue:true changeAction:nil],
8894
[self newSwitchCellWithTitle:@"Copy description" detailTitle:@"Copy the post description with a long press" key:@"copy_description" defaultValue:true changeAction:nil],
8995

9096
// Section 2: Feed
9197
[self newSectionWithTitle:@"Feed" footer:nil],
98+
[self newSwitchCellWithTitle:@"Hide Ads" detailTitle:@"Remove all ads from the Instagram app" key:@"hide_ads" defaultValue:true changeAction:nil],
9299
[self newSwitchCellWithTitle:@"No suggested posts" detailTitle:@"Remove suggested posts from your feed" key:@"no_suggested_post" defaultValue:false changeAction:nil],
100+
[self newSwitchCellWithTitle:@"No suggested for you" detailTitle:@"Hide suggested accounts for you to follow" key:@"no_suggested_account" defaultValue:false changeAction:nil],
93101

94102
// Section 3: Confirm actions
95103
[self newSectionWithTitle:@"Confirm actions" footer:nil],
@@ -119,6 +127,7 @@ - (NSArray *)specifiers {
119127
// Section 7: Debugging
120128
[self newSectionWithTitle:@"Debugging" footer:nil],
121129
[self newSwitchCellWithTitle:@"Enable FLEX" detailTitle:@"Show FLEX on instagram app." key:@"flex_instagram" defaultValue:false changeAction:@selector(FLEXAction:)],
130+
/* [self newHBButtonCellWithTitle:@"Clear cache" action:@selector(_clearCache:)], */
122131

123132
// Section 8: Credits
124133
[self newSectionWithTitle:@"Credits" footer:nil],
@@ -132,6 +141,47 @@ - (NSArray *)specifiers {
132141

133142
return _specifiers;
134143
}
144+
145+
- (void)_clearCache {
146+
JGProgressHUD *HUD = [[JGProgressHUD alloc] init];
147+
HUD.textLabel.text = @"Wowza.";
148+
HUD.indicatorView = [[JGProgressHUDErrorIndicatorView alloc] init];
149+
[HUD showInView:topMostController().view];
150+
[HUD dismissAfterDelay:2.0];
151+
152+
NSFileManager *fileManager = [NSFileManager defaultManager];
153+
NSString *directoryPath = [NSHomeDirectory() stringByAppendingString:@"/Documents/Library/Caches/"];
154+
155+
if ([fileManager fileExistsAtPath:directoryPath]) {
156+
NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:directoryPath];
157+
NSString *documentsName;
158+
while (documentsName = [dirEnum nextObject]) {
159+
NSString *filePath = [directoryPath stringByAppendingString:documentsName];
160+
BOOL isFileDeleted = [fileManager removeItemAtPath:filePath error:nil];
161+
if (isFileDeleted == NO) {
162+
163+
// Not all files were removed (error)
164+
JGProgressHUD *HUD = [[JGProgressHUD alloc] init];
165+
HUD.textLabel.text = @"Could not clear cache.";
166+
HUD.indicatorView = [[JGProgressHUDErrorIndicatorView alloc] init];
167+
[HUD showInView:topMostController().view];
168+
[HUD dismissAfterDelay:2.0];
169+
170+
NSLog(@"Error clearing cache!");
171+
break;
172+
173+
}
174+
}
175+
176+
// Success
177+
JGProgressHUD *HUD = [[JGProgressHUD alloc] init];
178+
HUD.textLabel.text = @"Cache has been cleared!";
179+
HUD.indicatorView = [[JGProgressHUDSuccessIndicatorView alloc] init];
180+
[HUD showInView:topMostController().view];
181+
[HUD dismissAfterDelay:2.0];
182+
}
183+
}
184+
135185
- (void)reloadSpecifiers {
136186
[super reloadSpecifiers];
137187

‎src/Features/Confirm/LikeConfirm.x‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,21 @@
110110
}
111111
}
112112
%end
113+
114+
// Liking stories
115+
%hook IGStoryFullscreenDefaultFooterView
116+
- (void)_likeTapped {
117+
if ([BHIManager postLikeConfirmation]) {
118+
showConfirmation(^(void) { %orig; });
119+
} else {
120+
return %orig;
121+
}
122+
}
123+
- (void)inputView:(id)arg1 didTapLikeButton:(id)arg2 {
124+
if ([BHIManager postLikeConfirmation]) {
125+
showConfirmation(^(void) { %orig; });
126+
} else {
127+
return %orig;
128+
}
129+
}
130+
%end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
static NSArray *removeAdsItemsInList(NSArray *list) {
55
NSMutableArray *orig = [list mutableCopy];
66
[orig enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
7+
// Remove suggested posts
78
if ([BHIManager removeSuggestedPost]) {
89
if ([obj respondsToSelector:@selector(explorePostInFeed)] && [obj performSelector:@selector(explorePostInFeed)]) {
910
[orig removeObjectAtIndex:idx];
@@ -17,6 +18,7 @@ static NSArray *removeAdsItemsInList(NSArray *list) {
1718
return [orig copy];
1819
}
1920

21+
// Suggested posts
2022
%hook IGMainFeedListAdapterDataSource
2123
- (NSArray *)objectsForListAdapter:(id)arg1 {
2224
if ([BHIManager hideAds]) {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#import "../../InstagramHeaders.h"
2+
#import "../../Manager.h"
3+
4+
// Remove suggested for you (accounts)
5+
%hook IGHScrollAYMFSectionController
6+
- (id)initWithUserSession:(id)arg1 sessionId:(id)arg2 analyticsModule:(id)arg3 format:(NSInteger)arg4 netEgoItemType:(NSUInteger)arg5 netegoImpressionStrategy:(id)arg6 isForcedDarkModeImmersive:(BOOL)arg7 {
7+
if ([BHIManager removeSuggestedAccounts]) {
8+
return nil;
9+
}
10+
return %orig;
11+
}
12+
%end

‎src/Features/Save/StoriesSave.x‎

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#import "../../InstagramHeaders.h"
2+
#import "../../Manager.h"
3+
#import "../../Tweak.h"
4+
#import "../../Utils.h"
5+
6+
%hook IGStoryViewerContainerView
7+
%property (nonatomic, strong) JGProgressHUD *hud;
8+
%property (nonatomic, retain) UIButton *hDownloadButton;
9+
%property (nonatomic, retain) NSString *fileextension;
10+
- (id)initWithFrame:(CGRect)arg1 shouldCreateComposerBackgroundView:(BOOL)arg2 userSession:(id)arg3 bloksContext:(id)arg4 {
11+
self = %orig;
12+
if ([BHIManager downloadVideos]) {
13+
self.hDownloadButton = [UIButton buttonWithType:UIButtonTypeSystem];
14+
[self.hDownloadButton addTarget:self action:@selector(hDownloadButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
15+
[self.hDownloadButton setImage:[UIImage systemImageNamed:@"arrow.down.to.line.circle.fill"] forState:UIControlStateNormal];
16+
[self.hDownloadButton setTranslatesAutoresizingMaskIntoConstraints:false];
17+
18+
[self addSubview:self.hDownloadButton];
19+
[NSLayoutConstraint activateConstraints:@[
20+
[self.hDownloadButton.topAnchor constraintEqualToAnchor:self.topAnchor constant:(self.frame.size.height - (isNotch() ? 120.0 : 90.0))],
21+
[self.hDownloadButton.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
22+
[self.hDownloadButton.widthAnchor constraintEqualToConstant:50],
23+
[self.hDownloadButton.heightAnchor constraintEqualToConstant:50],
24+
]];
25+
}
26+
27+
return self;
28+
}
29+
%new - (void)hDownloadButtonPressed:(UIButton *)sender {
30+
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"BHInsta Downloader" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
31+
32+
if ([self.mediaView isKindOfClass:%c(IGStoryPhotoView)]) {
33+
NSURL *url = ((IGStoryPhotoView *)self.mediaView).photoView.imageSpecifier.url;
34+
self.fileextension = @"png";
35+
36+
[alert addAction:[UIAlertAction actionWithTitle:@"Download Photo" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
37+
BHIDownload *dwManager = [[BHIDownload alloc] init];
38+
[dwManager downloadFileWithURL:url];
39+
[dwManager setDelegate:self];
40+
41+
self.hud = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
42+
self.hud.textLabel.text = @"Downloading";
43+
[self.hud showInView:topMostController().view];
44+
}]];
45+
} else if ([self.mediaView isKindOfClass:%c(IGStoryVideoView)]) {
46+
IGVideo *_video = [((IGStoryVideoView *)self.mediaView).videoPlayer valueForKey:@"_video"];
47+
self.fileextension = @"mp4";
48+
NSArray *videoURLArray = [_video.allVideoURLs allObjects];
49+
50+
for (int i = 0; i < [videoURLArray count]; i++) {
51+
[alert addAction:[UIAlertAction actionWithTitle:[NSString stringWithFormat:@"Download Video: Link %d (%@)", i + 1, i == 0 ? @"HD" : @"SD"] style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
52+
BHIDownload *dwManager = [[BHIDownload alloc] init];
53+
[dwManager downloadFileWithURL:[videoURLArray objectAtIndex:i]];
54+
[dwManager setDelegate:self];
55+
self.hud = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark];
56+
self.hud.textLabel.text = @"Downloading";
57+
[self.hud showInView:topMostController().view];
58+
}]];
59+
}
60+
}
61+
62+
// Currently not working (dunno why and im lazy too fix)
63+
/* if (self.delegate != nil) {
64+
[alert addAction:[UIAlertAction actionWithTitle:@"Mark as Seen" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
65+
shouldBeSeen = true;
66+
if ([self.delegate isKindOfClass:%c(IGStoryFullscreenSectionController)]) {
67+
IGStoryFullscreenSectionController *storyController = self.delegate;
68+
if ([storyController.delegate isKindOfClass:%c(IGStoryViewerViewController)]) {
69+
IGStoryViewerViewController *storyViewController = storyController.delegate;
70+
id currentItem = [storyViewController valueForKey:@"_focusStoryItemOnEntry"];
71+
[storyViewController fullscreenSectionController:[storyViewController _getMostVisibleSectionController] didMarkItemAsSeen:currentItem];
72+
}
73+
}
74+
}]];
75+
} */
76+
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
77+
[self.viewController presentViewController:alert animated:YES completion:nil];
78+
}
79+
%new - (void)downloadProgress:(float)progress {
80+
self.hud.detailTextLabel.text = [BHIManager getDownloadingPersent:progress];
81+
}
82+
%new - (void)downloadDidFinish:(NSURL *)filePath Filename:(NSString *)fileName {
83+
NSString *DocPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
84+
NSFileManager *manager = [NSFileManager defaultManager];
85+
NSURL *newFilePath = [[NSURL fileURLWithPath:DocPath] URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", NSUUID.UUID.UUIDString, self.fileextension]];
86+
[manager moveItemAtURL:filePath toURL:newFilePath error:nil];
87+
88+
[self.hud dismiss];
89+
[BHIManager showSaveVC:newFilePath];
90+
}
91+
%new - (void)downloadDidFailureWithError:(NSError *)error {
92+
if (error) {
93+
[self.hud dismiss];
94+
}
95+
}
96+
%end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#import "../../InstagramHeaders.h"
2+
#import "../../Manager.h"
3+
#import "../../Tweak.h"
4+
5+
%hook IGStoryViewerViewController
6+
- (void)fullscreenSectionController:(id)arg1 didMarkItemAsSeen:(id)arg2 {
7+
if ([BHIManager noSeenReceipt]) {
8+
%orig;
9+
10+
// Currently not working (dunno why and im lazy too fix)
11+
/* if (shouldBeSeen) {
12+
shouldBeSeen = false;
13+
} */
14+
} else {
15+
return %orig;
16+
}
17+
}
18+
%end

‎src/Features/StoriesAndMessages/NoScreenshotAlert.x‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#import "../../InstagramHeaders.h"
22
#import "../../Manager.h"
33

4+
// ! Note !
5+
// Not sure if this works, have to test
6+
47
%hook IGScreenshotObserver
58
+ (id)_onTakenScreenshot {
69
if ([BHIManager noScreenShotAlert]) {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#import "../../InstagramHeaders.h"
2+
#import "../../Manager.h"
3+
#import "../../Tweak.h"
4+
5+
// Seen buttons (in DMs)
6+
// - Enables no seen for messages
7+
// - Enables unlimited views of DM stories
8+
%hook IGTallNavigationBarView
9+
- (void)setRightBarButtonItems:(NSArray <UIBarButtonItem *> *)items {
10+
NSMutableArray *new_items = [items mutableCopy];
11+
12+
// Messages seen
13+
if ([BHIManager hideLastSeen]) {
14+
UIBarButtonItem *seenButton = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"checkmark.message"] style:UIBarButtonItemStylePlain target:self action:@selector(seenButtonHandler:)];
15+
[new_items addObject:seenButton];
16+
17+
if (seenButtonEnabled) {
18+
[seenButton setTintColor:UIColor.blueColor];
19+
} else {
20+
[seenButton setTintColor:UIColor.labelColor];
21+
}
22+
}
23+
24+
// DM stories viewed
25+
if ([BHIManager unlimitedReplay]) {
26+
UIBarButtonItem *dmStoriesViewedButton = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"photo.badge.checkmark"] style:UIBarButtonItemStylePlain target:self action:@selector(dmStoriesViewedButtonHandler:)];
27+
[new_items addObject:dmStoriesViewedButton];
28+
29+
if (dmStoriesViewedButtonEnabled) {
30+
[dmStoriesViewedButton setTintColor:UIColor.blueColor];
31+
} else {
32+
[dmStoriesViewedButton setTintColor:UIColor.labelColor];
33+
}
34+
}
35+
36+
%orig([new_items copy]);
37+
}
38+
39+
// Messages seen button
40+
%new - (void)seenButtonHandler:(UIBarButtonItem *)sender {
41+
if (seenButtonEnabled) {
42+
seenButtonEnabled = false;
43+
[sender setTintColor:UIColor.labelColor];
44+
} else {
45+
seenButtonEnabled = true;
46+
[sender setTintColor:UIColor.blueColor];
47+
}
48+
}
49+
// DM stories viewed button
50+
%new - (void)dmStoriesViewedButtonHandler:(UIBarButtonItem *)sender {
51+
if (dmStoriesViewedButtonEnabled) {
52+
dmStoriesViewedButtonEnabled = false;
53+
[sender setTintColor:UIColor.labelColor];
54+
} else {
55+
dmStoriesViewedButtonEnabled = true;
56+
[sender setTintColor:UIColor.blueColor];
57+
}
58+
}
59+
%end
60+
61+
// Messages seen logic
62+
%hook IGDirectThreadViewListAdapterDataSource
63+
- (BOOL)shouldUpdateLastSeenMessage {
64+
if ([BHIManager hideLastSeen]) {
65+
// Check if messages should be shown as seen
66+
if (seenButtonEnabled) {
67+
return %orig;
68+
}
69+
return false;
70+
}
71+
72+
return %orig;
73+
}
74+
%end
75+
76+
// DM stories viewed logic
77+
%hook IGStoryPhotoView
78+
- (void)progressImageView:(id)arg1 didLoadImage:(id)arg2 loadSource:(id)arg3 networkRequestSummary:(id)arg4 {
79+
if ([BHIManager unlimitedReplay]) {
80+
// Check if dm stories should be marked as viewed
81+
if (dmStoriesViewedButtonEnabled) {}
82+
else return;
83+
}
84+
85+
return %orig;
86+
}
87+
%end

‎src/InstagramHeaders.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
- (void)_superPresentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(id)completion;
1111
@end
1212

13+
@interface IGMainFeedAppHeaderController: UIViewController
14+
- (void)_superPresentViewController:(UIViewController *)viewController animated:(BOOL)animated completion:(id)completion; // new
15+
@end
16+
1317
@interface IGProfileMenuSheetViewController: IGViewController
1418
@end
1519

@@ -80,7 +84,7 @@
8084
@interface IGProfilePicturePreviewViewController () <BHIDownloadDelegate>
8185
@end
8286

83-
@interface IGFeedItemMediaCell : UICollectionViewCell
87+
@interface IGFeedItemMediaCell: UICollectionViewCell
8488
@property(retain, nonatomic) IGMedia *post;
8589
- (UIImage *)mediaCellCurrentlyDisplayedImage;
8690
@end

0 commit comments

Comments
 (0)