Skip to:
Content

BuddyPress.org

Changeset 8754


Ignore:
Timestamp:
08/03/2014 08:52:05 PM (7 years ago)
Author:
djpaul
Message:

Activity: introducing @mentions auto-suggestions.

Activity has long-supported @mentions, where you can mention the name of another user to get their attention in a conversation. You've always had to know the exact username of the person you're trying to mention, or you've been forced to go look it up. Now, when leaving an activity update or reply, press @ and then start typing someone's diaply name (or user_nicename), and username suggestions will automatically appear below where you're typing.

If the Friends component is active, and if the logged-in user has any friends, those friends' details are used to pre-prime the username suggestions for super-fast snappy suggestions. Suggestions are also provided when writing a blog post comment.

This change has mostly been implemented using two third-party libraries, At.js (https://github.com/ichord/At.js) and Caret.js (https://github.com/ichord/Caret.js). Big thanks to those projects' authors for their fine work, and also to Automattic's O2 team, who made a number of CSS+JS tweaks/adaptions to At.js, which we've adopted. Props also to karmatosed for design suggestions on the earliest implementation of this feature, three years ago. :)

Fixes #3278

Location:
trunk
Files:
10 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Gruntfile.js

    r8551 r8754  
    77
    88    BP_CSS = [
     9        'bp-activity/css/*.css',
    910        'bp-activity/admin/css/*.css',
    1011        'bp-core/admin/css/*.css',
     
    1920
    2021    BP_JS = [
     22        'bp-activity/js/*.js',
    2123        'bp-activity/admin/js/*.js',
    2224        'bp-core/js/*.js',
     
    3133
    3234    BP_EXCLUDED_JS = [
     35        '!bp-core/js/jquery.atwho.js',
     36        '!bp-core/js/jquery.caret.js',
    3337        '!bp-templates/bp-legacy/js/*.js'
    3438    ];
  • trunk/src/bp-activity/bp-activity-actions.php

    r8662 r8754  
    648648    $bp->activity->akismet = new BP_Akismet();
    649649}
     650
     651/**
     652 * AJAX endpoint for Suggestions API lookups.
     653 *
     654 * @since BuddyPress (2.1.0)
     655 */
     656function bp_ajax_get_suggestions() {
     657    if ( ! bp_is_user_active() || empty( $_GET['term'] ) || empty( $_GET['type'] ) ) {
     658        wp_send_json_error( 'missing_parameter' );
     659        exit;
     660    }
     661
     662    $results = bp_core_get_suggestions( array(
     663        'term' => sanitize_text_field( $_GET['term'] ),
     664        'type' => sanitize_text_field( $_GET['type'] ),
     665    ) );
     666
     667    if ( is_wp_error( $results ) ) {
     668        wp_send_json_error( $results->get_error_message() );
     669        exit;
     670    }
     671
     672    wp_send_json_success( $results );
     673}
     674add_action( 'wp_ajax_bp_get_suggestions', 'bp_ajax_get_suggestions' );
  • trunk/src/bp-activity/bp-activity-functions.php

    r8716 r8754  
    4747function bp_activity_do_mentions() {
    4848    return (bool) apply_filters( 'bp_activity_do_mentions', true );
     49}
     50
     51/**
     52 * Should BuddyPress load the mentions scripts and related assets, including results to prime the
     53 * mentions suggestions?
     54 *
     55 * @return bool True if mentions scripts should be loaded.
     56 * @since BuddyPress (2.1.0)
     57 */
     58function bp_activity_maybe_load_mentions_scripts() {
     59    $retval =
     60        bp_activity_do_mentions() &&
     61        bp_is_user_active() &&
     62        ( bp_is_activity_component() || bp_is_blog_page() && is_singular() && comments_open() || is_admin() );
     63
     64    return (bool) apply_filters( 'bp_activity_maybe_load_mentions_scripts', $retval );
    4965}
    5066
  • trunk/src/bp-activity/bp-activity-loader.php

    r8705 r8754  
    4848        // Files to include
    4949        $includes = array(
     50            'cssjs',
    5051            'actions',
    5152            'screens',
  • trunk/src/bp-core/bp-core-cssjs.php

    r8673 r8754  
    2020   
    2121    $scripts = apply_filters( 'bp_core_register_common_scripts', array(
     22        // Legacy
    2223        'bp-confirm'        => array( 'file' => "{$url}confirm{$ext}",        'dependencies' => array( 'jquery' ) ),
    2324        'bp-widget-members' => array( 'file' => "{$url}widget-members{$ext}", 'dependencies' => array( 'jquery' ) ),
    2425        'bp-jquery-query'   => array( 'file' => "{$url}jquery-query{$ext}",   'dependencies' => array( 'jquery' ) ),
    2526        'bp-jquery-cookie'  => array( 'file' => "{$url}jquery-cookie{$ext}",  'dependencies' => array( 'jquery' ) ),
     27
     28        // 2.1
     29        'jquery-caret' => array( 'file' => "{$url}jquery.caret{$ext}", 'dependencies' => array( 'jquery' ) ),
     30        'jquery-atwho' => array( 'file' => "{$url}jquery.atwho{$ext}", 'dependencies' => array( 'jquery', 'jquery-caret' ) ),
    2631    ) );
    2732
  • trunk/src/bp-friends/bp-friends-functions.php

    r8514 r8754  
    567567add_action( 'delete_user',       'friends_remove_data' );
    568568add_action( 'bp_make_spam_user', 'friends_remove_data' );
     569
     570/**
     571 * Used by the Activity component's @mentions to print a JSON list of the current user's friends.
     572 *
     573 * This is intended to speed up @mentions lookups for a majority of use cases.
     574 *
     575 * @see bp_activity_mentions_script()
     576 */
     577function bp_friends_prime_mentions_results() {
     578    if ( ! bp_activity_maybe_load_mentions_scripts() ) {
     579        return;
     580    }
     581
     582    $friends_query = array(
     583        'count_total'     => '',                    // Prevents total count
     584        'populate_extras' => false,
     585
     586        'type'            => 'alphabetical',
     587        'user_id'         => get_current_user_id(),
     588    );
     589
     590    $friends_query = new BP_User_Query( $friends_query );
     591    $results       = array();
     592
     593    foreach ( $friends_query->results as $user ) {
     594        $result        = new stdClass();
     595        $result->ID    = $user->user_nicename;
     596        $result->image = bp_core_fetch_avatar( array( 'html' => false, 'item_id' => $user->ID ) );
     597        $result->name  = bp_core_get_user_displayname( $user->ID );
     598
     599        $results[] = $result;
     600    }
     601
     602    wp_localize_script( 'bp-mentions', 'BP_Suggestions', array(
     603        'friends' => $results,
     604    ) );
     605}
     606add_action( 'bp_activity_mentions_prime_results', 'bp_friends_prime_mentions_results' );
  • trunk/src/bp-templates/bp-legacy/buddypress/activity/entry.php

    r7965 r8754  
    9898                    <div class="ac-reply-content">
    9999                        <div class="ac-textarea">
    100                             <textarea id="ac-input-<?php bp_activity_id(); ?>" class="ac-input" name="ac_input_<?php bp_activity_id(); ?>"></textarea>
     100                            <textarea id="ac-input-<?php bp_activity_id(); ?>" class="ac-input bp-suggestions" name="ac_input_<?php bp_activity_id(); ?>"></textarea>
    101101                        </div>
    102102                        <input type="submit" name="ac_form_submit" value="<?php esc_attr_e( 'Post', 'buddypress' ); ?>" /> &nbsp; <a href="#" class="ac-reply-cancel"><?php _e( 'Cancel', 'buddypress' ); ?></a>
  • trunk/src/bp-templates/bp-legacy/buddypress/activity/post-form.php

    r8405 r8754  
    2828    <div id="whats-new-content">
    2929        <div id="whats-new-textarea">
    30             <textarea name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_textarea( $_GET['r'] ); ?> <?php endif; ?></textarea>
     30            <textarea class="bp-suggestions" name="whats-new" id="whats-new" cols="50" rows="10"><?php if ( isset( $_GET['r'] ) ) : ?>@<?php echo esc_textarea( $_GET['r'] ); ?> <?php endif; ?></textarea>
    3131        </div>
    3232
Note: See TracChangeset for help on using the changeset viewer.