-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Blocks: Create a Live Schedule block (#243)
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
Showing
19 changed files
with
730 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
public_html/wp-content/mu-plugins/blocks/source/blocks/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
public_html/wp-content/mu-plugins/blocks/source/blocks/live-schedule/block.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
65 changes: 65 additions & 0 deletions
65
public_html/wp-content/mu-plugins/blocks/source/blocks/live-schedule/components/schedule.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |
77 changes: 77 additions & 0 deletions
77
public_html/wp-content/mu-plugins/blocks/source/blocks/live-schedule/components/session.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
); | ||
} |
68 changes: 68 additions & 0 deletions
68
public_html/wp-content/mu-plugins/blocks/source/blocks/live-schedule/controller.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' ); |
Oops, something went wrong.