Last active
August 21, 2019 16:03
-
-
Save spencerm/1005327871474b5cecccb1fb9109dda8 to your computer and use it in GitHub Desktop.
adding timezones & local time to gutenberg
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
const { registerPlugin } = wp.plugins; | |
const { PluginPostStatusInfo } = wp.editPost; | |
const { Component } = wp.element; | |
const { withSelect } = wp.data; | |
import TimezonePicker from 'react-timezone'; | |
import {SlideDown} from 'react-slidedown' | |
import { __ } from '@wordpress/i18n'; | |
import { dateI18n, __experimentalGetSettings } from '@wordpress/date'; | |
import { DateTimePicker, Button, Popover } from '@wordpress/components'; | |
import moment from 'moment'; | |
import 'moment-timezone/moment-timezone'; | |
import { styles } from './styled'; | |
import 'react-slidedown/lib/slidedown.css' | |
/** | |
* Store all time without timezones | |
* | |
* | |
*/ | |
const TIMEZONELESS_FORMAT = 'YYYY-MM-DDTHH:mm:ss'; | |
class Timezone extends Component { | |
constructor() { | |
super( ...arguments ); | |
this.state = { | |
tz: '', | |
localDateTime: '', | |
gmtDateTime: '', | |
tzAbbr: '', | |
closed: false, | |
} | |
this._handleTZChange = this._handleTZChange.bind(this); | |
this._handleLocalTimeChange = this._handleLocalTimeChange.bind(this); | |
this._handleToggle = this._handleToggle.bind(this); | |
} | |
componentDidMount() { | |
wp.apiFetch( { path: `/wp/v2/${this.props.postType}/${this.props.postID}`, method: 'GET' } ).then( | |
( data ) => { | |
if( data.meta.post_meta_timezone ){ | |
let local = moment.tz( this.props.postDate, 'Etc/GMT' ).tz( data.meta.post_meta_timezone ).format( TIMEZONELESS_FORMAT ) | |
let localinutc = moment( this.props.postDate ).tz( data.meta.post_meta_timezone ).format() | |
this.setState( { | |
tz: data.meta.post_meta_timezone, | |
gmtDateTime: this.props.postDate, | |
localDateTime: local, | |
tzAbbr: moment.tz( data.meta.post_meta_timezone ).zoneAbbr(), | |
closed: true, | |
} ) | |
} else { | |
this.setState( { | |
tz: 'UTC', | |
localDateTime: this.props.postDate, | |
gmtDateTime: this.props.postDate, | |
tzAbbr: moment.tz('UTC').zoneAbbr(), | |
closed: true, | |
} ) | |
} | |
}, | |
( err ) => { | |
return err; | |
} | |
) | |
} | |
_handleTZChange( tz ) { | |
// get new abbreviation | |
let tzAbbr = moment.tz( tz ).zoneAbbr() | |
// calculate new gmt time | |
let localDateTime = moment.tz( this.state.localDateTime, tz ) | |
let gmtDateTime = moment.utc( localDateTime ).format( TIMEZONELESS_FORMAT ) | |
// set timezone, abbreviation, gmt time | |
this.setState({ tz, tzAbbr, gmtDateTime }) | |
wp.data.dispatch('core/editor').editPost( { date: gmtDateTime, date_gmt: gmtDateTime } ) | |
wp.data.dispatch('core/editor').editPost( { meta:{ post_meta_timezone: tz } } ) | |
// console.log("tz change to: " + JSON.stringify( tz ) + localDateTime ) | |
} | |
_handleLocalTimeChange( localDateTime ) { | |
// calculate new gmt time | |
let newLocal = moment.tz( localDateTime, this.state.tz ) | |
let gmtDateTime = moment.utc( newLocal ).format( TIMEZONELESS_FORMAT ) | |
// set local time, gmt time | |
this.setState({ localDateTime, gmtDateTime }) | |
wp.data.dispatch('core/editor').editPost( { date: gmtDateTime, date_gmt: gmtDateTime } ) | |
// console.log("time change to: " + JSON.stringify( localDateTime ) + " gmt: " + gmtDateTime ) | |
} | |
_handleToggle() { | |
this.setState( | |
({ closed : !this.state.closed }) | |
) | |
} | |
render() { | |
const is12HourTime = /a(?!\\)/i.test( | |
__experimentalGetSettings().formats.time | |
.toLowerCase() // Test only the lower case a | |
.replace( /\\\\/g, '' ) // Replace "//" with empty strings | |
.split( '' ).reverse().join( '' ) // Reverse the string and test for "a" not followed by a slash | |
); | |
const formattedTime = dateI18n( "M j, Y g:ia", this.state.localDateTime ) | |
return ( | |
<PluginPostStatusInfo className={ styles.plugin }> | |
<div className={ styles.row }> | |
<span> | |
{ __( 'Publish' ) } {this.state.tzAbbr} | |
</span> | |
<Button | |
type="button" | |
onClick={ this._handleToggle } | |
isLink | |
> | |
{ formattedTime } | |
</Button> | |
</div> | |
<SlideDown closed={this.state.closed} className='dropdown-slidedown' alwaysRender={true}> | |
<TimezonePicker | |
value={ this.state.tz } | |
onChange={ timezone => this._handleTZChange( timezone ) } | |
className={ styles.tz } | |
inputProps={{ | |
placeholder: 'Select Timezone...', | |
name: 'timezone', | |
}} | |
/> | |
<DateTimePicker | |
currentDate={ this.state.localDateTime } | |
onChange={ this._handleLocalTimeChange } | |
is12Hour={ is12HourTime } | |
/> | |
</SlideDown> | |
</PluginPostStatusInfo> | |
) | |
} | |
} | |
const TimezoneSelect = withSelect( ( select ) => { | |
const { getCurrentPostId, getCurrentPostType, isEditedPostDateFloating, getEditedPostAttribute } = select( 'core/editor' ) | |
return { postID: getCurrentPostId(), postType: getCurrentPostType(), isFloating: isEditedPostDateFloating(), postDate: getEditedPostAttribute( "date" ) } | |
} )( Timezone ); | |
registerPlugin( 'post-status-info-timezone', { render: TimezoneSelect } ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment