Two different conditions with a single WP_Query

So from my understanding:

IF > User not Logged In – Show all ‘Public’ (meta) posts.

ELSE IF > User Logged In – Show all ‘Public’ (meta) posts (from all users) AND all ‘Private’ (meta) posts from the current logged in user.

I’ve run two queries below and combined the posts. It’s not without flaws, for instance: On the first page it shows more than posts_per_page parameter. I also couldn’t manually override the default posts_per_page without breaking pagination.

You may need to save out permalinks to get this to work – hopefully it does!

<?php
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;

    $mainQuery = new WP_Query(array('meta_query' => array(array('key' => 'key1', 'value' => 'public'))));

    $postCount = $mainQuery->post_count;

    if(is_user_logged_in()){
        $secondQuery = new WP_Query(array('post', 'meta_query' => array(array('key' => 'key1', 'value' => 'private')), 'author' => get_current_user_id(), 'paged' => $paged));
        $postCount = ($postCount + $secondQuery->post_count);

        $mainQuery->posts = array_merge($mainQuery->posts, $secondQuery->posts);
        $mainQuery->post_count = $postCount;
        $mainQuery->max_num_pages = ceil($postCount / $posts_per_page);
    }
?>

<?php if($mainQuery->have_posts()) : ?>
    <?php while($mainQuery->have_posts()) : $mainQuery->the_post(); ?>
        <h1><?php the_title(); ?></h1> 
    <?php endwhile; ?>
<?php endif; ?>

<?php if($mainQuery->max_num_pages > 1) : ?>
    <?php 
        $big = 9999999999;
        $args = array(
            'base'          => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
            'format'        => '?paged=%#%',
            'current'       => max( 1, $paged ),
            'total'         => $mainQuery->max_num_pages,
            'end_size'      => 0,
            'mid_size'      => 2,
            'prev_next'     => False
        ); 
        echo paginate_links($args); 
    ?>
<?php endif; ?>