PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.11
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.11
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / message-thread / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.11, at blocks/message-thread/index.js

183 lines 13.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 const el = window.wp.element.createElement;
3 const { registerBlockType } = window.wp.blocks;
4 const { InspectorControls, useBlockProps, PanelColorSettings } = window.wp.blockEditor;
5 const { PanelBody, RangeControl, ToggleControl, TextControl, SelectControl, Button } = window.wp.components;
6 const { __ } = window.wp.i18n;
7
8 var _tc, _tv;
9 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
10 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
11
12 // ── Renderer (opts.inlineTypo = true for deprecated save) ────────────────
13 function renderThread( a, opts ) {
14 opts = opts || {};
15 var it = opts.inlineTypo;
16 var messages = a.messages || [];
17 var R = a.bubbleRadius;
18
19 return el( 'div', { className: 'bkbg-mt-thread', style: { display: 'flex', flexDirection: 'column', gap: 16, padding: '20px 16px' } },
20 messages.map( function( msg, mi ) {
21 var isSelf = msg.side === 'self';
22 var senderSt = { color: a.tsColor, paddingLeft: isSelf ? 0 : 4, paddingRight: isSelf ? 4 : 0 };
23 if (it) { senderSt.fontSize = (a.senderNameFontSize || 11); senderSt.fontWeight = 600; }
24 var bubbleSt = {
25 background: isSelf ? a.selfBg : a.otherBg,
26 color: isSelf ? a.selfText : a.otherText,
27 padding: '10px 14px',
28 borderRadius: isSelf
29 ? R + 'px ' + R + 'px 4px ' + R + 'px'
30 : R + 'px ' + R + 'px ' + R + 'px 4px',
31 boxShadow: isSelf ? 'none' : '0 1px 3px rgba(0,0,0,0.08)',
32 wordBreak: 'break-word',
33 };
34 if (it) { bubbleSt.fontSize = a.fontSize + 'px'; bubbleSt.lineHeight = (a.lineHeight || 1.5); }
35 var tsSt = { color: a.tsColor, paddingLeft: isSelf ? 0 : 4, paddingRight: isSelf ? 4 : 0 };
36 if (it) { tsSt.fontSize = (a.timestampFontSize || 11); }
37
38 return el( 'div', {
39 key: mi,
40 className: 'bkbg-mt-row',
41 style: { display: 'flex', flexDirection: isSelf ? 'row-reverse' : 'row', alignItems: 'flex-end', gap: 10 }
42 },
43 a.showAvatars && el( 'div', {
44 className: 'bkbg-mt-avatar',
45 style: {
46 width: 36, height: 36, borderRadius: '50%', flexShrink: 0,
47 background: msg.avatarColor || ( isSelf ? a.selfBg : '#94a3b8' ),
48 display: 'flex', alignItems: 'center', justifyContent: 'center',
49 fontWeight: 700, fontSize: 14, color: '#ffffff',
50 }
51 }, ( msg.avatar || msg.sender || '?' ).charAt( 0 ).toUpperCase() ),
52
53 el( 'div', { className: 'bkbg-mt-bubble-col', style: { display: 'flex', flexDirection: 'column', gap: 4, maxWidth: '70%', alignItems: isSelf ? 'flex-end' : 'flex-start' } },
54 a.showSenderNames && el( 'span', { className: it ? undefined : 'bkbg-mt-sender', style: senderSt }, msg.sender ),
55 el( 'div', { className: 'bkbg-mt-bubble', style: bubbleSt }, msg.text ),
56 a.showTimestamps && msg.time && el( 'span', { className: it ? undefined : 'bkbg-mt-time', style: tsSt }, msg.time ),
57 ),
58 );
59 } )
60 );
61 }
62
63 function updMsg( setAttributes, messages, mi, field, val ) {
64 setAttributes( { messages: messages.map( ( m, i ) => i === mi ? { ...m, [field]: val } : m ) } );
65 }
66
67 // ── Block ─────────────────────────────────────────────────────────────────
68 registerBlockType( 'blockenberg/message-thread', {
69 deprecated: [{
70 save: function ( { attributes: a } ) {
71 var blockProps = useBlockProps.save( { className: 'bkbg-mt-wrap' } );
72 return el( 'div', blockProps,
73 a.showTitle && a.title ? el( 'h3', { className: 'bkbg-mt-title', style: { color: a.titleColor, margin: '0 0 0', padding: '16px 16px 0', fontSize: (a.titleSize || 16), fontWeight: (a.titleFontWeight || 700) } }, a.title ) : null,
74 el( 'div', { className: 'bkbg-mt-container', style: { background: a.bgColor, borderRadius: 12, maxWidth: a.maxWidth + 'px', margin: '0 auto', overflow: 'hidden' } },
75 renderThread( a, { inlineTypo: true } ),
76 ),
77 );
78 },
79 }],
80 edit: function ( props ) {
81 const { attributes: a, setAttributes } = props;
82 var blockProps = useBlockProps((function () {
83 var _tvf = getTypoCssVars();
84 var s = {};
85 Object.assign(s, _tvf(a.titleTypo, '--bkbg-mt-tt-'));
86 Object.assign(s, _tvf(a.bodyTypo, '--bkbg-mt-bd-'));
87 Object.assign(s, _tvf(a.metaTypo, '--bkbg-mt-mt-'));
88 return { className: 'bkbg-mt-wrap', style: s };
89 })());
90
91 return el( 'div', blockProps,
92 el( InspectorControls, {},
93
94 el( PanelBody, { title: __( 'Settings', 'blockenberg' ), initialOpen: true },
95 el( TextControl, { label: __( 'Title (optional)', 'blockenberg' ), value: a.title, onChange: v => setAttributes( { title: v } ) } ),
96 el( ToggleControl, { label: __( 'Show Title', 'blockenberg' ), checked: a.showTitle, onChange: v => setAttributes( { showTitle: v } ) } ),
97 el( ToggleControl, { label: __( 'Show Avatars', 'blockenberg' ), checked: a.showAvatars, onChange: v => setAttributes( { showAvatars: v } ) } ),
98 el( ToggleControl, { label: __( 'Show Sender Names', 'blockenberg' ),checked: a.showSenderNames, onChange: v => setAttributes( { showSenderNames: v } ) } ),
99 el( ToggleControl, { label: __( 'Show Timestamps', 'blockenberg' ), checked: a.showTimestamps, onChange: v => setAttributes( { showTimestamps: v } ) } ),
100 ),
101
102 el( PanelBody, { title: __( 'Style', 'blockenberg' ), initialOpen: false },
103 el( RangeControl, { label: __( 'Bubble Radius', 'blockenberg' ), value: a.bubbleRadius, onChange: v => setAttributes( { bubbleRadius: v } ), min: 4, max: 28 } ),
104 el( RangeControl, { label: __( 'Max Width', 'blockenberg' ), value: a.maxWidth, onChange: v => setAttributes( { maxWidth: v } ), min: 300, max: 1200, step: 20 } ),
105 ),
106
107 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
108 el( getTypoControl(), { label: __( 'Title', 'blockenberg' ), value: a.titleTypo, onChange: function (v) { setAttributes({ titleTypo: v }); } }),
109 el( getTypoControl(), { label: __( 'Body', 'blockenberg' ), value: a.bodyTypo, onChange: function (v) { setAttributes({ bodyTypo: v }); } }),
110 el( getTypoControl(), { label: __( 'Meta', 'blockenberg' ), value: a.metaTypo, onChange: function (v) { setAttributes({ metaTypo: v }); } })
111 ),
112 el( PanelColorSettings, {
113 title: __( 'Colors', 'blockenberg' ), initialOpen: false,
114 colorSettings: [
115 { label: __( 'Background', 'blockenberg' ), value: a.bgColor, onChange: v => setAttributes( { bgColor: v || '#f1f5f9' } ) },
116 { label: __( 'Self Bubble', 'blockenberg' ), value: a.selfBg, onChange: v => setAttributes( { selfBg: v || '#6366f1' } ) },
117 { label: __( 'Self Text', 'blockenberg' ), value: a.selfText, onChange: v => setAttributes( { selfText: v || '#ffffff' } ) },
118 { label: __( 'Other Bubble', 'blockenberg' ), value: a.otherBg, onChange: v => setAttributes( { otherBg: v || '#ffffff' } ) },
119 { label: __( 'Other Text', 'blockenberg' ), value: a.otherText, onChange: v => setAttributes( { otherText: v || '#111827' } ) },
120 { label: __( 'Timestamp', 'blockenberg' ), value: a.tsColor, onChange: v => setAttributes( { tsColor: v || '#94a3b8' } ) },
121 { label: __( 'Title', 'blockenberg' ), value: a.titleColor, onChange: v => setAttributes( { titleColor: v || '#111827' } ) },
122 ]
123 } ),
124
125 el( PanelBody, { title: __( 'Messages', 'blockenberg' ), initialOpen: false },
126 el( Button, { variant: 'secondary', style: { marginBottom: 10 }, onClick: () => setAttributes( { messages: [ ...( a.messages || [] ), { sender: 'Alice', side: 'other', text: 'New message…', time: '', avatar: 'A', avatarColor: '#10b981' } ] } ) }, __( '+ Add Message', 'blockenberg' ) ),
127 a.messages.map( ( msg, mi ) =>
128 el( PanelBody, { key: mi, title: `${ msg.sender }: ${ ( msg.text || '' ).slice( 0, 24 ) }${ ( msg.text || '' ).length > 24 ? '' : '' }`, initialOpen: false },
129 el( TextControl, { label: __( 'Sender Name', 'blockenberg' ), value: msg.sender, onChange: v => updMsg( setAttributes, a.messages, mi, 'sender', v ) } ),
130 el( SelectControl, {
131 label: __( 'Side', 'blockenberg' ),
132 value: msg.side,
133 options: [ { label: __( 'Other (left)', 'blockenberg' ), value: 'other' }, { label: __( 'Self (right)', 'blockenberg' ), value: 'self' } ],
134 onChange: v => updMsg( setAttributes, a.messages, mi, 'side', v ),
135 } ),
136 el( 'div', { style: { marginBottom: 8 } },
137 el( 'label', { style: { fontSize: 12, fontWeight: 600, display: 'block', marginBottom: 4 } }, __( 'Message', 'blockenberg' ) ),
138 el( 'textarea', {
139 value: msg.text,
140 rows: 3,
141 onChange: e => updMsg( setAttributes, a.messages, mi, 'text', e.target.value ),
142 style: { width: '100%', fontSize: 12, padding: '6px 8px', borderRadius: 4, border: '1px solid #d1d5db', resize: 'vertical', boxSizing: 'border-box' }
143 } ),
144 ),
145 el( TextControl, { label: __( 'Time', 'blockenberg' ), value: msg.time, onChange: v => updMsg( setAttributes, a.messages, mi, 'time', v ) } ),
146 el( TextControl, { label: __( 'Avatar Initial', 'blockenberg' ), value: msg.avatar, onChange: v => updMsg( setAttributes, a.messages, mi, 'avatar', v ) } ),
147 el( 'div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 } },
148 el( 'label', { style: { fontSize: 12 } }, __( 'Avatar Color', 'blockenberg' ) ),
149 el( 'input', { type: 'color', value: msg.avatarColor || '#6b7280', style: { width: 40, height: 28, border: 'none', borderRadius: 4, cursor: 'pointer' }, onChange: e => updMsg( setAttributes, a.messages, mi, 'avatarColor', e.target.value ) } ),
150 ),
151 el( Button, { isDestructive: true, isSmall: true, onClick: () => setAttributes( { messages: a.messages.filter( ( _, x ) => x !== mi ) } ) }, __( 'Remove', 'blockenberg' ) ),
152 )
153 ),
154 ),
155 ),
156
157 a.showTitle && a.title && el( 'h3', { className: 'bkbg-mt-title', style: { color: a.titleColor, margin: '0 0 0', padding: '16px 16px 0' } }, a.title ),
158
159 el( 'div', { className: 'bkbg-mt-container', style: { background: a.bgColor, borderRadius: 12, maxWidth: a.maxWidth + 'px', margin: '0 auto', overflow: 'hidden' } },
160 renderThread( a ),
161 ),
162 );
163 },
164
165 save: function ( { attributes: a } ) {
166 var blockProps = useBlockProps.save((function () {
167 var _tvf = getTypoCssVars();
168 var s = {};
169 Object.assign(s, _tvf(a.titleTypo, '--bkbg-mt-tt-'));
170 Object.assign(s, _tvf(a.bodyTypo, '--bkbg-mt-bd-'));
171 Object.assign(s, _tvf(a.metaTypo, '--bkbg-mt-mt-'));
172 return { className: 'bkbg-mt-wrap', style: s };
173 })());
174 return el( 'div', blockProps,
175 a.showTitle && a.title ? el( 'h3', { className: 'bkbg-mt-title', style: { color: a.titleColor, margin: '0 0 0', padding: '16px 16px 0' } }, a.title ) : null,
176 el( 'div', { className: 'bkbg-mt-container', style: { background: a.bgColor, borderRadius: 12, maxWidth: a.maxWidth + 'px', margin: '0 auto', overflow: 'hidden' } },
177 renderThread( a ),
178 ),
179 );
180 },
181 } );
182 }() );
183