~not/sonar

7c9a7f0b475894bd1cd9d806e9a67e902549c910 — b123400 a month ago 9a49b85 search
Integrated UI with local search
2 files changed, 58 insertions(+), 10 deletions(-)

M Sonar/Player/PlayerViewModeState.h
M Sonar/Player/PlayerWindowController.m
M Sonar/Player/PlayerViewModeState.h => Sonar/Player/PlayerViewModeState.h +1 -0
@@ 15,6 15,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, strong) NSArray<NSArray *> *expandedItems;
@property (nonatomic, assign) CGFloat scrollOffset;
@property (nonatomic, assign) BOOL initialLoaded;
@property (nonatomic, strong) NSString *searchQuery; // Search mode only

@end


M Sonar/Player/PlayerWindowController.m => Sonar/Player/PlayerWindowController.m +57 -10
@@ 22,6 22,7 @@ typedef enum : NSUInteger {
    PlayerWindowControllerViewModePlaylists = 1,
    PlayerWindowControllerViewModeAlbums = 2,
    PlayerWindowControllerViewModeStarred = 3,
    PlayerWindowControllerViewModeSearch = 4,
} PlayerWindowControllerViewMode;

@interface PlayerWindowController () <NSOutlineViewDelegate, NSOutlineViewDataSource, NSMenuDelegate>


@@ 59,6 60,7 @@ typedef enum : NSUInteger {

@property (nonatomic, assign) BOOL isExtraVisible;
@property (strong) IBOutlet NSLayoutConstraint *extraBottomConstraint;
@property (strong) IBOutlet NSLayoutConstraint *searchFieldHeightConstraint;

@property (strong) IBOutlet NSMenu *columnsMenu;
@property (strong) IBOutlet NSMenu *outlineViewMenu;


@@ 86,7 88,7 @@ typedef enum : NSUInteger {
- (instancetype)init {
    self = [super initWithWindowNibName:@"PlayerWindowController"];
    self.isExtraVisible = YES;
    self.viewModeStates = [NSMutableDictionary dictionaryWithCapacity:4];
    self.viewModeStates = [NSMutableDictionary dictionaryWithCapacity:5];
    self.volume = 1.0;
    return self;
}


@@ 127,6 129,11 @@ typedef enum : NSUInteger {
            i++;
        }
    }
    [[MediaDB shared] searchWithKeyword:@"star"
                             completion:^(NSError * _Nullable error, NSArray<BaseModel *> * _Nullable items) {
        
    }
                            fetchRemote:YES];
}

- (void)mouseEntered:(NSEvent *)event {


@@ 327,12 334,17 @@ typedef enum : NSUInteger {
        [self storeCurrentViewModeState];
    }
    _viewMode = newMode;
    self.favouritesModeButton.highlighted =
    self.playlistsModeButton.highlighted =
    self.artistsModeButton.highlighted =
    self.albumsModeButton.highlighted =
    self.favouritesModeButton.highlighted = newMode == PlayerWindowControllerViewModeStarred;
    self.playlistsModeButton.highlighted = newMode == PlayerWindowControllerViewModePlaylists;
    self.artistsModeButton.highlighted = newMode == PlayerWindowControllerViewModeArtists;
    self.albumsModeButton.highlighted = newMode == PlayerWindowControllerViewModeAlbums;
    self.searchModeButton.highlighted = newMode == PlayerWindowControllerViewModeSearch;
    self.songsModeButton.highlighted = NO;
    
    self.searchField.hidden = newMode != PlayerWindowControllerViewModeSearch;

    self.searchFieldHeightConstraint.constant = 0;
    
    NSMenuItem *viewItem = [[[NSApplication sharedApplication] mainMenu] itemWithTag:30];
    NSMenuItem *favouritesItem = [[viewItem submenu] itemWithTag:31];
    NSMenuItem *playlistsItem = [[viewItem submenu] itemWithTag:32];


@@ 347,7 359,6 @@ typedef enum : NSUInteger {
    typeof(self) __weak weakSelf = self;
    switch (_viewMode) {
        case PlayerWindowControllerViewModeArtists: {
            self.artistsModeButton.highlighted = YES;
            artistsItem.state = NSControlStateValueOff;
            [[MediaDB shared] listArtistsWithCompletion:^(NSError * _Nonnull error, NSArray<Artist *> * _Nonnull artists) {
                if (weakSelf.viewMode != newMode) return;


@@ 366,7 377,6 @@ typedef enum : NSUInteger {
        }
            break;
        case PlayerWindowControllerViewModePlaylists: {
            self.playlistsModeButton.highlighted = YES;
            playlistsItem.state = NSControlStateValueOff;
            [[MediaDB shared] listPlaylistsWithCompletion:^(NSError * _Nullable error, NSArray<Playlist *> * _Nullable playlists) {
                if (weakSelf.viewMode != newMode) return;


@@ 385,7 395,6 @@ typedef enum : NSUInteger {
        }
            break;
        case PlayerWindowControllerViewModeAlbums: {
            self.albumsModeButton.highlighted = YES;
            albumsItem.state = NSControlStateValueOff;
            [[MediaDB shared] listAlbumsWithCompletion:^(NSError * _Nullable error, NSArray<Album *> * _Nullable albums) {
                if (weakSelf.viewMode != newMode) return;


@@ 404,7 413,6 @@ typedef enum : NSUInteger {
        }
            break;
        case PlayerWindowControllerViewModeStarred: {
            self.favouritesModeButton.highlighted = YES;
            favouritesItem.state = NSControlStateValueOff;
            [[MediaDB shared] listStarredItems:^(NSError * _Nullable error, NSArray<BaseModel *> * _Nullable items) {
                if (weakSelf.viewMode != newMode) return;


@@ 422,10 430,36 @@ typedef enum : NSUInteger {
                                   fetchRemote:update];
        }
            break;
        case PlayerWindowControllerViewModeSearch: {
            self.searchFieldHeightConstraint.constant = 22;
            
            NSString *query = self.viewModeStates[@(PlayerWindowControllerViewModeSearch)].searchQuery;
            if (!query.length) {
                [self setOutlineViewItems:[NSMutableArray array]];
                self.viewModeStates[@(PlayerWindowControllerViewModeSearch)] = [[PlayerViewModeState alloc] init];
                [self.outlineView reloadData];
            } else {
                [[MediaDB shared] searchWithKeyword:query completion:^(NSError * _Nullable error, NSArray<BaseModel *> * _Nullable items) {
                    if (weakSelf.viewMode != PlayerWindowControllerViewModeSearch) return;
                    if (![weakSelf.viewModeStates[@(PlayerWindowControllerViewModeSearch)].searchQuery isEqual:query]) return;
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [weakSelf sortAndSetOutlineViewItems:items];
                        if (error) {
                            [weakSelf displayError:error];
                            return;
                        }
                        [weakSelf.outlineView reloadData];
                        [weakSelf restoreCurrentViewModeState];
                        weakSelf.viewModeStates[@(weakSelf.viewMode)].initialLoaded = YES;
                    });
                }
                                        fetchRemote:update];
            }
            
        }
        default:
            break;
    }
    
    [self invalidateRestorableState];
}



@@ 484,9 518,22 @@ typedef enum : NSUInteger {
- (IBAction)albumsModeClicked:(id)sender {
    self.viewMode = PlayerWindowControllerViewModeAlbums;
}
- (IBAction)searchModeClicked:(id)sender {
    self.viewMode = PlayerWindowControllerViewModeSearch;
}
- (IBAction)songsModeClicked:(id)sender {
}

- (IBAction)didEnteredSearchQuery:(id)sender {
    NSString *query = self.searchField.stringValue;
    PlayerViewModeState *state = self.viewModeStates[@(PlayerWindowControllerViewModeSearch)] =  [[PlayerViewModeState alloc] init];
    state.searchQuery = query;
    state.initialLoaded = NO;
    state.expandedItems = @[];
    state.scrollOffset = 0;
    [self setViewMode:PlayerWindowControllerViewModeSearch updatingItems:YES];
}

- (void)setIsRandomMode:(BOOL)isRandomMode {
    _isRandomMode = isRandomMode;
    [self reloadControls];