Skip to content

Instantly share code, notes, and snippets.

@spencerm
Last active August 21, 2019 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spencerm/1005327871474b5cecccb1fb9109dda8 to your computer and use it in GitHub Desktop.
Save spencerm/1005327871474b5cecccb1fb9109dda8 to your computer and use it in GitHub Desktop.
adding timezones & local time to gutenberg
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