aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/nodes/trails/PresBox.scss28
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx402
2 files changed, 236 insertions, 194 deletions
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index 5fc356299..dd0007d82 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -1,5 +1,33 @@
@import '../../global/globalCssVariables.module.scss';
+.pres-chat {
+ // padding: 8px;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ // display: flex;
+ // align-items: center;
+ // gap: 16px;
+}
+
+.pres-chatbox-container {
+ padding: 16px;
+ outline: 1px solid #999999;
+ border-radius: 16px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.pres-chatbox {
+ outline: none;
+ border: none;
+ resize: none;
+ font-family: Verdana, Geneva, sans-serif;
+ background-color: transparent;
+ overflow-y: hidden;
+}
+
.presBox-cont {
cursor: auto;
position: absolute;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index ba80facce..7d78d4648 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -38,7 +38,7 @@ import './PresBox.scss';
import ReactLoading from 'react-loading';
import { PresEffect, PresEffectDirection, PresMovement, PresStatus } from './PresEnums';
import ReactTextareaAutosize from 'react-textarea-autosize';
-import { Dropdown, IconButton, Type } from 'browndash-components';
+import { Button, Dropdown, IconButton, Type } from 'browndash-components';
import { BiMicrophone, BiX } from 'react-icons/bi';
import { AiOutlineSend } from 'react-icons/ai';
import { gptSlideProperties, gptTrailSlideCustomization } from '../../../apis/gpt/customization';
@@ -131,7 +131,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
public setChatActive = (active: boolean) => {
- this.chatActive = active;
+ this.toggleProperties();
};
@action
@@ -307,7 +307,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@action
customizeWithGPT = async (input: string) => {
- console.log('Slide to modify', this.slideToModify);
// const testInput = 'change title to Customized Slide, transition for 2.3s with fade in effect';
// if (!this.slideToModify) return;
this.setIsRecording(false);
@@ -315,7 +314,16 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
let currSlideProperties: { [key: string]: any } = {};
for (const key of gptSlideProperties) {
- currSlideProperties[key] = this.activeItem[key];
+ if (this.activeItem[key]) {
+ currSlideProperties[key] = this.activeItem[key];
+ } else {
+ // default values
+ if (key === 'presentation_transition') {
+ currSlideProperties[key] = 500;
+ } else if (key === 'config_zoom') {
+ currSlideProperties[key] = 1.0;
+ }
+ }
}
console.log('current slide props', currSlideProperties);
@@ -847,8 +855,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
navigateToActiveItem = (afterNav?: () => void) => {
const activeItem: Doc = this.activeItem;
console.log('active item', activeItem);
- // GPT update
- this.slideToModify = activeItem;
+
const targetDoc: Doc = this.targetDoc;
const finished = () => {
afterNav?.();
@@ -1797,6 +1804,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
return null;
}
+
+ @computed get gptDropdown() {
+ const activeItem = this.activeItem;
+ return <div></div>;
+ }
+
@computed get transitionDropdown() {
const activeItem = this.activeItem;
const preseEffect = (effect: PresEffect) => (
@@ -1829,19 +1842,77 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const zoom = NumCast(activeItem.config_zoom, 1) * 100;
const effect = activeItem.presentation_effect ? activeItem.presentation_effect : PresMovement.None;
return (
- <div
- className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
- onPointerDown={StopEvent}
- onPointerUp={StopEvent}
- onClick={action(e => {
- e.stopPropagation();
- this._openMovementDropdown = false;
- this._openEffectDropdown = false;
- this._openBulletEffectDropdown = false;
- })}>
- <div className="ribbon-box">
- Movement
- {/* <Dropdown
+ <>
+ {/* GPT Component */}
+ <div style={{ padding: '8px' }}>
+ Customize with GPT
+ <div className="pres-chat">
+ <div className="pres-chatbox-container">
+ <ReactTextareaAutosize
+ ref={r => (this._inputref = r)}
+ minRows={1}
+ placeholder="Customize..."
+ className="pres-chatbox"
+ autoFocus={true}
+ value={this.chatInput}
+ onChange={e => {
+ this.setChatInput(e.target.value);
+ }}
+ onKeyDown={e => {
+ this.stopDictation(true);
+ e.stopPropagation();
+ }}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={this.isRecording ? '#2bcaff' : StrCast(Doc.UserDoc().userVariantColor)}
+ tooltip="Record"
+ icon={<BiMicrophone size={'16px'} />}
+ onClick={() => {
+ if (!this.isRecording) {
+ this.recordDictation();
+ } else {
+ this.stopDictation(true);
+ }
+ }}
+ />
+ </div>
+ <Button
+ style={{ alignSelf: 'flex-end' }}
+ text="Send"
+ type={Type.TERT}
+ icon={this.isLoading ? <ReactLoading type="spin" color={'#ffffff'} width={20} height={20} /> : <AiOutlineSend />}
+ iconPlacement="right"
+ color={StrCast(Doc.UserDoc().userVariantColor)}
+ onClick={() => {
+ this.customizeWithGPT(this.chatInput);
+ }}
+ />
+
+ {/* <IconButton
+ type={Type.TERT}
+ color={!this.isLoading ? StrCast(Doc.UserDoc().userVariantColor) : '#7c7c7c'}
+ tooltip="Send"
+ icon={<AiOutlineSend size={'16px'} />}
+ onClick={() => {
+ this.customizeWithGPT(this.chatInput);
+ }}
+ /> */}
+ </div>
+ </div>
+ <div
+ className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
+ onPointerDown={StopEvent}
+ onPointerUp={StopEvent}
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openMovementDropdown = false;
+ this._openEffectDropdown = false;
+ this._openBulletEffectDropdown = false;
+ })}>
+ <div className="ribbon-box">
+ Movement
+ {/* <Dropdown
color={StrCast(Doc.UserDoc().userColor)}
formLabel={'Type'}
closeOnSelect={true}
@@ -1854,142 +1925,143 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
type={Type.TERT}
fillWidth
/> */}
- <div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openMovementDropdown = !this._openMovementDropdown;
- })}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userVariantColor,
- borderBottomLeftRadius: this._openMovementDropdown ? 0 : 5,
- border: this._openMovementDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
- }}>
- {this.movementName(activeItem)}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
<div
- className="presBox-dropdownOptions"
- id={'presBoxMovementDropdown'}
- onPointerDown={StopEvent}
+ className="presBox-dropdown"
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openMovementDropdown = !this._openMovementDropdown;
+ })}
style={{
color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
- display: this._openMovementDropdown ? 'grid' : 'none',
+ background: SettingsManager.userVariantColor,
+ borderBottomLeftRadius: this._openMovementDropdown ? 0 : 5,
+ border: this._openMovementDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
}}>
- {presMovement(PresMovement.None)}
- {presMovement(PresMovement.Center)}
- {presMovement(PresMovement.Zoom)}
- {presMovement(PresMovement.Pan)}
- {presMovement(PresMovement.Jump)}
- </div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
- <div className="presBox-subheading">Zoom (% screen filled)</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly={true} value={zoom} onChange={e => this.updateZoom(e.target.value)} />%
+ {this.movementName(activeItem)}
+ <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div
+ className="presBox-dropdownOptions"
+ id={'presBoxMovementDropdown'}
+ onPointerDown={StopEvent}
+ style={{
+ color: SettingsManager.userColor,
+ background: SettingsManager.userBackgroundColor,
+ display: this._openMovementDropdown ? 'grid' : 'none',
+ }}>
+ {presMovement(PresMovement.None)}
+ {presMovement(PresMovement.Center)}
+ {presMovement(PresMovement.Zoom)}
+ {presMovement(PresMovement.Pan)}
+ {presMovement(PresMovement.Jump)}
+ </div>
</div>
- <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), 0.1)}>
- <FontAwesomeIcon icon={'caret-up'} />
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? 'inline-flex' : 'none' }}>
+ <div className="presBox-subheading">Zoom (% screen filled)</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
+ <input className="presBox-input" type="number" readOnly={true} value={zoom} onChange={e => this.updateZoom(e.target.value)} />%
</div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), -0.1)}>
- <FontAwesomeIcon icon={'caret-down'} />
+ <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), 0.1)}>
+ <FontAwesomeIcon icon={'caret-up'} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.updateZoom(String(zoom), -0.1)}>
+ <FontAwesomeIcon icon={'caret-down'} />
+ </div>
</div>
</div>
- </div>
- {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Transition Time</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly={true} value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s
- </div>
- <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), 1000)}>
- <FontAwesomeIcon icon={'caret-up'} />
+ {PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Transition Time</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
+ <input className="presBox-input" type="number" readOnly={true} value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} /> s
</div>
- <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), -1000)}>
- <FontAwesomeIcon icon={'caret-down'} />
+ <div className="ribbon-propertyUpDown" style={{ color: SettingsManager.userBackgroundColor, background: SettingsManager.userColor }}>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), 1000)}>
+ <FontAwesomeIcon icon={'caret-up'} />
+ </div>
+ <div className="ribbon-propertyUpDownItem" onClick={() => this.updateTransitionTime(String(transitionSpeed), -1000)}>
+ <FontAwesomeIcon icon={'caret-down'} />
+ </div>
</div>
</div>
+ {PresBox.inputter('0.1', '0.1', '100', transitionSpeed, true, this.updateTransitionTime)}
+ <div className={'slider-headers'}>
+ <div className="slider-text">Fast</div>
+ <div className="slider-text">Medium</div>
+ <div className="slider-text">Slow</div>
+ </div>
</div>
- {PresBox.inputter('0.1', '0.1', '100', transitionSpeed, true, this.updateTransitionTime)}
- <div className={'slider-headers'}>
- <div className="slider-text">Fast</div>
- <div className="slider-text">Medium</div>
- <div className="slider-text">Slow</div>
- </div>
- </div>
- <div className="ribbon-box">
- Effects
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Play Audio Annotation</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))}
- checked={BoolCast(activeItem.presPlayAudio)}
- />
- </div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Zoom Text Selections</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
- type="checkbox"
- onChange={() => (activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText))}
- checked={BoolCast(activeItem.presentation_zoomText)}
- />
- </div>
- <div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openEffectDropdown = !this._openEffectDropdown;
- })}
- style={{
- color: SettingsManager.userColor,
- background: SettingsManager.userVariantColor,
- borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5,
- border: this._openEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
- }}>
- {effect?.toString()}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div className="ribbon-box">
+ Effects
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Play Audio Annotation</div>
+ <input
+ className="presBox-checkbox"
+ style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
+ type="checkbox"
+ onChange={() => (activeItem.presPlayAudio = !BoolCast(activeItem.presPlayAudio))}
+ checked={BoolCast(activeItem.presPlayAudio)}
+ />
+ </div>
+ <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
+ <div className="presBox-subheading">Zoom Text Selections</div>
+ <input
+ className="presBox-checkbox"
+ style={{ margin: 10, border: `solid 1px ${SettingsManager.userColor}` }}
+ type="checkbox"
+ onChange={() => (activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText))}
+ checked={BoolCast(activeItem.presentation_zoomText)}
+ />
+ </div>
<div
- className="presBox-dropdownOptions"
- id={'presBoxMovementDropdown'}
+ className="presBox-dropdown"
+ onClick={action(e => {
+ e.stopPropagation();
+ this._openEffectDropdown = !this._openEffectDropdown;
+ })}
style={{
color: SettingsManager.userColor,
- background: SettingsManager.userBackgroundColor,
- display: this._openEffectDropdown ? 'grid' : 'none',
- }}
- onPointerDown={e => e.stopPropagation()}>
- {Object.values(PresEffect)
- .filter(v => isNaN(Number(v)))
- .map(effect => preseEffect(effect))}
+ background: SettingsManager.userVariantColor,
+ borderBottomLeftRadius: this._openEffectDropdown ? 0 : 5,
+ border: this._openEffectDropdown ? `solid 2px ${SettingsManager.userVariantColor}` : `solid 1px ${SettingsManager.userColor}`,
+ }}>
+ {effect?.toString()}
+ <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={'angle-down'} />
+ <div
+ className="presBox-dropdownOptions"
+ id={'presBoxMovementDropdown'}
+ style={{
+ color: SettingsManager.userColor,
+ background: SettingsManager.userBackgroundColor,
+ display: this._openEffectDropdown ? 'grid' : 'none',
+ }}
+ onPointerDown={e => e.stopPropagation()}>
+ {Object.values(PresEffect)
+ .filter(v => isNaN(Number(v)))
+ .map(effect => preseEffect(effect))}
+ </div>
</div>
- </div>
- <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
- <div className="presBox-subheading">Effect direction</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
- {StrCast(this.activeItem.presentation_effectDirection)}
+ <div className="ribbon-doubleButton" style={{ display: effect === PresEffectDirection.None ? 'none' : 'inline-flex' }}>
+ <div className="presBox-subheading">Effect direction</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SettingsManager.userColor}` }}>
+ {StrCast(this.activeItem.presentation_effectDirection)}
+ </div>
+ </div>
+ <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
+ {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+ {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+ {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+ {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+ {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
</div>
</div>
- <div className="effectDirection" style={{ display: effect === PresEffectDirection.None ? 'none' : 'grid', width: 40 }}>
- {presDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
- {presDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
- {presDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
- {presDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
- {presDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
- </div>
- </div>
- <div className="ribbon-final-box">
- <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
- Apply to all
+ <div className="ribbon-final-box">
+ <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
+ Apply to all
+ </div>
</div>
</div>
- </div>
+ </>
);
}
}
@@ -2764,65 +2836,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
} */}
</div>
{/* presbox chatbox */}
- {this.chatActive && (
- <div className="presBox-chatbox">
- <div style={{ alignSelf: 'flex-end' }}>
- {this.isLoading ? (
- <ReactLoading type="spin" color={StrCast(Doc.UserDoc().userVariantColor)} width={14} height={14} />
- ) : (
- <IconButton
- type={Type.PRIM}
- color={StrCast(Doc.UserDoc().userVariantColor)}
- tooltip="Close"
- icon={<BiX size={'16px'} />}
- onClick={() => {
- this.setChatActive(false);
- }}
- />
- )}
- </div>
- <ReactTextareaAutosize
- ref={r => (this._inputref = r)}
- minRows={3}
- placeholder="Customize..."
- className="pres-chatbox"
- autoFocus={true}
- value={this.chatInput}
- onChange={e => {
- this.setChatInput(e.target.value);
- }}
- onKeyDown={e => {
- this.stopDictation(true);
- e.stopPropagation();
- }}
- />
- {/* <input className="chatbox" placeholder="Customize..." value={this.chatInput} onChange={e => this.setChatInput(e.target.value)} /> */}
- <div style={{ alignSelf: 'flex-end', display: 'flex', gap: '8px' }}>
- <IconButton
- type={Type.TERT}
- color={this.isRecording ? 'red' : StrCast(Doc.UserDoc().userVariantColor)}
- tooltip="Record"
- icon={<BiMicrophone size={'16px'} />}
- onClick={() => {
- if (!this.isRecording) {
- this.recordDictation();
- } else {
- this.stopDictation(true);
- }
- }}
- />
- <IconButton
- type={Type.TERT}
- color={!this.isLoading ? StrCast(Doc.UserDoc().userVariantColor) : '#7c7c7c'}
- tooltip="Send"
- icon={<AiOutlineSend size={'16px'} />}
- onClick={() => {
- this.customizeWithGPT(this.chatInput);
- }}
- />
- </div>
- </div>
- )}
+ {this.chatActive && <div className="presBox-chatbox"></div>}
</div>
);
}