summaryrefslogtreecommitdiffstats
path: root/QuickActions/QuickActionsPrefs
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-12-29 10:41:53 -0500
committerCameron Katri <me@cameronkatri.com>2021-12-29 10:41:53 -0500
commit451ec46218d0a5ac206441a48e5aa5b926209eb0 (patch)
treef806fe4528e56ed2541b2fa7b7aefcb9cbbe8937 /QuickActions/QuickActionsPrefs
parent15240ea1e0dc4fc86a3f36cffe5b9c14ff0b2c93 (diff)
downloadtweaks-451ec46218d0a5ac206441a48e5aa5b926209eb0.tar.gz
tweaks-451ec46218d0a5ac206441a48e5aa5b926209eb0.tar.zst
tweaks-451ec46218d0a5ac206441a48e5aa5b926209eb0.zip
I hate this project
Diffstat (limited to 'QuickActions/QuickActionsPrefs')
-rw-r--r--QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h28
-rw-r--r--QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m125
-rw-r--r--QuickActions/QuickActionsPrefs/QASAppSelectorController.h22
-rw-r--r--QuickActions/QuickActionsPrefs/QASAppSelectorController.m341
-rw-r--r--QuickActions/QuickActionsPrefs/QASRootListController.m3
5 files changed, 314 insertions, 205 deletions
diff --git a/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h b/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h
new file mode 100644
index 0000000..65866ab
--- /dev/null
+++ b/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h
@@ -0,0 +1,28 @@
+#import <Foundation/Foundation.h>
+
+@interface LSApplicationRecord : NSObject
+@property (nonatomic,readonly) NSArray* appTags;
+@property (getter=isLaunchProhibited,readonly) BOOL launchProhibited;
+@end
+
+@interface LSApplicationProxy : NSObject
+@property (nonatomic,readonly) NSArray* appTags;
+@property (getter=isLaunchProhibited,nonatomic,readonly) BOOL launchProhibited;
+@property (nonatomic,readonly) NSString* localizedName;
++(LSApplicationProxy *)applicationProxyForIdentifier:(NSString *)id;
+-(NSString *)localizedNameForContext:(id)arg;
+-(NSURL *)bundleURL;
+-(NSString *)bundleIdentifier;
+-(LSApplicationRecord *)correspondingApplicationRecord;
+@end
+
+@interface LSApplicationProxy (AltList)
+-(BOOL)atl_isHidden;
+-(NSString *)atl_fastDisplayName;
+-(NSString *)atl_nameToDisplay;
+@end
+
+@interface LSApplicationWorkspace : NSObject
++(LSApplicationWorkspace *)defaultWorkspace;
+-(NSArray<LSApplicationWorkspace *> *)allApplications;
+@end \ No newline at end of file
diff --git a/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m b/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m
new file mode 100644
index 0000000..ab6c292
--- /dev/null
+++ b/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m
@@ -0,0 +1,125 @@
+#import <Foundation/Foundation.h>
+#import "LSApplicationProxy+AltList.h"
+
+@implementation LSApplicationProxy (AltList)
+// the tag " hidden " is also valid, so we need to check if any strings contain "hidden" instead
+BOOL tagArrayContainsTag(NSArray* tagArr, NSString* tag)
+{
+ if(!tagArr || !tag) return NO;
+
+ __block BOOL found = NO;
+
+ [tagArr enumerateObjectsUsingBlock:^(NSString* tagToCheck, NSUInteger idx, BOOL* stop)
+ {
+ if(![tagToCheck isKindOfClass:[NSString class]])
+ {
+ return;
+ }
+
+ if([tagToCheck rangeOfString:tag options:0].location != NSNotFound)
+ {
+ found = YES;
+ *stop = YES;
+ }
+ }];
+
+ return found;
+}
+
+// always returns NO on iOS 7
+- (BOOL)atl_isHidden
+{
+ NSArray* appTags;
+ NSArray* recordAppTags;
+ NSArray* sbAppTags;
+
+ BOOL launchProhibited = NO;
+
+ if([self respondsToSelector:@selector(correspondingApplicationRecord)])
+ {
+ // On iOS 14, self.appTags is always empty but the application record still has the correct ones
+ LSApplicationRecord* record = [self correspondingApplicationRecord];
+ recordAppTags = record.appTags;
+ launchProhibited = record.launchProhibited;
+ }
+ if([self respondsToSelector:@selector(appTags)])
+ {
+ appTags = self.appTags;
+ }
+ if(!launchProhibited && [self respondsToSelector:@selector(isLaunchProhibited)])
+ {
+ launchProhibited = self.launchProhibited;
+ }
+
+ NSURL* bundleURL = self.bundleURL;
+ if(bundleURL && [bundleURL checkResourceIsReachableAndReturnError:nil])
+ {
+ NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
+ sbAppTags = [bundle objectForInfoDictionaryKey:@"SBAppTags"];
+ }
+
+ BOOL isWebApplication = ([self.bundleIdentifier rangeOfString:@"com.apple.webapp" options:NSCaseInsensitiveSearch].location != NSNotFound);
+ return tagArrayContainsTag(appTags, @"hidden") || tagArrayContainsTag(recordAppTags, @"hidden") || tagArrayContainsTag(sbAppTags, @"hidden") || isWebApplication || launchProhibited;
+}
+
+// Getting the display name is slow (up to 2ms) because it uses an IPC call
+// this stacks up if you do it for every single application
+// This method provides a faster way (around 0.5ms) to get the display name
+// This reduces the overall time needed to sort the applications from ~230 to ~120ms on my test device
+- (NSString*)atl_fastDisplayName
+{
+ NSString* cachedDisplayName = [self valueForKey:@"_localizedName"];
+ if(cachedDisplayName && ![cachedDisplayName isEqualToString:@""])
+ {
+ return cachedDisplayName;
+ }
+
+ NSString* localizedName;
+
+ NSURL* bundleURL = self.bundleURL;
+ if(!bundleURL || ![bundleURL checkResourceIsReachableAndReturnError:nil])
+ {
+ localizedName = self.localizedName;
+ }
+ else
+ {
+ NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
+
+ localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
+ if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
+ if(!localizedName || [localizedName isEqualToString:@""])
+ {
+ localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
+ if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
+ if(!localizedName || [localizedName isEqualToString:@""])
+ {
+ localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleExecutable"];
+ if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
+ if(!localizedName || [localizedName isEqualToString:@""])
+ {
+ //last possible fallback: use slow IPC call
+ localizedName = self.localizedName;
+ }
+ }
+ }
+ }
+
+ [self setValue:localizedName forKey:@"_localizedName"];
+ return localizedName;
+}
+
+- (NSString*)atl_nameToDisplay
+{
+ NSString* localizedName = [self atl_fastDisplayName];
+
+ if([self.bundleIdentifier rangeOfString:@"carplay" options:NSCaseInsensitiveSearch].location != NSNotFound)
+ {
+ if([localizedName rangeOfString:@"carplay" options:NSCaseInsensitiveSearch range:NSMakeRange(0, localizedName.length) locale:[NSLocale currentLocale]].location == NSNotFound)
+ {
+ return [localizedName stringByAppendingString:@" (CarPlay)"];
+ }
+ }
+
+ return localizedName;
+}
+@end \ No newline at end of file
diff --git a/QuickActions/QuickActionsPrefs/QASAppSelectorController.h b/QuickActions/QuickActionsPrefs/QASAppSelectorController.h
index 13ffe60..f439fcb 100644
--- a/QuickActions/QuickActionsPrefs/QASAppSelectorController.h
+++ b/QuickActions/QuickActionsPrefs/QASAppSelectorController.h
@@ -1,18 +1,28 @@
#import <UIKit/UIKit.h>
#import "PSDetailController.h"
+#import "LSApplicationProxy+AltList.h"
@interface UIImage (Private)
+(instancetype)_applicationIconImageForBundleIdentifier:(NSString*)bundleIdentifier format:(int)format scale:(CGFloat)scale;
-(UIImage *)_applicationIconImageForFormat:(int)format precomposed:(BOOL)precomposed scale:(CGFloat)scale;
@end
-@interface QASAppSelectorController : PSDetailController<UITableViewDataSource,
-UITableViewDelegate>
+typedef enum {
+ ENABLED = 0,
+ SYSTEM,
+ APPS
+} ItemType;
+
+@interface QASAppSelectorController : PSDetailController<UITableViewDataSource, UITableViewDelegate,
+UISearchResultsUpdating, UISearchBarDelegate> {
+ UISearchController *_searchController;
+ NSString *_searchKey;
+}
@property (nonatomic) UITableView *tableView;
-@property (nonatomic) NSMutableArray *enabled;
-@property (nonatomic) NSMutableArray *disabled;
-@property (nonatomic) NSArray *systemAvailable;
-@property (nonatomic) NSMutableArray *systemDisabled;
+@property (nonatomic) NSMutableArray<NSString *> *enabled;
+@property (nonatomic) NSMutableArray<LSApplicationProxy *>*disabled;
+@property (nonatomic) NSArray<NSString *> *systemDisabled;
@property (nonatomic) NSString *key;
@property (nonatomic) NSString *defaults;
+-(NSArray<LSApplicationProxy *> *)filteredDisabled;
@end \ No newline at end of file
diff --git a/QuickActions/QuickActionsPrefs/QASAppSelectorController.m b/QuickActions/QuickActionsPrefs/QASAppSelectorController.m
index cfb6c7a..cadca5c 100644
--- a/QuickActions/QuickActionsPrefs/QASAppSelectorController.m
+++ b/QuickActions/QuickActionsPrefs/QASAppSelectorController.m
@@ -1,45 +1,9 @@
#import <Foundation/Foundation.h>
-#include <objc/NSObject.h>
#import <UIKit/UIKit.h>
#import <Preferences/PSSpecifier.h>
-#import "QASAppSelectorController.h"
-@interface LSApplicationRecord
-@property (readonly) NSArray * appTags;
-@property (getter=isLaunchProhibited,readonly) BOOL launchProhibited;
-@end
-
-@interface LSApplicationProxy : NSObject
-@property (getter=isLaunchProhibited, nonatomic, readonly) BOOL launchProhibited;
-@property (nonatomic, readonly) NSArray *appTags;
-@property (nonatomic,readonly) LSApplicationRecord * correspondingApplicationRecord;
-+ (id)applicationProxyForIdentifier:(id)arg1;
-- (id)localizedNameForContext:(id)arg1;
-- (NSString *)bundleIdentifier;
-- (NSString *)applicationType;
-- (NSURL *)bundleURL;
-@end
-
-@interface LSApplicationProxy (StolenFromAltList)
-- (BOOL)atl_isHidden;
-@end
-
-@interface LSApplicationWorkspace : NSObject
-+(id)defaultWorkspace;
--(NSArray<LSApplicationProxy *> *)allApplications;
-@end
-
-@interface NSMutableArray (Custom)
--(void)sortApps;
-@end
-
-// @interface ListItem : NSObject
-// @property (nonatomic, retain) NSString *name;
-// @property (nonatomic, retain) NSString *bundleID;
-// @property (nonatomic, retain) NSString *type;
-// @property (nonatomic, retain) UIImage *icon;
-// -(ListItem *)initWithName:(NSString *)name bundleID:(NSString *)bundleID type:(NSString *)type icon:(UIImage *)icon;
-// @end
+#import "QASAppSelectorController.h"
+#import "LSApplicationProxy+AltList.h"
@implementation QASAppSelectorController
-(void)viewDidLoad
@@ -54,6 +18,8 @@
self.disabled = [NSMutableArray new];
self.enabled = [NSMutableArray new];
+ self.systemDisabled = @[ @"com.apple.camera", @"com.apple.donotdisturb", @"com.apple.flashlight" ];
+
NSArray *defaults = [[[NSUserDefaults alloc] initWithSuiteName:self.defaults] arrayForKey:self.key];
if (defaults == nil) {
@@ -65,56 +31,92 @@
[self.enabled addObjectsFromArray:defaults];
for (LSApplicationProxy *proxy in [[LSApplicationWorkspace defaultWorkspace] allApplications]) {
- if (![proxy atl_isHidden] && [self.enabled indexOfObject:proxy.bundleIdentifier] == NSNotFound)
- [self.disabled addObject:proxy.bundleIdentifier];
+ if (![proxy atl_isHidden] && ![[proxy bundleIdentifier] isEqualToString:@"com.apple.camera"]) {
+ [self.disabled addObject:proxy];
+ }
}
- if ([self.enabled indexOfObject:@"com.apple.flashlight"] == NSNotFound)
- [self.disabled addObject:@"com.apple.flashlight"];
+ [self.disabled sortUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"atl_fastDisplayName"
+ ascending:YES
+ selector:@selector(localizedCaseInsensitiveCompare:)]]];
- if ([self.enabled indexOfObject:@"com.apple.donotdisturb"] == NSNotFound)
- [self.disabled addObject:@"com.apple.donotdisturb"];
+ _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
+ _searchController.searchResultsUpdater = self;
+ _searchController.obscuresBackgroundDuringPresentation = NO;
+ _searchController.searchBar.delegate = self;
- [self.disabled sortApps];
+ self.navigationItem.searchController = _searchController;
+ self.navigationItem.hidesSearchBarWhenScrolling = NO;
+
+ self.definesPresentationContext = YES;
+}
+
+-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
+ _searchKey = searchController.searchBar.text;
+ [self.tableView reloadData];
}
+-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { return YES; }
+
-(void)viewWillAppear:(BOOL)animated
{
- self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
- self.tableView.delegate = self;
- self.tableView.dataSource = self;
- self.tableView.editing = TRUE;
+ [super viewWillAppear:animated];
- [self.view addSubview:self.tableView];
+ if (self.tableView == nil) {
+ self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
+ self.tableView.delegate = self;
+ self.tableView.dataSource = self;
+ self.tableView.editing = TRUE;
+
+ [self.view addSubview:self.tableView];
+ }
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
- if (section == 0)
- return @"Enabled";
- else if (section == 1)
- return @"Disabled";
- else
- return @"";
+ switch ((ItemType)section) {
+ case ENABLED:
+ return @"Enabled";
+ case SYSTEM:
+ return @"System";
+ case APPS:
+ return @"Apps";
+ }
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
- return 2;
+ return 3;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
- if (section == 0)
- return self.enabled.count;
- else
- return self.disabled.count;
+ switch ((ItemType)section) {
+ case ENABLED:
+ return self.enabled.count;
+ case SYSTEM:
+ return self.systemDisabled.count;
+ case APPS:
+ return self.filteredDisabled.count;
+ }
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
- NSString *bundleid = indexPath.section == 0 ? self.enabled[indexPath.row] : self.disabled[indexPath.row];
-
+ NSObject *item;
+
+ switch ((ItemType)indexPath.section) {
+ case ENABLED:
+ item = self.enabled[indexPath.row];
+ break;
+ case SYSTEM:
+ item = self.systemDisabled[indexPath.row];
+ break;
+ case APPS:
+ item = self.filteredDisabled[indexPath.row];
+ break;
+ }
+
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"com.cameronkatri.quickactions"];
if (cell == nil) {
@@ -122,32 +124,45 @@
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
-
- if ([bundleid isEqualToString:@"com.apple.flashlight"]) {
- cell.textLabel.text = @"Flashlight";
- cell.detailTextLabel.text = nil;
- NSBundle *flashlightModule = [NSBundle bundleWithPath:@"/System/Library/ControlCenter/Bundles/FlashlightModule.bundle"];
- cell.imageView.image = [[UIImage imageNamed:@"SettingsIcon"
- inBundle:flashlightModule
- compatibleWithTraitCollection:nil] _applicationIconImageForFormat:0 precomposed:YES scale:[UIScreen mainScreen].scale];
- } else if ([bundleid isEqualToString:@"com.apple.donotdisturb"]) {
+
+ if ([item isKindOfClass:[NSString class]] && [(NSString*)item isEqualToString:@"com.apple.donotdisturb"]) {
cell.textLabel.text = @"Do Not Disturb";
cell.detailTextLabel.text = nil;
+
NSBundle *doNotDisturbBundle = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/DoNotDisturb.framework/PlugIns/DoNotDisturbIntents.appex"];
cell.imageView.image = [[UIImage imageNamed:@"DoNotDisturb"
- inBundle:doNotDisturbBundle
- compatibleWithTraitCollection:nil] _applicationIconImageForFormat:0 precomposed:YES scale:[UIScreen mainScreen].scale];
+ inBundle:doNotDisturbBundle
+ compatibleWithTraitCollection:nil] _applicationIconImageForFormat:0
+ precomposed:YES
+ scale:[UIScreen mainScreen].scale];
+ } else if ([item isKindOfClass:[NSString class]] && [(NSString*)item isEqualToString:@"com.apple.flashlight"]) {
+ cell.textLabel.text = @"Flashlight";
+ cell.detailTextLabel.text = nil;
+ NSBundle *flashlightModule = [NSBundle bundleWithPath:@"/System/Library/ControlCenter/Bundles/FlashlightModule.bundle"];
+ cell.imageView.image = [[UIImage imageNamed:@"SettingsIcon"
+ inBundle:flashlightModule
+ compatibleWithTraitCollection:nil] _applicationIconImageForFormat:0
+ precomposed:YES
+ scale:[UIScreen mainScreen].scale];
} else {
- cell.textLabel.text = [[LSApplicationProxy applicationProxyForIdentifier:bundleid] localizedNameForContext:nil];
- if (cell.textLabel.text == nil) {
- cell.textLabel.text = bundleid;
- cell.detailTextLabel.text = nil;
+ LSApplicationProxy *proxy;
+ if ([item isKindOfClass:[NSString class]]) {
+ proxy = [LSApplicationProxy applicationProxyForIdentifier:(NSString*)item];
} else {
- cell.detailTextLabel.text = bundleid;
+ proxy = (LSApplicationProxy*)item;
}
+ cell.textLabel.text = [proxy atl_nameToDisplay];
+ if (cell.textLabel.text == nil) {
+ cell.textLabel.text = [proxy bundleIdentifier];
+ cell.detailTextLabel.text = nil;
+ } else
+ cell.detailTextLabel.text = [proxy bundleIdentifier];
cell.detailTextLabel.textColor = [UIColor secondaryLabelColor];
- cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:bundleid format:0 scale:[UIScreen mainScreen].scale];
+ cell.imageView.image = [UIImage _applicationIconImageForBundleIdentifier:[proxy bundleIdentifier]
+ format:0
+ scale:[UIScreen mainScreen].scale];
}
+
cell.showsReorderControl = indexPath.section == 0 ? YES : FALSE;
@@ -156,29 +171,32 @@
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
- return indexPath.section == 0 ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
+ return indexPath.section == ENABLED ? UITableViewCellEditingStyleDelete : UITableViewCellEditingStyleInsert;
}
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
- return indexPath.section == 0 ? YES : FALSE;
+ return indexPath.section == ENABLED ? YES : FALSE;
}
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(nonnull NSIndexPath *)sourceIndexPath toIndexPath:(nonnull NSIndexPath *)destinationIndexPath
{
- if (sourceIndexPath.section == 0) {
- if (destinationIndexPath.section == 0)
- [self.enabled exchangeObjectAtIndex:sourceIndexPath.row withObjectAtIndex:destinationIndexPath.row];
- else {
- [self.disabled addObject:self.enabled[sourceIndexPath.row]];
- [self.enabled removeObjectAtIndex:sourceIndexPath.row];
- }
- } else {
- [self.enabled insertObject:self.disabled[sourceIndexPath.row] atIndex:destinationIndexPath.row];
- [self.disabled removeObjectAtIndex:sourceIndexPath.row];
+ switch ((ItemType)sourceIndexPath.section) {
+ case ENABLED:
+ if (destinationIndexPath.section == ENABLED) {
+ NSString *item = self.enabled[sourceIndexPath.row];
+ [self.enabled removeObjectAtIndex:sourceIndexPath.row];
+ [self.enabled insertObject:item atIndex:destinationIndexPath.row];
+ }
+ break;
+ case SYSTEM:
+ [self.enabled insertObject:self.systemDisabled[sourceIndexPath.row] atIndex:destinationIndexPath.row];
+ break;
+ case APPS:
+ [self.enabled insertObject:self.filteredDisabled[sourceIndexPath.row].bundleIdentifier atIndex:destinationIndexPath.row];
+ break;
}
- [self.disabled sortApps];
[tableView reloadData];
[[[NSUserDefaults alloc] initWithSuiteName:self.defaults] setObject:self.enabled forKey:self.key];
@@ -186,125 +204,52 @@
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
- if (sourceIndexPath.section == 0 && proposedDestinationIndexPath.section == 1) {
- NSUInteger insPoint = [self.disabled
- indexOfObject:self.enabled[sourceIndexPath.row]
- inSortedRange:NSMakeRange(0, [self.disabled count])
- options:NSBinarySearchingInsertionIndex
- usingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- if ([obj1 isEqualToString:@"com.apple.flashlight"])
- return NSOrderedAscending;
- else if ([obj2 isEqualToString:@"com.apple.flashlight"])
- return NSOrderedDescending;
- NSString *obj1Name = [[LSApplicationProxy applicationProxyForIdentifier:obj1] localizedNameForContext:nil];
- NSString *obj2Name = [[LSApplicationProxy applicationProxyForIdentifier:obj2] localizedNameForContext:nil];
- return ([obj1Name localizedCaseInsensitiveCompare:obj2Name]);
- }];
- return [NSIndexPath indexPathForRow:insPoint inSection:1];
- }
+ if (sourceIndexPath.section == ENABLED && proposedDestinationIndexPath.section != ENABLED)
+ return [NSIndexPath indexPathForRow:(self.enabled.count - 1) inSection:0];
+
return proposedDestinationIndexPath;
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
- NSString *item = indexPath.section == 0 ? self.enabled[indexPath.row] : self.disabled[indexPath.row];
- NSIndexPath *insertPath;
+ NSString *item;
+ switch ((ItemType)indexPath.section) {
+ case ENABLED:
+ item = self.enabled[indexPath.row];
+ break;
+ case SYSTEM:
+ item = self.systemDisabled[indexPath.row];
+ break;
+ case APPS:
+ item = self.filteredDisabled[indexPath.row].bundleIdentifier;
+ break;
+ }
- if (editingStyle == UITableViewCellEditingStyleDelete) {
- [self.enabled removeObject:item];
- [self.disabled addObject:item];
- [self.disabled sortApps];
+ [tableView beginUpdates];
- insertPath = [NSIndexPath indexPathForRow:[self.disabled indexOfObject:item] inSection:1];
+ if (editingStyle == UITableViewCellEditingStyleDelete) {
+ [self.enabled removeObjectAtIndex:indexPath.row];
+ [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
- [self.disabled removeObject:item];
- [self.enabled addObject:item];
-
- insertPath = [NSIndexPath indexPathForRow:([self.enabled count] - 1) inSection:0];
+ [self.enabled insertObject:item atIndex:self.enabled.count];
+ [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:([self.enabled count] - 1) inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
}
-
- [tableView beginUpdates];
- [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:insertPath] withRowAnimation:UITableViewRowAnimationFade];
- [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
+
[tableView endUpdates];
[[[NSUserDefaults alloc] initWithSuiteName:self.defaults] setObject:self.enabled forKey:self.key];
}
-@end
-
-@implementation NSMutableArray (Custom)
--(void)sortApps {
- [self sortUsingComparator:^NSComparisonResult(NSString *obj1, NSString *obj2) {
- if ([obj1 isEqualToString:@"com.apple.flashlight"])
- return NSOrderedAscending;
- else if ([obj2 isEqualToString:@"com.apple.flashlight"])
- return NSOrderedDescending;
-
- NSString *obj1Name = [[LSApplicationProxy applicationProxyForIdentifier:obj1] localizedNameForContext:nil];
- NSString *obj2Name = [[LSApplicationProxy applicationProxyForIdentifier:obj2] localizedNameForContext:nil];
-
- return ([obj1Name localizedCaseInsensitiveCompare:obj2Name]);
- }];
-}
-@end
-
-@implementation LSApplicationProxy (StolenFromAltList)
-BOOL tagArrayContainsTag(NSArray* tagArr, NSString* tag)
-{
- if(!tagArr || !tag) return NO;
-
- __block BOOL found = NO;
-
- [tagArr enumerateObjectsUsingBlock:^(NSString* tagToCheck, NSUInteger idx, BOOL* stop)
- {
- if(![tagToCheck isKindOfClass:[NSString class]])
- {
- return;
- }
-
- if([tagToCheck rangeOfString:tag options:0].location != NSNotFound)
- {
- found = YES;
- *stop = YES;
+-(NSArray<LSApplicationProxy *> *)filteredDisabled {
+ if ([_searchKey length] == 0) {
+ return self.disabled;
+ } else {
+ NSMutableArray<LSApplicationProxy *> *filteredArray = [NSMutableArray new];
+ for (LSApplicationProxy *proxy in self.disabled) {
+ if ([proxy.bundleIdentifier rangeOfString:_searchKey options:NSCaseInsensitiveSearch].location != NSNotFound || [proxy.atl_fastDisplayName rangeOfString:_searchKey options:NSCaseInsensitiveSearch range:NSMakeRange(0, [proxy.atl_fastDisplayName length]) locale:[NSLocale currentLocale]].location != NSNotFound)
+ [filteredArray addObject:proxy];
}
- }];
-
- return found;
-}
-
-- (BOOL)atl_isHidden
-{
- NSArray* appTags;
- NSArray* recordAppTags;
- NSArray* sbAppTags;
-
- BOOL launchProhibited = NO;
-
- if([self respondsToSelector:@selector(correspondingApplicationRecord)])
- {
- // On iOS 14, self.appTags is always empty but the application record still has the correct ones
- LSApplicationRecord* record = [self correspondingApplicationRecord];
- recordAppTags = record.appTags;
- launchProhibited = record.launchProhibited;
- }
- if([self respondsToSelector:@selector(appTags)])
- {
- appTags = self.appTags;
- }
- if(!launchProhibited && [self respondsToSelector:@selector(isLaunchProhibited)])
- {
- launchProhibited = self.launchProhibited;
+ return filteredArray;
}
-
- NSURL* bundleURL = self.bundleURL;
- if(bundleURL && [bundleURL checkResourceIsReachableAndReturnError:nil])
- {
- NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
- sbAppTags = [bundle objectForInfoDictionaryKey:@"SBAppTags"];
- }
-
- BOOL isWebApplication = ([self.bundleIdentifier rangeOfString:@"com.apple.webapp" options:NSCaseInsensitiveSearch].location != NSNotFound);
- return tagArrayContainsTag(appTags, @"hidden") || tagArrayContainsTag(recordAppTags, @"hidden") || tagArrayContainsTag(sbAppTags, @"hidden") || isWebApplication || launchProhibited;
}
-@end
+@end \ No newline at end of file
diff --git a/QuickActions/QuickActionsPrefs/QASRootListController.m b/QuickActions/QuickActionsPrefs/QASRootListController.m
index 2fe7cb2..0d26dc7 100644
--- a/QuickActions/QuickActionsPrefs/QASRootListController.m
+++ b/QuickActions/QuickActionsPrefs/QASRootListController.m
@@ -14,6 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+#import "Preferences/PSTableCell.h"
#import <Foundation/Foundation.h>
#import "QASRootListController.h"
#include <spawn.h>
@@ -32,7 +33,7 @@
-(void)viewDidLoad
{
[super viewDidLoad];
- UIBarButtonItem *respringButton = [[UIBarButtonItem alloc] initWithTitle:@"Respring"
+ UIBarButtonItem *respringButton = [[UIBarButtonItem alloc] initWithTitle:@"Apply"
style:UIBarButtonItemStylePlain
target:self
action:@selector(respring)];