Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
marcoroth committed Mar 17, 2019
0 parents commit ce7c639
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# gitignore for Theos

*.deb
_/
theos/
theos
.theos
packages/
./packages/
obj/
./obj/
obj
.DS_Store
4 changes: 4 additions & 0 deletions FolderFinder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@interface FolderFinder : NSObject
+(NSString*) findSharedFolder:(NSString*) appName;
+(NSString*) findFolder:(NSString*) appName folder:(NSString*) dir;
@end
40 changes: 40 additions & 0 deletions FolderFinder.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Credit: u/Mordred666
// Source: https://reddit.com/r/jailbreakdevelopers/comments/5wb3tv/application_appgroup_path/

#import "FolderFinder.h"

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

+(NSString*) findFolder:(NSString*) appName folder:(NSString*) dir {
NSFileManager *manager = [NSFileManager defaultManager];

NSError *error = nil;
NSArray *folders = [manager contentsOfDirectoryAtPath:dir error:&error];

if (!error) {
for (NSString *folder in folders) {
NSString *folderPath = [dir stringByAppendingString:folder];
NSArray *items = [manager contentsOfDirectoryAtPath:folderPath error:&error];

for(NSString* itemPath in items) {
if([itemPath rangeOfString:@".com.apple.mobile_container_manager.metadata.plist"].location != NSNotFound) {
NSString* fullpath = [NSString stringWithFormat:@"%@/%@",folderPath, itemPath];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:fullpath];

NSString* mcmmetadata = dict[@"MCMMetadataIdentifier"];
if(mcmmetadata && [mcmmetadata.lowercaseString isEqualToString:appName.lowercaseString]) {
return folderPath;
}
}
}

}
}
return nil;
}
@end
15 changes: 15 additions & 0 deletions Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDisplayName</key>
<string>Viber</string>
<key>DDNotificationExternalProviderClasses</key>
<dict>
<key>ViberContactPhotoProvider</key>
<string>com.viber</string>
</dict>
<key>DDNotificationExternalProviderAPIVersion</key>
<integer>1</integer>
</dict>
</plist>
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
ARCHS = armv7 arm64

include $(THEOS)/makefiles/common.mk

BUNDLE_NAME = ShortLook-Viber
$(BUNDLE_NAME)_CFLAGS = -fobjc-arc
$(BUNDLE_NAME)_FILES = $(wildcard *.m)
$(BUNDLE_NAME)_FRAMEWORKS = UIKit
$(BUNDLE_NAME)_INSTALL_PATH = /Library/Dynastic/ShortLook/Plugins/ContactPhotoProviders
$(BUNDLE_NAME)_LDFLAGS = -lsqlite3

include $(THEOS_MAKE_PATH)/bundle.mk

BUNDLE_PATH = $($(BUNDLE_NAME)_INSTALL_PATH)/$(BUNDLE_NAME).bundle

internal-stage::
$(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)$(BUNDLE_PATH)$(ECHO_END)
$(ECHO_NOTHING)cp Info.plist $(THEOS_STAGING_DIR)$(BUNDLE_PATH)/Info.plist$(ECHO_END)

after-install::
install.exec "killall -9 SpringBoard"
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Viber Contact Photo Provider for ShortLook

Show Viber users' profile pictures in ShortLook when you receive a Viber notification!

(This is not ShortLook itself, but a plugin for it)
107 changes: 107 additions & 0 deletions ShortLook-API.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// WARNING:
// This file contains the required headers to compile a tweak that
// interacts with ShortLook's contact photo API. Do not modify the
// headers within, or it could lead to unexpected behaviour.
//
// ---
//
// ShortLook-API.h
//
// Created by AppleBetas on 2018-05-18.
// Copyright © 2018 Dynastic Development. All rights reserved.
//

#import <UIKit/UIKit.h>
@class NCNotificationRequest, UNNotificationContent;

/// A ShortLook-displayable notification representing a real user notification sent by an application to the system.
@interface DDUserNotification : NSObject
/// A custom notification title, separate from the application's title.
@property (nonatomic, retain, readonly) NSString *notificationTitle;

/// A dictionary of any extra information included by ShortLook.
@property (nonatomic, retain) NSDictionary *userInfo;

/// The system notification request that created this notification.
@property (nonatomic, readonly, retain) NCNotificationRequest *request;

/// The user notification's content, sent by the application.
- (UNNotificationContent *)content;

/// A dictionary of any extra information provided by the application sending the notification.
- (NSDictionary *)applicationUserInfo;

/// The bundle identifier of the application this notification represents.
- (NSString *)senderIdentifier;
@end

/// An object representing settings for the photo to be provided by a promise.
@interface DDNotificationContactPhotoSettings: NSObject
/// The background colour to show for the contact photo view if the provided image contains any transparency.
@property (nonatomic, retain) UIColor *backgroundColor;

/// Whether or not ShortLook should automatically cache the returned image from your provider and use it for all future notifications with the same photo identifier and application.
@property (nonatomic, assign) BOOL usesCaching;
@end

/// A promise representing a commitment to providing a contact icon for a notification.
@interface DDNotificationContactPhotoPromise: NSObject
/// An object holding the settings pertaining to the photo to be displayed.
@property (nonatomic, retain) DDNotificationContactPhotoSettings *settings;

/// Whether or not this promise has already been resolved or rejected.
@property (nonatomic, readonly, assign) BOOL isComplete;

// MARK: - Provider methods

/// Resolve this promise with the provided image, notifying ShortLook that you have received your image.
/// - NOTE: This method should only be ran from within `addResolver:`.
- (void)resolveWithImage:(UIImage *)image;

/// Reject this promise, notifying ShortLook that you failed to receive an image.
/// - NOTE: This method should only be ran from within `addResolver:`.
- (void)reject;
@end

/// An offer to fulfill a promise representing a commitment to providing a contact icon for a notification.
@interface DDNotificationContactPhotoPromiseOffer: NSObject
/// A unique identifier for the photo that will be provided by this promise.
@property (nonatomic, readonly, retain) NSString *photoIdentifier;

/// A string to replace the notification's title with, if it is required for your provider's context. Set to "" to remove the provided notification's title.
@property (nonatomic, retain) NSString *titleOverride;

/// A string to replace the notification's subtitle with, if it is required for your provider's context. Set to "" to remove the provided notification's subtitle.
@property (nonatomic, retain) NSString *subtitleOverride;

/// A string to replace the notification's body with, if it is required for your provider's context. Set to "" to remove the provided notification's body.
@property (nonatomic, retain) NSString *bodyOverride;

/// Initialize a promise with the provided photo identifier.
- (instancetype)initWithPhotoIdentifier:(NSString *)photoIdentifier;

/// Create a promise offer that will return the image at the provided URL, if needed.
+ (instancetype)offerDownloadingPromiseWithPhotoIdentifier:(NSString *)photoIdentifier fromURL:(NSURL *)url;

/// Create a promise offer that will return the image at the provided URL, if needed, with custom settings.
+ (instancetype)offerDownloadingPromiseWithPhotoIdentifier:(NSString *)photoIdentifier fromURL:(NSURL *)url withSettings:(DDNotificationContactPhotoSettings *)settings;

/// Create a promise offer that will instantly return the provided image.
+ (instancetype)offerInstantlyResolvingPromiseWithPhotoIdentifier:(NSString *)photoIdentifier image:(UIImage *)image;

/// Create a promise offer that will instantly return the provided image with custom settings.
+ (instancetype)offerInstantlyResolvingPromiseWithPhotoIdentifier:(NSString *)photoIdentifier image:(UIImage *)image withSettings:(DDNotificationContactPhotoSettings *)settings;

/// Add the block that will run if your image is needed (as it will not be in some cases, such as if your image is already cached by ShortLook).
/// If your provider does any long-running or asynchronous operations, they should be done using this method.
/// Any code run inside the provider block will be performed on a background thread.
- (void)fulfillWithBlock:(void (^)(DDNotificationContactPhotoPromise *promise))block;
@end

/// An object that can provide contact photos for ShortLook notifications.
@protocol DDNotificationContactPhotoProviding <NSObject>
@required
/// Returns an offer to fulfill a promise to provide a contact photo for a notification.
- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification;
@end
5 changes: 5 additions & 0 deletions ViberContactPhotoProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#import "ShortLook-API.h"

@interface ViberContactPhotoProvider : NSObject <DDNotificationContactPhotoProviding>
- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification;
@end
36 changes: 36 additions & 0 deletions ViberContactPhotoProvider.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#import <sqlite3.h>
#import "FolderFinder.h"
#import "ViberContactPhotoProvider.h"

@implementation ViberContactPhotoProvider
- (DDNotificationContactPhotoPromiseOffer *)contactPhotoPromiseOfferForNotification:(DDUserNotification *)notification {
NSString *containerPath = [FolderFinder findSharedFolder:@"group.viber.share.container"];
NSString *databasePath = [NSString stringWithFormat:@"%@/com.viber/database/Contacts.data", containerPath];
NSString *iconsPath = [NSString stringWithFormat:@"%@/com.viber/ViberIcons", containerPath];

NSString *senderMemberId = [notification.applicationUserInfo valueForKey:@"senderMemberId"];

const char *dbpath = [databasePath UTF8String];
sqlite3 *_viberdb;

if (sqlite3_open(dbpath, &_viberdb) == SQLITE_OK) {
const char *stmt = [[NSString stringWithFormat:@"SELECT ZICONID FROM ZMEMBER WHERE ZMEMBERID = '%@' AND ZICONSTATE = 'iconExist';", senderMemberId] UTF8String];
sqlite3_stmt *statement;

if (sqlite3_prepare_v2(_viberdb, stmt, -1, &statement, NULL) == SQLITE_OK) {
if (sqlite3_step(statement) == SQLITE_ROW) {
const unsigned char *result = sqlite3_column_text(statement, 0);
NSString *imageName = [NSString stringWithUTF8String:(char *)result];
NSString *imageURL = [NSString stringWithFormat:@"%@/%@.jpg", iconsPath, imageName];
UIImage *image = [UIImage imageWithContentsOfFile:imageURL];

return [NSClassFromString(@"DDNotificationContactPhotoPromiseOffer") offerInstantlyResolvingPromiseWithPhotoIdentifier:imageURL image:image];
}
sqlite3_finalize(statement);
}
sqlite3_close(_viberdb);
}

return nil;
}
@end
9 changes: 9 additions & 0 deletions control
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Package: ch.marcoroth.shortlook.plugin.contact-photo.viber
Name: Viber Profile Pictures for ShortLook
Depends: mobilesubstrate, co.dynastic.ios.tweak.shortlook
Version: 1.0.0
Architecture: iphoneos-arm
Description: Show Viber users' profile pictures in ShortLook when you receive a Viber notification!
Maintainer: Marco Roth
Author: Marco Roth
Section: Tweaks (ShortLook)

0 comments on commit ce7c639

Please sign in to comment.