]> git.cameronkatri.com Git - tweaks.git/commitdiff
I hate this project
authorCameron Katri <me@cameronkatri.com>
Wed, 29 Dec 2021 15:41:53 +0000 (10:41 -0500)
committerCameron Katri <me@cameronkatri.com>
Wed, 29 Dec 2021 15:41:53 +0000 (10:41 -0500)
QuickActions/DragonMake
QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h [new file with mode: 0644]
QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m [new file with mode: 0644]
QuickActions/QuickActionsPrefs/QASAppSelectorController.h
QuickActions/QuickActionsPrefs/QASAppSelectorController.m
QuickActions/QuickActionsPrefs/QASRootListController.m

index f75e655021e0614db156c50d48e9db898f0716ab..0d4f18cd5cc832dd5f264169607d01c435e4bbbc 100644 (file)
@@ -27,6 +27,7 @@ QuickActionsPrefs:
   files:
     - QASRootListController.m
     - QASAppSelectorController.m
+    - LSApplicationProxy+AltList.m
   frameworks:
     - MobileCoreServices
   targetvers: 13.0
\ No newline at end of file
diff --git a/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h b/QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.h
new file mode 100644 (file)
index 0000000..65866ab
--- /dev/null
@@ -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 (file)
index 0000000..ab6c292
--- /dev/null
@@ -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
index 13ffe6050182900764adabf6db9b4dcdaabae74e..f439fcb86f261107ebeac5ffefe6dcefb45d0023 100644 (file)
@@ -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
index cfb6c7a218583433f90a17cbe7f0684ee30d7fd0..cadca5c18779c7af4a7c74210e6c23d14994278e 100644 (file)
@@ -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) {
                [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) {
 
                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;
 
 
 -(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];
 
 -(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
index 2fe7cb21d80b0e59e6fdf31daa150a4854cde499..0d26dc731b1309cd049d69923740f51e04500e91 100644 (file)
@@ -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)];