mirror of
https://github.com/faroukbmiled/RyukGram.git
synced 2026-04-30 08:08:30 +02:00
- Read receipt mode setting: button (one-shot) or toggle (blue/white)
- Auto mark seen on interact: locally marks messages as read when you send any message (text, photo, video, audio, sticker)
This commit is contained in:
@@ -79,7 +79,8 @@ A feature-rich iOS tweak for Instagram, forked from [SCInsta](https://github.com
|
||||
|
||||
### Stories and messages
|
||||
- Keep deleted messages
|
||||
- Manually mark messages as seen
|
||||
- Manually mark messages as seen (button or toggle mode) **\***
|
||||
- Auto mark seen on send (marks messages as read when you send any message) **\***
|
||||
- Disable typing status
|
||||
- Unlimited replay of direct stories
|
||||
- Disable view-once limitations
|
||||
|
||||
@@ -1,81 +1,126 @@
|
||||
#import "../../InstagramHeaders.h"
|
||||
#import "../../Tweak.h"
|
||||
#import "../../Utils.h"
|
||||
#import <objc/runtime.h>
|
||||
#import <objc/message.h>
|
||||
#import <substrate.h>
|
||||
|
||||
|
||||
// Seen buttons (in DMs)
|
||||
// - Enables no seen for messages
|
||||
// - Enables unlimited views of DM visual messages
|
||||
|
||||
BOOL dmSeenToggleEnabled = NO;
|
||||
static BOOL sciSeenAutoBypass = NO;
|
||||
|
||||
static BOOL sciIsSeenToggleMode() {
|
||||
return [[SCIUtils getStringPref:@"seen_mode"] isEqualToString:@"toggle"];
|
||||
}
|
||||
|
||||
static BOOL sciAutoInteractEnabled() {
|
||||
return [SCIUtils getBoolPref:@"remove_lastseen"] && [SCIUtils getBoolPref:@"seen_auto_on_interact"];
|
||||
}
|
||||
|
||||
static void sciDoAutoSeen(IGDirectThreadViewController *threadVC) {
|
||||
sciSeenAutoBypass = YES;
|
||||
[threadVC markLastMessageAsSeen];
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
sciSeenAutoBypass = NO;
|
||||
});
|
||||
}
|
||||
|
||||
// ============ AUTO SEEN ON SEND ============
|
||||
|
||||
static void (*orig_setHasSent)(id self, SEL _cmd, BOOL sent);
|
||||
static void new_setHasSent(id self, SEL _cmd, BOOL sent) {
|
||||
orig_setHasSent(self, _cmd, sent);
|
||||
if (!sent || !sciAutoInteractEnabled()) return;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
sciDoAutoSeen((IGDirectThreadViewController *)self);
|
||||
});
|
||||
}
|
||||
|
||||
// ============ NAV BAR BUTTONS ============
|
||||
|
||||
%hook IGTallNavigationBarView
|
||||
- (void)setRightBarButtonItems:(NSArray <UIBarButtonItem *> *)items {
|
||||
NSMutableArray *new_items = [[items filteredArrayUsingPredicate:
|
||||
[NSPredicate predicateWithBlock:^BOOL(UIView *value, NSDictionary *_) {
|
||||
if ([SCIUtils getBoolPref:@"hide_reels_blend"]) {
|
||||
if ([SCIUtils getBoolPref:@"hide_reels_blend"])
|
||||
return ![value.accessibilityIdentifier isEqualToString:@"blend-button"];
|
||||
}
|
||||
|
||||
return true;
|
||||
}]
|
||||
] mutableCopy];
|
||||
|
||||
// Messages seen
|
||||
if ([SCIUtils getBoolPref:@"remove_lastseen"]) {
|
||||
UIBarButtonItem *seenButton = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"checkmark.message"] style:UIBarButtonItemStylePlain target:self action:@selector(seenButtonHandler:)];
|
||||
if (sciIsSeenToggleMode())
|
||||
[seenButton setTintColor:dmSeenToggleEnabled ? SCIUtils.SCIColor_Primary : UIColor.labelColor];
|
||||
[new_items addObject:seenButton];
|
||||
}
|
||||
|
||||
// DM visual messages viewed
|
||||
if ([SCIUtils getBoolPref:@"unlimited_replay"]) {
|
||||
UIBarButtonItem *dmVisualMsgsViewedButton = [[UIBarButtonItem alloc] initWithImage:[UIImage systemImageNamed:@"photo.badge.checkmark"] style:UIBarButtonItemStylePlain target:self action:@selector(dmVisualMsgsViewedButtonHandler:)];
|
||||
[new_items addObject:dmVisualMsgsViewedButton];
|
||||
|
||||
if (dmVisualMsgsViewedButtonEnabled) {
|
||||
[dmVisualMsgsViewedButton setTintColor:SCIUtils.SCIColor_Primary];
|
||||
} else {
|
||||
[dmVisualMsgsViewedButton setTintColor:UIColor.labelColor];
|
||||
}
|
||||
[dmVisualMsgsViewedButton setTintColor:dmVisualMsgsViewedButtonEnabled ? SCIUtils.SCIColor_Primary : UIColor.labelColor];
|
||||
}
|
||||
|
||||
%orig([new_items copy]);
|
||||
}
|
||||
|
||||
// Messages seen button
|
||||
%new - (void)seenButtonHandler:(UIBarButtonItem *)sender {
|
||||
UIViewController *nearestVC = [SCIUtils nearestViewControllerForView:self];
|
||||
if ([nearestVC isKindOfClass:%c(IGDirectThreadViewController)]) {
|
||||
[(IGDirectThreadViewController *)nearestVC markLastMessageAsSeen];
|
||||
// ============ MESSAGES SEEN BUTTON ============
|
||||
|
||||
[SCIUtils showToastForDuration:2.5 title:@"Marked messages as seen"];
|
||||
%new - (void)seenButtonHandler:(UIBarButtonItem *)sender {
|
||||
if (sciIsSeenToggleMode()) {
|
||||
dmSeenToggleEnabled = !dmSeenToggleEnabled;
|
||||
[sender setTintColor:dmSeenToggleEnabled ? SCIUtils.SCIColor_Primary : UIColor.labelColor];
|
||||
if (dmSeenToggleEnabled) {
|
||||
UIViewController *nearestVC = [SCIUtils nearestViewControllerForView:self];
|
||||
if ([nearestVC isKindOfClass:%c(IGDirectThreadViewController)])
|
||||
[(IGDirectThreadViewController *)nearestVC markLastMessageAsSeen];
|
||||
[SCIUtils showToastForDuration:2.5 title:@"Read receipts enabled"];
|
||||
} else {
|
||||
[SCIUtils showToastForDuration:2.5 title:@"Read receipts disabled"];
|
||||
}
|
||||
} else {
|
||||
UIViewController *nearestVC = [SCIUtils nearestViewControllerForView:self];
|
||||
if ([nearestVC isKindOfClass:%c(IGDirectThreadViewController)]) {
|
||||
[(IGDirectThreadViewController *)nearestVC markLastMessageAsSeen];
|
||||
[SCIUtils showToastForDuration:2.5 title:@"Marked messages as seen"];
|
||||
}
|
||||
}
|
||||
}
|
||||
// DM visual messages viewed button
|
||||
|
||||
// ============ DM VISUAL MESSAGES VIEWED BUTTON ============
|
||||
|
||||
%new - (void)dmVisualMsgsViewedButtonHandler:(UIBarButtonItem *)sender {
|
||||
if (dmVisualMsgsViewedButtonEnabled) {
|
||||
dmVisualMsgsViewedButtonEnabled = false;
|
||||
[sender setTintColor:UIColor.labelColor];
|
||||
|
||||
[SCIUtils showToastForDuration:4.5 title:@"Visual messages can be replayed without expiring"];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dmVisualMsgsViewedButtonEnabled = true;
|
||||
[sender setTintColor:SCIUtils.SCIColor_Primary];
|
||||
|
||||
[SCIUtils showToastForDuration:4.5 title:@"Visual messages will now expire after viewing"];
|
||||
}
|
||||
}
|
||||
%end
|
||||
|
||||
// Messages seen logic
|
||||
// ============ SEEN BLOCKING LOGIC ============
|
||||
|
||||
%hook IGDirectThreadViewListAdapterDataSource
|
||||
- (BOOL)shouldUpdateLastSeenMessage {
|
||||
if ([SCIUtils getBoolPref:@"remove_lastseen"]) {
|
||||
if (sciIsSeenToggleMode() && dmSeenToggleEnabled) return %orig;
|
||||
if (sciSeenAutoBypass) return %orig;
|
||||
return false;
|
||||
}
|
||||
|
||||
return %orig;
|
||||
}
|
||||
%end
|
||||
|
||||
// DM visual messages viewed logic
|
||||
// ============ DM VISUAL MESSAGES VIEWED LOGIC ============
|
||||
|
||||
%hook IGDirectVisualMessageViewerEventHandler
|
||||
- (void)visualMessageViewerController:(id)arg1 didBeginPlaybackForVisualMessage:(id)arg2 atIndex:(NSInteger)arg3 {
|
||||
if ([SCIUtils getBoolPref:@"unlimited_replay"] && !dmVisualMsgsViewedButtonEnabled) return;
|
||||
@@ -85,4 +130,17 @@
|
||||
if ([SCIUtils getBoolPref:@"unlimited_replay"] && !dmVisualMsgsViewedButtonEnabled) return;
|
||||
%orig;
|
||||
}
|
||||
%end
|
||||
%end
|
||||
|
||||
// ============ RUNTIME HOOKS ============
|
||||
|
||||
%ctor {
|
||||
Class threadVCClass = NSClassFromString(@"IGDirectThreadViewController");
|
||||
if (threadVCClass) {
|
||||
SEL sentSel = NSSelectorFromString(@"setHasSentAMessageOrUpdate:");
|
||||
if (class_getInstanceMethod(threadVCClass, sentSel)) {
|
||||
MSHookMessageEx(threadVCClass, sentSel,
|
||||
(IMP)new_setHasSent, (IMP *)&orig_setHasSent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -497,6 +497,9 @@
|
||||
- (id)messageSenderFeatureController;
|
||||
@end
|
||||
|
||||
@interface IGDirectMessageSenderFeatureController : NSObject
|
||||
@end
|
||||
|
||||
@interface IGTabBarButton : UIButton
|
||||
- (void)addHandleLongPress; // new
|
||||
@end
|
||||
|
||||
@@ -141,6 +141,8 @@
|
||||
@"rows": @[
|
||||
[SCISetting switchCellWithTitle:@"Keep deleted messages" subtitle:@"Saves deleted messages in chat conversations" defaultsKey:@"keep_deleted_message"],
|
||||
[SCISetting switchCellWithTitle:@"Manually mark messages as seen" subtitle:@"Adds a button to DM threads, which will mark messages as seen" defaultsKey:@"remove_lastseen"],
|
||||
[SCISetting menuCellWithTitle:@"Read receipt mode" subtitle:@"How the seen button behaves" menu:[self menus][@"seen_mode"]],
|
||||
[SCISetting switchCellWithTitle:@"Auto: mark seen on interact" subtitle:@"Locally marks messages as seen when you send a message or react" defaultsKey:@"seen_auto_on_interact"],
|
||||
[SCISetting switchCellWithTitle:@"Disable typing status" subtitle:@"Prevents the typing indicator from being shown to others when you're typing in DMs" defaultsKey:@"disable_typing_status"],
|
||||
[SCISetting switchCellWithTitle:@"Send audio as file" subtitle:@"Adds an 'Audio File' option to the plus menu in DMs to send audio files as voice messages" defaultsKey:@"send_audio_as_file"],
|
||||
]
|
||||
@@ -324,6 +326,25 @@
|
||||
|
||||
+ (NSDictionary *)menus {
|
||||
return @{
|
||||
@"seen_mode": [UIMenu menuWithChildren:@[
|
||||
[UICommand commandWithTitle:@"Button"
|
||||
image:nil
|
||||
action:@selector(menuChanged:)
|
||||
propertyList:@{
|
||||
@"defaultsKey": @"seen_mode",
|
||||
@"value": @"button"
|
||||
}
|
||||
],
|
||||
[UICommand commandWithTitle:@"Toggle"
|
||||
image:nil
|
||||
action:@selector(menuChanged:)
|
||||
propertyList:@{
|
||||
@"defaultsKey": @"seen_mode",
|
||||
@"value": @"toggle"
|
||||
}
|
||||
]
|
||||
]],
|
||||
|
||||
@"dw_save_action": [UIMenu menuWithChildren:@[
|
||||
[UICommand commandWithTitle:@"Share sheet"
|
||||
image:nil
|
||||
|
||||
+2
-1
@@ -4,4 +4,5 @@
|
||||
extern NSString *SCIVersionString;
|
||||
|
||||
// Variables that work across features
|
||||
extern BOOL dmVisualMsgsViewedButtonEnabled; // Whether story dm unlimited views button is enabled
|
||||
extern BOOL dmVisualMsgsViewedButtonEnabled; // Whether story dm unlimited views button is enabled
|
||||
extern BOOL dmSeenToggleEnabled; // Whether read receipts toggle is active
|
||||
+3
-1
@@ -47,7 +47,9 @@ BOOL dmVisualMsgsViewedButtonEnabled = false;
|
||||
@"doom_scrolling_reel_count": @(1),
|
||||
@"no_seen_visual": @(YES),
|
||||
@"send_audio_as_file": @(YES),
|
||||
@"unlock_password_reels": @(YES)
|
||||
@"unlock_password_reels": @(YES),
|
||||
@"seen_mode": @"button",
|
||||
@"seen_auto_on_interact": @(YES)
|
||||
};
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:sciDefaults];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user