PluginProbe
codoc / 0.9.61
codoc v0.9.61
0.9.61 0.9.8.8 0.9.8.9 0.9.9 0.9.9.1 trunk 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.8.1 0.8.2 0.8.3 0.8.4 0.8.6 0.8.7 0.8.8 0.8.9 0.9 0.9.1 0.9.10 All 115 releases
← All changes | src/block/block.js +348 -75 0.9.8.9 → 0.9.61 View file →
@@ -10,9 +10,8 @@
10 10 import './editor.scss';
11 11 import icon from './icon';
12 12 //import { ENTER } from '@wordpress/keycodes';
13 13 const { ENTER } = wp.keycodes;
14 -
15 14 const { __ } = wp.i18n; // Import __() from wp.i18n
16 15 const { Component } = wp.element;
17 16
18 17 const { registerBlockType } = wp.blocks; // Import registerBlockType() from wp.blocks
@@ -26,10 +25,14 @@
26 25 PanelBody,
27 26 ToggleControl,
28 27 CheckboxControl,
29 28 RangeControl,
29 + TextControl,
30 + Notice,
30 31 } = wp.components;
31 32
33 +const { withSelect } = wp.data;
34 +
32 35 const {
33 36 getDefaultBlockName,
34 37 createBlock,
35 38 } = wp.blocks;
@@ -39,20 +42,151 @@
39 42 const CODOC_URL = OPTIONS.codoc_url;
40 43 const CODOC_USER_CODE = OPTIONS.codoc_usercode;
41 44 const CODOC_PLUGIN_VERSION = OPTIONS.codoc_plugin_version;
42 45 const CODOC_ENTRIES_CLASS = 'codoc-entries';
46 +const CODOC_ACCOUNT_IS_PRO = OPTIONS.codoc_account_is_pro;
47 +const CODOC_CURRENCY_CODE = OPTIONS.codoc_currency_code;
48 +const CODOC_CURRENCY_DECIMAL_PLACES = OPTIONS.codoc_currency_decimal_places;
43 49
44 50 //import Cookies from 'universal-cookie';
45 51 //const cookies = new Cookies();
46 52
53 +const CODOC_MAX_LENGTHS = OPTIONS.codoc_max_lengths || {};
54 +
55 +// エディタで前回使った設定を localStorage に保存し、新規ブロックの初期値に使う
56 +// (優先順位: 設定画面の Block Default Values -> 前回値 -> 固定値)
57 +const CODOC_LAST_USED_KEY = 'codoc_block_last_used';
58 +const CODOC_LAST_USED_ATTRS = ['showPrice','price','limited','limitedCount','affiliateMode','affiliateRate','showSupport','showPaywalledSupport','showPayWithoutAccountButton','statusLimited','subscriptions'];
59 +function loadLastUsedAttributes() {
60 + try {
61 + const parsed = JSON.parse(window.localStorage.getItem(CODOC_LAST_USED_KEY) || 'null');
62 + return (parsed && typeof parsed === 'object') ? parsed : {};
63 + } catch (e) {
64 + return {};
65 + }
66 +}
67 +function saveLastUsedAttributes(attributes) {
68 + try {
69 + const saved = {};
70 + CODOC_LAST_USED_ATTRS.forEach((key) => {
71 + if (attributes[key] !== undefined && attributes[key] !== null) {
72 + saved[key] = attributes[key];
73 + }
74 + });
75 + window.localStorage.setItem(CODOC_LAST_USED_KEY, JSON.stringify(saved));
76 + } catch (e) {
77 + // localStorage が使えない環境では何もしない
78 + }
79 +}
80 +
81 +// codoc ブロックの直前/直後で本文を分割
82 +function splitCodocContent(content) {
83 + const blockRegex = /<!--\s*wp:codoc\/codoc-block[\s\S]*?<!--\s*\/wp:codoc\/codoc-block\s*-->/;
84 + const splited = (content || '').split(blockRegex);
85 + return {
86 + bodyFree: splited[0] || '',
87 + bodyPaywalled: splited.slice(1).join('') || '',
88 + };
89 +}
90 +
91 +function buildLengthErrors(title, bodyFree, bodyPaywalled) {
92 + const errors = [];
93 + const total = bodyFree.length + bodyPaywalled.length;
94 + if (CODOC_MAX_LENGTHS.title && title.length > CODOC_MAX_LENGTHS.title) {
95 + errors.push(__('Title exceeds the maximum length of', 'codoc') + ' ' + CODOC_MAX_LENGTHS.title + ' (' + title.length + ')');
96 + }
97 + if (CODOC_MAX_LENGTHS.body_free && bodyFree.length > CODOC_MAX_LENGTHS.body_free) {
98 + errors.push(__('Free area exceeds the maximum length of', 'codoc') + ' ' + CODOC_MAX_LENGTHS.body_free + ' (' + bodyFree.length + ')');
99 + }
100 + if (CODOC_MAX_LENGTHS.body_paywalled && bodyPaywalled.length > CODOC_MAX_LENGTHS.body_paywalled) {
101 + errors.push(__('Paid area exceeds the maximum length of', 'codoc') + ' ' + CODOC_MAX_LENGTHS.body_paywalled + ' (' + bodyPaywalled.length + ')');
102 + }
103 + if (CODOC_MAX_LENGTHS.body && total > CODOC_MAX_LENGTHS.body) {
104 + errors.push(__('Total body exceeds the maximum length of', 'codoc') + ' ' + CODOC_MAX_LENGTHS.body + ' (' + total + ')');
105 + }
106 + return errors;
107 +}
108 +
109 +// codoc ブロック選択時の Inspector サイドバーに警告を表示する
110 +const CodocLengthNotices = withSelect((select) => {
111 + const editor = select('core/editor');
112 + return {
113 + postTitle: editor ? editor.getEditedPostAttribute('title') : '',
114 + postContent: editor ? editor.getEditedPostAttribute('content') : '',
115 + };
116 +})(({ postTitle, postContent }) => {
117 + const { bodyFree, bodyPaywalled } = splitCodocContent(postContent);
118 + const errors = buildLengthErrors(postTitle || '', bodyFree, bodyPaywalled);
119 + if (errors.length === 0) {
120 + return null;
121 + }
122 + return (
123 + <Notice status="error" isDismissible={ false }>
124 + <strong>{ __('codoc length limit exceeded:', 'codoc') }</strong>
125 + <ul style={{ marginTop: '0.5em', marginBottom: 0 }}>
126 + { errors.map((e, i) => <li key={i}>{ e }</li>) }
127 + </ul>
128 + </Notice>
129 + );
130 +});
131 +
132 +// codoc ブロックを選択していなくても、本文中に存在すればエディタ上部に通知を表示する
133 +(function() {
134 + if (!wp.data || !wp.data.subscribe) {
135 + return;
136 + }
137 + const NOTICE_ID = 'codoc-length-limit';
138 + let lastState = '';
139 + wp.data.subscribe(function() {
140 + const editor = wp.data.select('core/editor');
141 + const blockEditor = wp.data.select('core/block-editor') || wp.data.select('core/editor');
142 + const noticesDispatch = wp.data.dispatch('core/notices');
143 + if (!editor || !blockEditor || !noticesDispatch) {
144 + return;
145 + }
146 + const blocks = blockEditor.getBlocks ? blockEditor.getBlocks() : [];
147 + const hasCodocBlock = blocks.some(function(b) { return b && b.name === 'codoc/codoc-block'; });
148 + if (!hasCodocBlock) {
149 + if (lastState !== '') {
150 + noticesDispatch.removeNotice(NOTICE_ID);
151 + lastState = '';
152 + }
153 + return;
154 + }
155 + const title = editor.getEditedPostAttribute('title') || '';
156 + const content = editor.getEditedPostAttribute('content') || '';
157 + const { bodyFree, bodyPaywalled } = splitCodocContent(content);
158 + const errors = buildLengthErrors(title, bodyFree, bodyPaywalled);
159 + const state = errors.join('||');
160 + if (state === lastState) {
161 + return;
162 + }
163 + lastState = state;
164 + noticesDispatch.removeNotice(NOTICE_ID);
165 + if (errors.length > 0) {
166 + noticesDispatch.createNotice(
167 + 'error',
168 + __('codoc length limit exceeded:', 'codoc') + ' ' + errors.join(' / '),
169 + { id: NOTICE_ID, isDismissible: false }
170 + );
171 + }
172 + });
173 +})();
174 +
47 175 class CodocControls extends Component {
48 176 constructor( props ) {
49 177 super( ...arguments );
50 178 this.subscriptionsFetched = [];
179 + this.subscriptionSearchTerm = '';
180 + this.state = {
181 + searchTerm: '',
182 + filteredSubscriptions: []
183 + };
51 184 this.fetchSubscriptions();
185 + this.handleSearchChange = this.handleSearchChange.bind(this);
52 186 }
53 187
54 - fetchSubscriptions() {
188 + fetchSubscriptions(searchTitle = '') {
55 189 const {
56 190 setAttributes,
57 191 attributes: {
58 192 fetching,
@@ -65,8 +199,13 @@
65 199
66 200 setAttributes( { fetching: true } )
67 201 let url = CODOC_URL + '/api/v1/cms/' + CODOC_USER_CODE + '/subscriptions?without_token=1';
68 202
203 + // Add title parameter if search term exists
204 + if (searchTitle) {
205 + url += '&title=' + encodeURIComponent(searchTitle);
206 + }
207 +
69 208 fetch(url)
70 209 .then( res => res.json() )
71 210 .then( res => {
72 211 let list = [];
@@ -74,104 +213,173 @@
74 213 for ( var i = 0; i < res.subscriptions.length; i++ ) {
75 214 let info = {
76 215 value: res.subscriptions[i].code,
77 216 label: res.subscriptions[i].title,
217 + term: res.subscriptions[i].term,
218 + price: res.subscriptions[i].price,
219 + currency: res.subscriptions[i].currency
78 220 }
79 221 list[i] = info
80 222 }
81 223 }
82 - if (list.length) {
224 + if (list.length || searchTitle) {
83 225 this.subscriptionsFetched = list;
226 + this.setState({ filteredSubscriptions: list });
84 227 }
85 228 setAttributes( { fetching: false } )
86 229 })
87 230 }
88 -
231 +
232 + handleSearchChange(value) {
233 + this.setState({ searchTerm: value });
234 +
235 + // Debounce the API call
236 + clearTimeout(this.searchTimeout);
237 + this.searchTimeout = setTimeout(() => {
238 + this.fetchSubscriptions(value);
239 + }, 500);
240 + }
241 +
89 242 getShowPriceHelp( checked ) {
90 243 return checked ?
91 - __( 'する' ) :
92 - __( 'しない' );
244 + __( 'Enable','codoc' ) :
245 + __( 'Disable','codoc' );
93 246 }
94 247 getShowSupportHelp( checked ) {
95 248 return checked ?
96 - __( '受け付ける' ) :
97 - __( '受け付けない' );
249 + __( 'Accept' ,'codoc') :
250 + __( 'Do not accept' ,'codoc');
98 251 }
99 -
252 + getShowPaywalledSupportHelp( checked ) {
253 + return checked ?
254 + __( 'The paid part will be hidden upon access, but will be displayed after tapping "Pay to Read". Viewers can freely specify the amount to purchase based on the content. Please note that there may be cases where it is not purchased.' ,'codoc') :
255 + __( ' ' );
256 + }
257 + getStatusLimitedHelp( checked ) {
258 + return checked ?
259 + __( 'Unlisted' ,'codoc') :
260 + __( 'Published' ,'codoc');
261 + }
262 + getShowPayWithoutAccountButtonHelp( checked ) {
263 + return checked ?
264 + __( 'Viewers can purchase without a codoc account.' ,'codoc') :
265 + __( 'Viewers must log in to codoc to purchase.' ,'codoc');
266 + }
267 +
100 268 render() {
101 269 const {
102 - setAttributes,
270 + setAttributes: setBlockAttributes,
103 271 attributes: {
104 272 showPrice,
105 273 price,
106 274 limited,
107 275 limitedCount,
108 -
276 +
109 277 affiliateMode,
110 278 affiliateRate,
111 279
112 280 showSupport,
113 -
281 + showPaywalledSupport,
282 + showPayWithoutAccountButton,
283 + statusLimited,
114 284 subscriptions,
115 285 }
116 286 } = this.props;
287 + // 設定変更のたびに前回値として保存
288 + const setAttributes = (attrs) => {
289 + setBlockAttributes(attrs);
290 + saveLastUsedAttributes(Object.assign({}, this.props.attributes, attrs));
291 + };
117 292
118 293 const toggleShowPrice = () => setAttributes( { showPrice: ! showPrice } );
119 294 const toggleLimited = () => setAttributes( { limited: ! limited } );
295 + const toggleShowPaywalledSupport = () => setAttributes( { showPaywalledSupport: ! showPaywalledSupport } );
296 + const toggleStatusLimited = () => setAttributes( { statusLimited: ! statusLimited } );
120 297 const toggleAffiliateMode = () => setAttributes( { affiliateMode: ! affiliateMode } );
121 298 const toggleShowSupport = () => setAttributes( { showSupport: ! showSupport } );
122 -
299 + const toggleShowPayWithoutAccountButton = () => setAttributes( { showPayWithoutAccountButton: ! showPayWithoutAccountButton } );
300 +
123 301 const SubscriptionCheckBoxes = withState({
124 - checked_obj: Object.assign(new Object, subscriptions)
125 - })( ( { checked_obj , setState } ) => (
302 + checked_obj: Object.assign({}, subscriptions)
303 + })( ({ checked_obj, setState }) => (
304 + <div>
305 + {this.state.filteredSubscriptions.length === 0 ? (
306 + <p style={{ fontStyle: 'italic', color: '#666' }}>
307 + { this.state.searchTerm
308 + ? __('No plans found matching your search.','codoc')
309 + : __('No reader plans available.','codoc')
310 + }
311 + </p>
312 + ) : (
126 313 <ul>
127 - {
128 - this.subscriptionsFetched.map((v) => (
129 - <li><CheckboxControl
130 - className="check_items"
131 - label={v.label}
132 - checked={checked_obj[v.value]}
314 + {
315 + this.state.filteredSubscriptions.map((v) => {
316 + const isChecked = !!checked_obj[v.value];
317 + const checkedCount = Object.keys(checked_obj).length;
133 318
134 - onChange={ ( check ) => {
135 - check ? checked_obj[v.value] = true : delete checked_obj[v.value]
136 - setAttributes({subscriptions : checked_obj})
137 - setState({checked_obj})
138 - } }
139 - /></li>
140 - ) )
319 + return (
320 + <li key={v.value}>
321 + <CheckboxControl
322 + className="check_items"
323 + label={v.label}
324 + checked={isChecked}
325 + onChange={(check) => {
326 + // 追加する場合、5個以上は無効
327 + if (check && checkedCount >= 5) {
328 + return; // これ以上チェックできない
329 + }
330 +
331 + const newChecked = { ...checked_obj };
332 +
333 + if (check) {
334 + newChecked[v.value] = true;
335 + } else {
336 + delete newChecked[v.value];
337 + }
338 +
339 + setAttributes({ subscriptions: newChecked });
340 + setState({ checked_obj: newChecked });
341 + }}
342 + />
343 + </li>
344 + );
345 + })
141 346 }
142 347 </ul>
348 + )}
349 + </div>
143 350 ) )
144 351 const affiliateRateOptions = [
145 - { value: '0.0500', label:'販売価格の5%' },
146 - { value: '0.1000', label:'販売価格の10%' },
147 - { value: '0.1500', label:'販売価格の15%' },
148 - { value: '0.2000', label:'販売価格の20%' },
149 - { value: '0.2500', label:'販売価格の25%' },
150 - { value: '0.3000', label:'販売価格の30%' },
151 - { value: '0.3500', label:'販売価格の35%' },
152 - { value: '0.4000', label:'販売価格の40%' },
153 - { value: '0.4500', label:'販売価格の45%' },
154 - { value: '0.5000', label:'販売価格の50%' },
352 + { value: '0.0500', label:'5%' },
353 + { value: '0.1000', label:'10%' },
354 + { value: '0.1500', label:'15%' },
355 + { value: '0.2000', label:'20%' },
356 + { value: '0.2500', label:'25%' },
357 + { value: '0.3000', label:'30%' },
358 + { value: '0.3500', label:'35%' },
359 + { value: '0.4000', label:'40%' },
360 + { value: '0.4500', label:'45%' },
361 + { value: '0.5000', label:'50%' },
155 362 ];
156 363
157 364 return(
158 365 <InspectorControls key="CodocControls">
159 366
367 + <CodocLengthNotices />
368 +
160 369 <PanelBody>
161 370
162 371 <ToggleControl
163 - label={ __( '単体販売' ) }
372 + label={ __( 'individual sale','codoc' ) }
164 373 checked={ !! showPrice }
165 374 help={ this.getShowPriceHelp }
166 375 ref="showPrice"
167 376 onChange={ toggleShowPrice }
168 377 />
169 -
378 +
170 379 <div style={{ display: showPrice ? 'initial' : 'none' }}>
171 -
172 380 <RangeControl
173 - label={ __( '価格(円)' ) }
381 + label={ __('price','codoc') + ' ' + (CODOC_CURRENCY_DECIMAL_PLACES > 0 ? (price / 100).toFixed(CODOC_CURRENCY_DECIMAL_PLACES) : price) + ' ' + __(CODOC_CURRENCY_CODE) + __(showPaywalledSupport ? '【' + __('Displayed as the your suggested price','codoc') + '】' : '' ) }
174 382 value={ price }
175 383 initialPosition={ price }
176 384 onChange={ ( value ) => {
177 385 // do validate this
@@ -177,13 +385,21 @@
177 385 // do validate this
178 386 setAttributes({ price: value });
179 387 }}
180 388 min="100"
181 - max="50000"
389 + max={ CODOC_ACCOUNT_IS_PRO == 1 ? 100000 : 50000 }
182 390 /><br />
183 -
391 +
184 392 <ToggleControl
185 - label={ __( '数量限定販売' ) }
393 + label={ __( 'Pay-what-you-want','codoc' ) }
394 + checked={ !! showPaywalledSupport }
395 + help={ this.getShowPaywalledSupportHelp }
396 + onChange={ toggleShowPaywalledSupport }
397 + />
398 +
399 + <div style={{ display: showPaywalledSupport ? 'none' : 'initial' }}>
400 + <ToggleControl
401 + label={ __( 'Limited quantity sale','codoc' ) }
186 402 checked={ !! limited }
187 403 onChange={ toggleLimited }
188 404 />
189 405
@@ -188,9 +404,9 @@
188 404 />
189 405
190 406 <div style={{ display: limited ? 'initial' : 'none' }}>
191 407 <RangeControl
192 - label={ __( '限定数' ) }
408 + label={ __( 'Limited quantity','codoc' ) }
193 409 value={ limitedCount }
194 410 onChange={ ( value ) => {
195 411 // do validate this
196 412 setAttributes({ limitedCount: value });
@@ -195,15 +411,15 @@
195 411 // do validate this
196 412 setAttributes({ limitedCount: value });
197 413 }}
198 414 initialPosition={ limitedCount }
199 - min="1"
415 + min="0"
200 416 max="100"
201 417 /><br />
202 418 </div>
203 -
419 +
204 420 <ToggleControl
205 - label={ __( 'アフィリエイト' ) }
421 + label={ __( 'Affiliate','codoc' ) }
206 422 checked={ !! affiliateMode }
207 423 onChange={ toggleAffiliateMode }
208 424 />
209 425
@@ -208,33 +424,72 @@
208 424 />
209 425
210 426 <div style={{ display: affiliateMode ? 'initial' : 'none' }}>
211 427 <SelectControl
212 - label={ __( '料率' ) }
213 - description={ __( '購入者を対象に指定した料率でアフィリエイトをオファーできます') }
428 + label={ __( 'Rate' , 'codoc') }
429 + description={ __( 'You can offer affiliate marketing at a specified rate for purchasers.', 'codoc') }
214 430 options={ affiliateRateOptions }
215 431 value={ affiliateRate }
216 432 onChange={ ( value ) => {
217 433 setAttributes( { affiliateRate: value } );
218 - }}/><br />
434 + }}/><br />
219 435 </div>
220 -
436 +
221 437 </div>
222 -
438 + </div>
439 +
440 + <div style={{ display: showPaywalledSupport ? 'none' : 'initial' }}>
223 441 <ToggleControl
224 - label={ __( 'サポート' ) }
442 + label={ __( 'Tipping', 'codoc') }
225 443 checked={ !! showSupport }
226 444 value="1"
227 445 onChange={ toggleShowSupport }
228 446 help={ this.getShowSupportHelp }
229 447 />
230 -
231 - <label>サブスクリプション</label>
448 + </div>
449 +
450 + <div style={{ display: 'initial' }}>
451 + <ToggleControl
452 + label={ __( 'Guest purchase', 'codoc') }
453 + checked={ !! showPayWithoutAccountButton }
454 + value="1"
455 + onChange={ toggleShowPayWithoutAccountButton }
456 + help={ this.getShowPayWithoutAccountButtonHelp }
457 + />
458 + </div>
459 +
460 + <div style={{ display: 'initial' }}>
461 + <ToggleControl
462 + label={ __( 'Unlisted','codoc' ) }
463 + checked={ !! statusLimited }
464 + value="1"
465 + onChange={ toggleStatusLimited }
466 + help={ this.getStatusLimitedHelp }
467 + />
468 + </div>
469 +
470 + <div class="codoc-subscription-title">
471 + <label>
472 + { __('Reader Plans','codoc') }
473 + </label>
232 474 <a
233 475 href={ CODOC_URL + '/me/subscriptions'}
234 - target="_blank">➕</a>
476 + target="_blank" class="codoc-subscription-add"
477 + >
478 + { __('Add','codoc') }
479 + </a>
480 + </div>
481 +
482 + <TextControl
483 + label={ __('Search Plans','codoc') }
484 + value={ this.state.searchTerm }
485 + onChange={ this.handleSearchChange }
486 + placeholder={ __('Enter title to search...','codoc') }
487 + />
488 +
235 489 <SubscriptionCheckBoxes />
236 490
491 +
237 492 </PanelBody>
238 493 </InspectorControls>
239 494 );
240 495 }
@@ -243,22 +498,28 @@
243 498 class EditBlockContent extends Component {
244 499 constructor() {
245 500 super( ...arguments );
246 501 // デフォルト値
502 + const bd = OPTIONS.codoc_block_defaults || {};
503 + const lu = loadLastUsedAttributes();
504 + const d = (key, fallback) => bd.hasOwnProperty(key) ? bd[key] : (lu.hasOwnProperty(key) ? lu[key] : fallback);
247 505 this.props.setAttributes({ version: CODOC_PLUGIN_VERSION });
248 - this.props.setAttributes({ showPrice: this.props.attributes.showPrice == null ? true : this.props.attributes.showPrice });
249 - this.props.setAttributes({ price: this.props.attributes.price == null ? 100 : this.props.attributes.price });
250 - this.props.setAttributes({ limited: this.props.attributes.limited == null ? false : this.props.attributes.limited });
251 - this.props.setAttributes({ limitedCount: this.props.attributes.limitedCount == null ? 10 : this.props.attributes.limitedCount });
252 - this.props.setAttributes({ affiliateMode: this.props.attributes.affiliateMode == null ? false : this.props.attributes.affiliateMode });
253 - this.props.setAttributes({ affiliateRate: this.props.attributes.affiliateRate == null ? '0.0500' : this.props.attributes.affiliateRate });
254 - this.props.setAttributes({ showSupport: this.props.attributes.showSupport == null ? false : this.props.attributes.showSupport });
255 - this.props.setAttributes({ subscriptions: this.props.attributes.subscriptions == null ? {} : this.props.attributes.subscriptions });
506 + this.props.setAttributes({ showPrice: this.props.attributes.showPrice == null ? d('showPrice', true) : this.props.attributes.showPrice });
507 + this.props.setAttributes({ price: this.props.attributes.price == null ? d('price', 500) : this.props.attributes.price });
508 + this.props.setAttributes({ limited: this.props.attributes.limited == null ? d('limited', false) : this.props.attributes.limited });
509 + this.props.setAttributes({ limitedCount: this.props.attributes.limitedCount == null ? d('limitedCount', 10) : this.props.attributes.limitedCount });
510 + this.props.setAttributes({ affiliateMode: this.props.attributes.affiliateMode == null ? d('affiliateMode', false) : this.props.attributes.affiliateMode });
511 + this.props.setAttributes({ affiliateRate: this.props.attributes.affiliateRate == null ? d('affiliateRate', '0.0500') : this.props.attributes.affiliateRate });
512 + this.props.setAttributes({ showSupport: this.props.attributes.showSupport == null ? d('showSupport', false) : this.props.attributes.showSupport });
513 + this.props.setAttributes({ showPaywalledSupport: this.props.attributes.showPaywalledSupport == null ? d('showPaywalledSupport', false) : this.props.attributes.showPaywalledSupport });
514 + this.props.setAttributes({ statusLimited: this.props.attributes.statusLimited == null ? d('statusLimited', false) : this.props.attributes.statusLimited });
515 + this.props.setAttributes({ showPayWithoutAccountButton: this.props.attributes.showPayWithoutAccountButton == null ? d('showPayWithoutAccountButton', true) : this.props.attributes.showPayWithoutAccountButton });
516 + this.props.setAttributes({ subscriptions: this.props.attributes.subscriptions == null ? d('subscriptions', {}) : this.props.attributes.subscriptions });
256 517
257 518 this.onChangeInput = this.onChangeInput.bind( this );
258 519 this.onKeyDown = this.onKeyDown.bind( this );
259 520 this.state = {
260 - defaultText: __( 'この続きをみるには' ),
521 + defaultText: __( 'To continue reading, ...','codoc' ),
261 522 };
262 523 }
263 524 onChangeInput( event ) {
264 525 this.setState( {
@@ -274,9 +535,9 @@
274 535 if ( keyCode === ENTER ) {
275 536 insertBlocksAfter( [ createBlock( getDefaultBlockName() ) ] );
276 537 }
277 538 }
278 -
539 +
279 540 render() {
280 541 const {
281 542 attributes: {
282 543 customText,
@@ -308,10 +569,10 @@
308 569 };
309 570
310 571
311 572 registerBlockType( 'codoc/codoc-block', {
312 - title: __( 'codoc' ),
313 - description: __( 'このブロックから下のブロックは認証されたcodocユーザーのみが閲覧できる有料エリアとなります。' ),
573 + title: __( 'codoc' ,'codoc'),
574 + description: __( 'The area from this block down is a paid area that only authenticated codoc users can view.','codoc' ),
314 575 icon,
315 576 category: 'layout',
316 577 supports: {
317 578 customClassName: false,
@@ -319,11 +580,11 @@
319 580 html: false,
320 581 multiple: false,
321 582 },
322 583 keywords: [
323 - __( 'codoc Block' ),
324 - __( 'plugin for codoc' ),
325 - __( 'codoc-block' ),
584 + __( 'codoc Block' ,'codoc'),
585 + __( 'plugin for codoc' ,'codoc'),
586 + __( 'codoc-block' ,'codoc'),
326 587 ],
327 588 attributes: {
328 589 showPrice: {
329 590 type: 'boolean',
@@ -352,8 +613,20 @@
352 613 showSupport: {
353 614 type: 'boolean',
354 615 default: null,
355 616 },
617 + showPaywalledSupport: {
618 + type: 'boolean',
619 + default: null,
620 + },
621 + statusLimited: {
622 + type: 'boolean',
623 + default: null,
624 + },
625 + showPayWithoutAccountButton: {
626 + type: 'boolean',
627 + default: null,
628 + },
356 629 subscriptions: {
357 630 type: 'object',
358 631 default: null,
359 632 },
@@ -365,11 +638,11 @@
365 638 type: 'string',
366 639 default: null,
367 640 },
368 641 },
369 -
642 +
370 643 edit: EditBlockContent,
371 -
644 +
372 645 save: function( props ) {
373 646 const {
374 647 setAttributes,
375 648 attributes: {