Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
- Add generated profile picture with initials if no picture was found
- Add dedicated error message for secret conversations
- Improve .gitignore
- Other improvements
  • Loading branch information
RedenticDev committed Aug 13, 2021
1 parent 3858f82 commit fa0c423
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 155 deletions.
13 changes: 2 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
# gitignore for Theos

*.deb
_/
theos/
theos
.theos
.vscode/
.theos/
packages/
./packages/
obj/
./obj/
obj
.DS_Store
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "ShortLook-API"]
path = ShortLook-API
url = https://github.com/dynastic/ShortLook-API
6 changes: 0 additions & 6 deletions FolderFinder.h

This file was deleted.

1 change: 1 addition & 0 deletions ShortLook-API
Submodule ShortLook-API added at 856139
107 changes: 0 additions & 107 deletions ShortLook-API.h

This file was deleted.

6 changes: 6 additions & 0 deletions TGSFolderFinder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#import <Foundation/Foundation.h>

@interface TGSFolderFinder : NSObject
+ (NSString *)findSharedFolder:(NSString *)appName;
+ (NSString *)findFolder:(NSString *)appName folder:(NSString *)dir;
@end
8 changes: 3 additions & 5 deletions FolderFinder.m → TGSFolderFinder.m
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// Credit: u/Mordred666
// Source: https://reddit.com/r/jailbreakdevelopers/comments/5wb3tv/application_appgroup_path/

#import "FolderFinder.h"
#import "TGSFolderFinder.h"

@implementation FolderFinder
@implementation TGSFolderFinder

+ (NSString *)findSharedFolder:(NSString *)appName {
NSString *dir = @"/var/mobile/Containers/Shared/AppGroup/";
NSString *result = [self findFolder:appName folder:dir];
return result;
return [self findFolder:appName folder:@"/var/mobile/Containers/Shared/AppGroup/"];
}

+ (NSString *)findFolder:(NSString *)appName folder:(NSString *)dir {
Expand Down
5 changes: 5 additions & 0 deletions TGSInitialsPictureGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import <UIKit/UIKit.h>

@interface TGSInitialsPictureGenerator : NSObject
+ (UIImage *)generatePictureWithFirstLetter:(unichar)firstLetter secondLetter:(unichar)secondLetter;
@end
64 changes: 64 additions & 0 deletions TGSInitialsPictureGenerator.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#import "TGSInitialsPictureGenerator.h"

@implementation TGSInitialsPictureGenerator

// https://github.com/bachonk/UIImageView-Letters/blob/master/UIImageView%2BLetters/UIImageView%2BLetters.m#L137-L187
+ (UIImage *)generatePictureWithFirstLetter:(unichar)firstLetter secondLetter:(unichar)secondLetter {
// Initial variables
static NSInteger imageDimension = 300;
CGFloat fontSize = imageDimension * .5f;

// Assemble letters
NSString *content = [NSString stringWithFormat:@"%C%C", firstLetter, secondLetter];
UIFont *textFont = [UIFont systemFontOfSize:fontSize weight:UIFontWeightBold];
if (@available(iOS 13.0, *)) { // round the font to look like Telegram
textFont = [UIFont fontWithDescriptor:[textFont.fontDescriptor fontDescriptorWithDesign:UIFontDescriptorSystemDesignRounded] size:fontSize];
}
NSDictionary *attributes = @{
NSFontAttributeName : textFont,
NSForegroundColorAttributeName : [UIColor whiteColor]
};

// Generate background
NSArray<UIColor *> *colors = @[ // official colors from Telegram (https://github.com/TelegramMessenger/Telegram-iOS/blob/master/submodules/LocationResources/Sources/VenueIconResources.swift#L116)
[UIColor colorWithRed:.9 green:.42 blue:.84 alpha:1.], // Pink
[UIColor colorWithRed:.97 green:.58 blue:.25 alpha:1.], // Orange
[UIColor colorWithRed:.6 green:.53 blue:1. alpha:1.], // Magenta
[UIColor colorWithRed:.27 green:.7 blue:.96 alpha:1.], // Light Blue
[UIColor colorWithRed:.43 green:.76 blue:.22 alpha:1.], // Green
[UIColor colorWithRed:1. green:.36 blue:.35 alpha:1.], // Red
[UIColor colorWithRed:.97 green:.48 blue:.68 alpha:1.], // Another pink
[UIColor colorWithRed:.43 green:.51 blue:.7 alpha:1.], // Dark blue
[UIColor colorWithRed:.96 green:.73 blue:.13 alpha:1.] // Yellow
];
CGSize imageSize = CGSizeMake(imageDimension, imageDimension);
CGRect imageRect = {CGPointZero, imageSize};
// 1. Image basis
UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// 2. Circular shape
CGPathRef path = CGPathCreateWithEllipseInRect(imageRect, NULL);
CGContextAddPath(context, path);
CGContextClip(context);
CGPathRelease(path);
// 3. Fill color
CGContextSetFillColorWithColor(context, colors[arc4random_uniform(colors.count)].CGColor);
CGContextFillRect(context, imageRect);

// Add letters in it
CGSize textSize = [content sizeWithAttributes:attributes];
[content drawInRect:CGRectMake(imageSize.width / 2 - textSize.width / 2,
imageSize.height / 2 - textSize.height / 2,
textSize.width,
textSize.height)
withAttributes:attributes];

// Extract it
UIImage *generatedPicture = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// Return it
return generatedPicture;
}

@end
4 changes: 3 additions & 1 deletion TelegramContactPhotoProvider.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#import "ShortLook-API.h"
#import "ShortLook-API/ShortLook-API.h"
#import "TGSFolderFinder.h"
#import "TGSInitialsPictureGenerator.h"

@interface TelegramContactPhotoProvider : NSObject <DDNotificationContactPhotoProviding>
- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification;
Expand Down
68 changes: 44 additions & 24 deletions TelegramContactPhotoProvider.m
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#import "FolderFinder.h"
#import "TelegramContactPhotoProvider.h"

@interface NCNotificationRequest
-(NSString *)threadIdentifier;
- (NSString *)threadIdentifier;
@end

@implementation TelegramContactPhotoProvider

- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification {
NCNotificationRequest *request = [notification request];
NSString *threadIdentifier = [request threadIdentifier];
NSString *sharedFolder = [FolderFinder findSharedFolder:@"group.ph.telegra.Telegraph"];
NSLog(@"[TLGM] Starting Telegram Contact Photo search");
NSString *threadIdentifier = [[notification request] threadIdentifier];
NSString *sharedFolder = [TGSFolderFinder findSharedFolder:@"group.ph.telegra.Telegraph"];
NSLog(@"Starting Telegram Contact Photo search");

if ([[threadIdentifier lowercaseString] isEqualToString:@"locked"]) { // Telegram is locked!
NSLog(@"[TLGM] Error: Telegram app is locked, no info provided");
NSLog(@"Error: Telegram app is locked, no info provided");
} else if ([[threadIdentifier lowercaseString] isEqualToString:@"secret"]) { // Secret conversation
NSLog(@"Error: Secret conversation, cannot read info");
} else if ([threadIdentifier hasPrefix:@"-"]) { // group/bot -> unsupported
/*
Current state for group/bot profile pictures:
Expand All @@ -25,32 +25,52 @@ API is not available without the private key of the channel (why??) so I can't f
plus I miss at least one element for each technique I can think of.
- Database: I found nothing interesting in all local databases existing in Telegram folders.
*/
NSLog(@"[TLGM] Error: negative threadId (threadId = %@), group or bot -> unsupported", threadIdentifier);
NSLog(@"Error: negative threadId (threadId = %@), group or bot -> unsupported", threadIdentifier);
} else { // casual convo
NSString *firstName;
NSString *lastName;

NSString *convoFolder = [NSString stringWithFormat:@"%@/telegram-data/accounts-metadata/spotlight/p:%@", sharedFolder, threadIdentifier];
NSLog(@"[TLGM] Good path found! Path: %@", convoFolder);
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/data.json", convoFolder]]) {
NSLog(@"[TLGM] Looking for High-res profile picture...");
NSData *jsonData = [NSData dataWithContentsOfFile:[NSString stringWithFormat:@"%@/data.json", convoFolder]];
NSLog(@"Good path found! Path: %@", convoFolder);

// HD Profile Picture
NSString *dataJsonPath = [convoFolder stringByAppendingString:@"/data.json"];
if ([[NSFileManager defaultManager] fileExistsAtPath:dataJsonPath]) {
NSLog(@"Looking for High-res profile picture...");
NSError *error = nil;
NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataJsonPath] options:kNilOptions error:&error];
if (!error) {
NSString *imagePath = [NSString stringWithFormat:@"%@/%@", sharedFolder, parsedData[@"avatarSourcePath"]];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
NSLog(@"[TLGM] High-res (%.fx%.f) profile picture found! Path: %@", image.size.width * image.scale, image.size.height * image.scale, imagePath);
if (parsedData[@"avatarSourcePath"]) {
NSString *imagePath = [NSString stringWithFormat:@"%@/%@", sharedFolder, parsedData[@"avatarSourcePath"]];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
NSLog(@"High-res (%.fx%.f) profile picture found! Path: %@", image.size.width * image.scale, image.size.height * image.scale, imagePath);

return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:imagePath image:image];
return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:threadIdentifier image:image];
} else {
firstName = parsedData[@"firstName"];
lastName = parsedData[@"lastName"];
}
}
NSLog(@"[TLGM] An error occurred while fetching High-res profile picture (error: %@)", error);
NSLog(@"An error occurred while fetching High-res profile picture (error: %@)", error);
}

// SD Profile Picture
NSString *avatarPngPath = [convoFolder stringByAppendingString:@"/avatar.png"];
if ([[NSFileManager defaultManager] fileExistsAtPath:avatarPngPath]) {
UIImage *image = [UIImage imageWithContentsOfFile:avatarPngPath];
NSLog(@"Low-res (%.fx%.f) avatar only found? (This is a rare bad case). Path: %@", image.size.width * image.scale, image.size.height * image.scale, avatarPngPath);

return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:threadIdentifier image:image];
}
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/avatar.png", convoFolder]]) {
NSString *imagePath = [NSString stringWithFormat:@"%@/avatar.png", convoFolder];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
NSLog(@"[TLGM] Low-res (%.fx%.f) avatar only found? (This is a rare bad case). Path: %@", image.size.width * image.scale, image.size.height * image.scale, imagePath);

return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:imagePath image:image];
// Custom initials Profile Picture
if (firstName && firstName.length > 0) { // last name can be missing
UIImage *generatedImage = [TGSInitialsPictureGenerator generatePictureWithFirstLetter:[[firstName uppercaseString] characterAtIndex:0]
secondLetter:lastName && lastName.length > 0 ? [[lastName uppercaseString] characterAtIndex:0] : '\0'];
return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:threadIdentifier image:generatedImage];
}
NSLog(@"[TLGM] No avatar for this conversation");

NSLog(@"No avatar available for this conversation");
}

return nil;
Expand Down
2 changes: 1 addition & 1 deletion control
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: com.redenticdev.shortlook.plugin.contact-photo.telegram
Name: Telegram Contact Photos for ShortLook
Depends: mobilesubstrate, co.dynastic.ios.tweak.shortlook
Version: 1.0.0
Version: 1.1.0
Architecture: iphoneos-arm
Description: Show Telegram Contact Photos in ShortLook when you receive a Telegram notification!
Maintainer: RedenticDev
Expand Down

0 comments on commit fa0c423

Please sign in to comment.