Skip to content

Commit

Permalink
Blocks: Create a Live Schedule block (#243)
Browse files Browse the repository at this point in the history
Add a new block called "Live Schedule", which can be used on the Day of Event template (or any other page). This copies the functionality from the Live Schedule component into a block. Eventually, this will let organizers have total control over the content of the Day of Event template.

Fixes #127 – You can customize the heading text and level in the block UI.
See #130 – Addresses a few tasks from this issue
  • Loading branch information
ryelle authored Oct 11, 2019
1 parent d5c24f8 commit 167342e
Show file tree
Hide file tree
Showing 19 changed files with 730 additions and 103 deletions.
7 changes: 7 additions & 0 deletions public_html/wp-content/mu-plugins/blocks/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ function load_includes() {
require_once $blocks_dir . 'speakers/controller.php';
require_once $blocks_dir . 'sponsors/controller.php';

if (
( defined( 'WORDCAMP_ENVIRONMENT' ) && 'production' !== WORDCAMP_ENVIRONMENT )
|| in_array( get_current_blog_id(), [ 928 ], true ) // 2017.testing
) {
require_once $blocks_dir . 'live-schedule/controller.php';
}

}

add_action( 'plugins_loaded', __NAMESPACE__ . '\load_includes' );
Expand Down
4 changes: 2 additions & 2 deletions public_html/wp-content/mu-plugins/blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
"*.min.js"
],
"scripts": {
"start": "wp-scripts start source/blocks.js",
"build": "wp-scripts build source/blocks.js",
"start": "wp-scripts start blocks=./source/blocks.js live-schedule=./source/blocks/live-schedule/front-end.js",
"build": "wp-scripts build blocks=./source/blocks.js live-schedule=./source/blocks/live-schedule/front-end.js",
"lint:js": "wp-scripts lint-js",
"lint:css": "wp-scripts lint-style '**/*.scss'",
"lint:pkg-json": "wp-scripts lint-pkg-json",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/**
* Internal dependencies
*/
import * as liveSchedule from './live-schedule';
import * as organizers from './organizers';
import * as sessions from './sessions';
import * as speakers from './speakers';
import * as sponsors from './sponsors';

export const BLOCKS = [
liveSchedule,
organizers,
sessions,
speakers,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* WordPress dependencies
*/
import { _x } from '@wordpress/i18n';
import { Component } from '@wordpress/element';

/**
* Internal dependencies
*/
import { getDataFromAPI } from './data';
import LiveSchedule from './components/schedule';

/**
* Display the live schedule.
*
* @returns {Component}
*/
class Block extends Component {
constructor( props ) {
super( props );
this.state = {
sessions: [],
isFetching: true,
};
this.fetchApi = this.fetchApi.bind( this );
this.apiInterval = setInterval( this.fetchApi, 5 * 60 * 1000 ); // 5 minutes in ms.

this.renderInterval = setInterval( () => {
// `forceUpdate` is a React internal that triggers a render cycle.
this.forceUpdate();
}, 60 * 1000 ); // 1 minutes in ms.
}

componentDidMount() {
this.fetchApi();
}

componentWillUnmount() {
clearInterval( this.apiInterval );
clearInterval( this.renderInterval );
}

fetchApi() {
getDataFromAPI().then( ( sessions ) => this.setState( { sessions: sessions, isFetching: false } ) );
}

render() {
const { config, attributes } = this.props;
const { sessions, isFetching } = this.state;

let classes = 'wordcamp-live-schedule';
if ( isFetching ) {
classes += ' is-fetching';
}

return (
<div className={ classes }>
<LiveSchedule
config={ config }
sessions={ sessions }
isFetching={ isFetching }
attributes={ attributes }
/>
<p className="wp-block-button aligncenter">
<a
className="wordcamp-live-schedule__schedule-link wp-block-button__link"
href={ config.scheduleUrl }
>
{ _x( 'View Full Schedule', 'text', 'wordcamporg' ) }
</a>
</p>
</div>
);
}
}

export default Block;
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Fragment } from '@wordpress/element';

/**
* Internal dependencies
*/
import Session from './session';

export default function( { attributes, isFetching, sessions } ) {
// A session track is "running" if there is a talk either now or next.
const runningSessions = sessions.filter( ( session ) => ( !! session.now || !! session.next ) );

if ( ! isFetching && ! runningSessions.length ) {
return <p>{ __( 'No WordCamp events are scheduled today :(', 'wordcamporg' ) }</p>;
}

if ( isFetching ) {
return <span className="components-spinner" />;
}

const { level = 2 } = attributes;
const Heading = `h${ level }`;

return (
<Fragment>
<Heading className="wordcamp-live-schedule__title">{ attributes.now }</Heading>

{ sessions.map( ( trackPair, index ) => {
const session = trackPair.now;
const track = trackPair.track;
const sessionKey = `${ session ? session.id : index }-${ track.id }`;

return (
<Session
key={ sessionKey }
headingLevel={ parseInt( level ) + 1 }
session={ session }
track={ track }
/>
);
} ) }

<Heading className="wordcamp-live-schedule__title">{ attributes.next }</Heading>

{ sessions.map( ( trackPair, index ) => {
const session = trackPair.next;
const track = trackPair.track;
const sessionKey = `${ session ? session.id : index }-${ track.id }`;

return (
<Session
key={ sessionKey }
headingLevel={ parseInt( level ) + 1 }
session={ session }
track={ track }
/>
);
} ) }

</Fragment>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* External dependencies
*/
import { get } from 'lodash';

/**
* WordPress dependencies
*/
import { stripTagsAndEncodeText } from '@wordpress/sanitize';

/**
* Component
*
* @returns {Component}
*/
export default function( { headingLevel = 3, session, track } ) {
if ( ! session ) {
return null;
}
const Heading = `h${ headingLevel }`;

// Pull details out of the session object.
const { link, terms = {} } = session;
const title = get( session, 'title.rendered', '' );
const type = get( session, 'meta._wcpt_session_type', '' );
const categories = session.session_category || [];
const time = get( session, 'session_date_time.time', '' );

const speakers = get( session, '_embedded.speakers', [] );
const validSpeakers = speakers.filter( ( speaker ) => !! speaker.id );

return (
<div className={ `wordcamp-live-schedule__session type-${ type }` }>
<span className={ `wordcamp-live-schedule__session-track track-${ track.slug }` }>{ track.name }</span>

<div className="wordcamp-live-schedule__session-details">
<Heading className="wordcamp-live-schedule__session-title">
{ !! link ? (
<a href={ link }>{ stripTagsAndEncodeText( title ) }</a>
) : (
stripTagsAndEncodeText( title )
) }
</Heading>

<span className="wordcamp-live-schedule__session-time">{ time }</span>

<span className="wordcamp-live-schedule__session-speaker">
{ !! validSpeakers.length &&
validSpeakers.map( ( speaker ) => {
const {
id,
title: { rendered: name },
link: speakerLink,
} = speaker;

return (
<a key={ id } href={ speakerLink }>
{ stripTagsAndEncodeText( name ) }
</a>
);
} ) }
</span>

{ categories.map( ( catId ) => {
const name = terms[ catId ].name;
const slug = terms[ catId ].slug;

return (
<span key={ catId } className={ `wordcamp-live-schedule__session-cat category-${ slug }` }>
{ name }
</span>
);
} ) }
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
namespace WordCamp\Blocks\Live_Schedule;

defined( 'WPINC' ) || die();

/**
* Register Live Schedule block and enqueue assets.
*/
function init() {
$deps_path = \WordCamp\Blocks\PLUGIN_DIR . 'build/live-schedule.min.deps.json';
$dependencies = file_exists( $deps_path ) ? json_decode( file_get_contents( $deps_path ) ) : array();

wp_register_script(
'wordcamp-live-schedule',
\WordCamp\Blocks\PLUGIN_URL . 'build/live-schedule.min.js',
$dependencies,
filemtime( \WordCamp\Blocks\PLUGIN_DIR . 'build/live-schedule.min.js' ),
true
);

/** This filter is documented in mu-plugins/blocks/blocks.php */
$data = apply_filters( 'wordcamp_blocks_script_data', [] );

wp_add_inline_script(
'wordcamp-live-schedule',
sprintf(
'var WordCampBlocks = JSON.parse( decodeURIComponent( \'%s\' ) );',
rawurlencode( wp_json_encode( $data ) )
),
'before'
);

wp_set_script_translations( 'wordcamp-live-schedule', 'wordcamporg' );

wp_register_style(
'wordcamp-live-schedule',
\WordCamp\Blocks\PLUGIN_URL . 'build/live-schedule.min.css',
[],
filemtime( \WordCamp\Blocks\PLUGIN_DIR . 'build/live-schedule.min.css' )
);

register_block_type(
'wordcamp/live-schedule',
array(
'editor_script' => 'wordcamp-blocks',
'editor_style' => 'wordcamp-blocks',
'style' => 'wordcamp-live-schedule',
'script' => 'wordcamp-live-schedule',
)
);
}
add_action( 'init', __NAMESPACE__ . '\init' );

/**
* Add data to be used by the JS scripts in the block editor.
*
* @param array $data
*
* @return array
*/
function add_script_data( array $data ) {
$data['live-schedule'] = [
'scheduleUrl' => esc_url( site_url( __( 'schedule', 'wordcamporg' ) ) ),
];

return $data;
}
add_filter( 'wordcamp_blocks_script_data', __NAMESPACE__ . '\add_script_data' );
Loading

0 comments on commit 167342e

Please sign in to comment.