aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2025-02-06 14:37:19 -0500
committerbobzel <zzzman@gmail.com>2025-02-06 14:37:19 -0500
commita23e4c26d23224b56ec51d73b38adeb2b54fed6d (patch)
tree82365a8171d048a440cc2e5db3fa61497554c51a
parent382e09f606d94921dab460cc8c8564199bb0b70d (diff)
overhaul of presbox properties ui + fixing bugs with progressivize highlight expanding
-rw-r--r--src/client/views/PropertiesView.tsx70
-rw-r--r--src/client/views/nodes/trails/PresBox.scss36
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx591
3 files changed, 350 insertions, 347 deletions
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 42aa6782f..bed96f600 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -119,6 +119,7 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
// Pres Trails booleans:
@observable openPresTransitions: boolean = true;
@observable openPresProgressivize: boolean = false;
+ @observable openPresMedia: boolean = false;
@observable openPresVisibilityAndDuration: boolean = false;
@observable openAddSlide: boolean = false;
@observable openSlideOptions: boolean = false;
@@ -1936,74 +1937,74 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
</div>
</div>
{!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
+ <div className="propertiesView-section">
<div
- className="propertiesView-presentationTrails-title"
+ className="propertiesView-sectionTitle"
onPointerDown={action(() => {
- this.openPresTransitions = !this.openPresTransitions;
+ this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration;
})}
style={{
color: SnappingManager.userColor,
- backgroundColor: this.openPresTransitions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userVariantColor,
}}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Transitions
+ Visibility
<div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
+ <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
- {this.openPresTransitions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
+ {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibilityDurationDropdown}</div> : null}
</div>
)}
{!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
+ <div className="propertiesView-section">
<div
- className="propertiesView-presentationTrails-title"
+ className="propertiesView-sectionTitle"
onPointerDown={action(() => {
- this.openPresVisibilityAndDuration = !this.openPresVisibilityAndDuration;
+ this.openPresProgressivize = !this.openPresProgressivize;
})}
style={{
color: SnappingManager.userColor,
- backgroundColor: this.openPresVisibilityAndDuration ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userVariantColor,
}}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Visibility
+ Progressivize
<div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" />
+ <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
- {this.openPresVisibilityAndDuration ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.visibilityDurationDropdown}</div> : null}
+ {this.openPresProgressivize ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
</div>
)}
{!selectedItem ? null : (
- <div className="propertiesView-presentationTrails">
+ <div className="propertiesView-section">
<div
- className="propertiesView-presentationTrails-title"
+ className="propertiesView-sectionTitle"
onPointerDown={action(() => {
- this.openPresProgressivize = !this.openPresProgressivize;
+ this.openPresMedia = !this.openPresMedia;
})}
style={{
color: SnappingManager.userColor,
- backgroundColor: this.openPresProgressivize ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userVariantColor,
}}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon="rocket" /> &nbsp; Progressivize
+ Media
<div className="propertiesView-presentationTrails-title-icon">
- <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" />
+ <FontAwesomeIcon icon={this.openPresMedia ? 'caret-down' : 'caret-right'} size="lg" />
</div>
</div>
- {this.openPresProgressivize ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
+ {this.openPresMedia ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.mediaDropdown}</div> : null}
</div>
)}
{!selectedItem || (type !== DocumentType.VID && type !== DocumentType.AUDIO) ? null : (
- <div className="propertiesView-presentationTrails">
+ <div className="propertiesView-section">
<div
- className="propertiesView-presentationTrails-title"
+ className="propertiesView-sectionTitle"
onPointerDown={action(() => {
this.openSlideOptions = !this.openSlideOptions;
})}
style={{
color: SnappingManager.userColor,
- backgroundColor: this.openSlideOptions ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ backgroundColor: SnappingManager.userVariantColor,
}}>
- &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
+ {type === DocumentType.AUDIO ? 'file-audio' : 'file-video'}
<div className="propertiesView-presentationTrails-title-icon">
<FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" />
</div>
@@ -2011,6 +2012,25 @@ export class PropertiesView extends ObservableReactComponent<PropertiesViewProps
{this.openSlideOptions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null}
</div>
)}
+ {!selectedItem ? null : (
+ <div className="propertiesView-section">
+ <div
+ className="propertiesView-sectionTitle"
+ onPointerDown={action(() => {
+ this.openPresTransitions = !this.openPresTransitions;
+ })}
+ style={{
+ color: SnappingManager.userColor,
+ backgroundColor: SnappingManager.userVariantColor,
+ }}>
+ Transitions
+ <div className="propertiesView-presentationTrails-title-icon">
+ <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" />
+ </div>
+ </div>
+ {this.openPresTransitions ? <div className="propertiesView-presentationTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
+ </div>
+ )}
</div>
);
}
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
index a181687f8..e34e1b380 100644
--- a/src/client/views/nodes/trails/PresBox.scss
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -18,6 +18,7 @@
max-width: calc(100% - 25px);
width: 100%;
padding: 15px;
+ padding-left: 0px;
}
.pres-chat {
@@ -100,6 +101,14 @@
gap: 4px;
}
+.presBox-switches {
+ display: flex;
+ width: 100%;
+ > div {
+ width: 100%;
+ }
+}
+
.presBox-bezier-editor {
border: 1px solid rgb(221, 221, 221);
border-radius: 4px;
@@ -302,7 +311,7 @@
}
.presBox-toggles {
- display: flex;
+ display: flow;
overflow-x: auto;
}
@@ -387,7 +396,7 @@
font-size: 11;
font-weight: 400;
margin-top: 10px;
- max-width: min(100px, 25%);
+ max-width: min(85px, 25%);
width: 100%;
}
.presBox-springSlider {
@@ -567,20 +576,17 @@
}
.presBox-input {
- border: none;
background-color: transparent;
- width: 40;
- // padding: 8px;
- // border-radius: 4px;
- // width: 30;
- // height: 100%;
- // background: none;
- // border: none;
- // text-align: right;
+ text-align: center;
+ width: 100%;
+ height: 15px;
+ font-size: 10;
}
-
- .presBox-input:focus {
- outline: none;
+ .presBox-inputNumber {
+ border: none;
+ background-color: transparent;
+ width: 100%;
+ max-width: 25px;
}
.ribbon-frameSelector {
@@ -784,7 +790,7 @@
font-weight: 200;
height: 20;
background-color: $white;
- display: flex;
+ display: inline-flex;
color: $black;
border-radius: 5px;
width: max-content;
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 5dbf502d2..28afe1df4 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,4 +1,4 @@
-import { Button, Dropdown, DropdownType, IconButton, Size, Toggle, ToggleType, Type } from '@dash/components';
+import { Button, Dropdown, DropdownType, IconButton, Size, Type } from '@dash/components';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@mui/material';
import Slider from '@mui/material/Slider';
@@ -101,8 +101,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
@observable _forceKeyEvents: boolean = false;
@observable _showAIGallery = false;
- @observable _showBezierEditor = false;
- @observable _showSpringEditor = false;
@observable _showPreview = true;
@observable _easeDropdownVal = 'ease';
@@ -150,8 +148,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
setAnimationChat = action((input: string) => { this._animationChat = input; }); // prettier-ignore
setIsLoading = action((input?: boolean) => { this._isLoading = !!input; }); // prettier-ignore
setIsRecording = action((input: boolean) => { this._isRecording = input; }); // prettier-ignore
- setBezierEditorVisibility = action((visible: boolean) => { this._showBezierEditor = visible; }); // prettier-ignore
- setSpringEditorVisibility = action((visible: boolean) => { this._showSpringEditor = visible; }); // prettier-ignore
setShowAIGalleryVisibilty = action((visible: boolean) => { this._showAIGallery = visible; }); // prettier-ignore
setBezierControlPoints = action((newPoints: { p1: number[]; p2: number[] }) => {
this.setEaseFunc(this.activeItem, `cubic-bezier(${newPoints.p1[0]}, ${newPoints.p1[1]}, ${newPoints.p2[0]}, ${newPoints.p2[1]})`);
@@ -390,7 +386,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (!first) {
const presBulletTiming = 500; // bcz: hardwired for now
Doc.linkFollowUnhighlight();
- Doc.HighlightDoc(listItemDoc);
+ Doc.linkFollowHighlight(listItemDoc);
listItemDoc.presentation_effect = this.activeItem.presBulletEffect;
listItemDoc.presentation_transition = presBulletTiming;
listItemDoc.opacity = undefined;
@@ -1612,20 +1608,22 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</Tooltip>
</div>
{[DocumentType.AUDIO, DocumentType.VID].includes(targetType as DocumentType) ? null : (
- <>
- <div className="ribbon-doubleButton">
- <div className="presBox-subheading">Slide Duration</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}` }}>
- <input className="presBox-input" type="number" readOnly value={duration} onKeyDown={e => e.stopPropagation()} onChange={e => this.updateDurationTime(e.target.value)} /> s
+ <div className="ribbon-doubleButton">
+ <Tooltip title={<div>How long to view the slide before transitioning to the next slide</div>}>
+ <div className="presBox-subheading">DURATION</div>
+ </Tooltip>
+ <div className="presBox-subheading-slider">
+ {PresBox.inputter('0.1', '0.1', '10', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)}
+ <div className="slider-headers">
+ <div className="slider-text">Short</div>
+ <div className="slider-text">Long</div>
</div>
</div>
- {PresBox.inputter('0.1', '0.1', '20', duration, targetType !== DocumentType.AUDIO, this.updateDurationTime)}
- <div className="slider-headers" style={{ display: targetType === DocumentType.AUDIO ? 'none' : 'grid' }}>
- <div className="slider-text">Short</div>
- <div className="slider-text">Medium</div>
- <div className="slider-text">Long</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}`, display: 'flex', maxWidth: 60, width: '100%' }}>
+ <input className="presBox-inputNumber" type="number" readOnly value={duration} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateDurationTime(e.target.value))} />
+ <span>s</span>
</div>
- </>
+ </div>
)}
</div>
</div>
@@ -1633,28 +1631,62 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
return undefined;
}
- @computed get progressivizeDropdown() {
+
+ @computed get mediaDropdown() {
const { activeItem } = this;
if (activeItem && this.targetDoc) {
- const effect = activeItem.presBulletEffect ? activeItem.presBulletEffect : PresMovement.None;
- const bulletEffect = (presEffect: PresEffect) => (
- <div
- className={`presBox-dropdownOption ${activeItem.presentation_effect === presEffect || (presEffect === PresEffect.None && !activeItem.presentation_effect) ? 'active' : ''}`}
- onPointerDown={StopEvent}
- onClick={() => this.updateEffect(presEffect, true)}>
- {presEffect}
+ return (
+ <div className="presBox-option-block">
+ <div className="presBox-ribbon presbox-toggles">
+ <Tooltip title={<div className="dash-tooltip">Should first bullet be progressively disclosed or does it appear with slide.</div>}>
+ <div
+ className={`ribbon-toggle ${BoolCast(activeItem.presentation_playAudio) ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: BoolCast(activeItem.presentation_playAudio) ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => {
+ activeItem.presentation_playAudio = !BoolCast(activeItem.presentation_playAudio);
+ }}>
+ Play Audio Annotation
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Should first bullet be progressively disclosed or does it appear with slide.</div>}>
+ <div
+ className={`ribbon-toggle ${BoolCast(activeItem.presentation_zoomText) ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: BoolCast(activeItem.presentation_zoomText) ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => {
+ activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText);
+ }}>
+ Zoom Text Selections
+ </div>
+ </Tooltip>
+ </div>
</div>
);
+ }
+ return null;
+ }
+ @computed get progressivizeDropdown() {
+ const { activeItem } = this;
+ if (activeItem && this.targetDoc) {
return (
<div className="presBox-option-block">
- <div className="presBox-ribbon">
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Progressivize Collection</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
- type="checkbox"
- onChange={() => {
+ <div className="presBox-toggles presBox-ribbon">
+ <Tooltip title={<div className="dash-tooltip">whether progressivization is active for this slide</div>}>
+ <div
+ className={`ribbon-toggle ${Cast(activeItem.presentation_indexed, 'number', null) !== undefined ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: Cast(activeItem.presentation_indexed, 'number', null) !== undefined ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => {
activeItem.presentation_indexed = activeItem.presentation_indexed === undefined ? 0 : undefined;
activeItem.presentation_hideBefore = activeItem.presentation_indexed !== undefined;
const tagDoc = PresBox.targetRenderedDoc(this.activeItem);
@@ -1667,62 +1699,51 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (DocCast(activeItem.presentation_targetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc.annotationOn?.["${dataField}"]`);
else activeItem.data = ComputedField.MakeFunction(`this.presentation_targetDoc?.["${dataField}"]`);
+ }}>
+ Enable
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Should first bullet be progressively disclosed or does it appear with slide.</div>}>
+ <div
+ className={`ribbon-toggle ${!NumCast(activeItem.presentation_indexedStart) ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: !NumCast(activeItem.presentation_indexedStart) ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
}}
- checked={Cast(activeItem.presentation_indexed, 'number', null) !== undefined}
- />
- </div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Progressivize First Bullet</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
- type="checkbox"
- onChange={() => {
+ onClick={() => {
activeItem.presentation_indexedStart = activeItem.presentation_indexedStart ? 0 : 1;
- }}
- checked={!NumCast(activeItem.presentation_indexedStart)}
- />
- </div>
- <div className="ribbon-doubleButton" style={{ display: 'inline-flex' }}>
- <div className="presBox-subheading">Expand Current Bullet</div>
- <input
- className="presBox-checkbox"
- style={{ margin: 10, border: `solid 1px ${SnappingManager.userColor}` }}
- type="checkbox"
- onChange={() => {
- activeItem.presBulletExpand = !activeItem.presBulletExpand;
- }}
- checked={BoolCast(activeItem.presBulletExpand)}
- />
- </div>
-
- <div className="ribbon-box">
- Bullet Effect
+ }}>
+ All Bullets
+ </div>
+ </Tooltip>
+ <Tooltip title={<div className="dash-tooltip">Whether the active bullet expands when active.</div>}>
<div
- className="presBox-dropdown"
- onClick={action(e => {
- e.stopPropagation();
- this._openBulletEffectDropdown = !this._openBulletEffectDropdown;
- })}
+ className={`ribbon-toggle ${BoolCast(activeItem.presBulletExpand) ? 'active' : ''}`}
style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
color: SnappingManager.userColor,
- background: SnappingManager.userVariantColor,
- borderBottomLeftRadius: this._openBulletEffectDropdown ? 0 : 5,
- border: this._openBulletEffectDropdown ? `solid 2px ${SnappingManager.userVariantColor}` : `solid 1px ${SnappingManager.userColor}`,
+ background: BoolCast(activeItem.presBulletExpand) ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => {
+ activeItem.presBulletExpand = !activeItem.presBulletExpand;
}}>
- {effect?.toString()}
- <FontAwesomeIcon className="presBox-dropdownIcon" style={{ gridColumn: 2, color: this._openBulletEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon="angle-down" />
- <div
- className="presBox-dropdownOptions"
- style={{ display: this._openBulletEffectDropdown ? 'grid' : 'none', color: SnappingManager.userColor, background: SnappingManager.userBackgroundColor }}
- onPointerDown={e => e.stopPropagation()}>
- {Object.values(PresEffect)
- .filter(v => isNaN(Number(v)))
- .map(pEffect => bulletEffect(pEffect))}
- </div>
+ Expand Active
</div>
- </div>
+ </Tooltip>
</div>
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Effect"
+ toolTip="Animation effect to use when bullet activates"
+ formLabelPlacement="left"
+ closeOnSelect
+ items={Object.values(PresEffect).map(v => ({ text: v.toString(), val: v }))}
+ selectedVal={StrCast(activeItem.presBulletEffect, PresMovement.None)}
+ setSelectedVal={val => this.updateEffect(val as PresEffect, true)}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
</div>
);
}
@@ -1733,6 +1754,77 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return <div />;
}
+ /**
+ * This chatbox is for getting slide effect transition suggestions from gpt and visualizing them
+ */
+ @computed get aiEffects() {
+ return (
+ <div className="presBox-gpt-chat" style={{ display: SnappingManager.PropertiesWidth < 1 || !this._showAIGallery ? 'none' : undefined }}>
+ {/* Custom */}
+ <div className="pres-chat">
+ <div className="pres-chatbox-container-ai">
+ <ReactTextareaAutosize
+ placeholder="Use AI to suggest effects. Leave blank for random results."
+ className="pres-chatbox"
+ ref={r => {
+ setTimeout(() => {
+ if (r && !r.textContent) {
+ r.style.height = '';
+ r.style.height = r.scrollHeight + 'px';
+ }
+ });
+ }}
+ value={this._animationChat}
+ onChange={e => {
+ e.currentTarget.style.height = '';
+ e.currentTarget.style.height = e.currentTarget.scrollHeight + 'px';
+ this.setAnimationChat(e.target.value);
+ }}
+ onKeyDown={e => {
+ this.stopDictation();
+ e.stopPropagation();
+ }}
+ />
+ </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={SnappingManager.userVariantColor}
+ onClick={this.customizeAnimations}
+ />
+ </div>
+ <div style={{ alignItems: 'center' }}>
+ Click a box to use the effect.
+ {/* Preview Animations */}
+ <div className="presBox-effects">
+ {this.generatedAnimations.map((elem, i) => (
+ <div
+ key={i}
+ className="presBox-effect-container"
+ onClick={() => {
+ this.updateEffect(elem.effect, false);
+ this.updateEffectDirection(elem.direction);
+ this.updateEffectTiming(this.activeItem, {
+ type: SpringType.CUSTOM,
+ stiffness: elem.stiffness,
+ damping: elem.damping,
+ mass: elem.mass,
+ });
+ }}>
+ <SlideEffect dir={elem.direction} presEffect={elem.effect} springSettings={elem} infinite>
+ <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }} />
+ </SlideEffect>
+ </div>
+ ))}
+ </div>
+ </div>
+ </div>
+ );
+ }
+
@computed get transitionDropdown() {
const { activeItem } = this;
// Retrieving spring timing properties
@@ -1827,29 +1919,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._openBulletEffectDropdown = false;
})}>
<div className="presBox-option-block">
- <Dropdown
- color={SnappingManager.userColor}
- formLabel="Navigation"
- formLabelPlacement="left"
- closeOnSelect
- items={movementItems}
- selectedVal={this.movementName(activeItem)}
- setSelectedVal={val => this.updateMovement(val as PresMovement)}
- dropdownType={DropdownType.SELECT}
- type={Type.TERT}
- />
- <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? undefined : 'none' }}>
- <Tooltip title={<div>How much (%) of screen target should occupy</div>}>
- <div className="presBox-subheading">ZOOM %</div>
- </Tooltip>
- <div className="presBox-subheading-slider">{PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}</div>
- <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}`, display: 'flex', maxWidth: 60, width: '100%' }}>
- <input style={{ maxWidth: 25 }} className="presBox-input" readOnly type="number" value={zoom} onChange={e => this.updateZoom(e.target.value)} />
- <span>%</span>
- </div>
- </div>
<div className="ribbon-doubleButton">
- <div className="presBox-subheading">ZOOM/EFFECT TIME</div>
+ <Tooltip title={<div>How long the transition (view navigation and slide animation effect) lasts</div>}>
+ <div className="presBox-subheading">SPEED</div>
+ </Tooltip>
<div className="presBox-subheading-slider">
{PresBox.inputter('0.1', '0.1', '10', transitionSpeed, true, this.updateTransitionTime)}
<div className="slider-headers">
@@ -1858,153 +1931,55 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
</div>
</div>
<div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}`, display: 'flex', maxWidth: 60, width: '100%' }}>
- <input style={{ maxWidth: 25 }} className="presBox-input" type="number" readOnly value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} />
+ <input className="presBox-inputNumber" type="number" readOnly value={transitionSpeed} onKeyDown={e => e.stopPropagation()} onChange={action(e => this.updateTransitionTime(e.target.value))} />
<span>s</span>
</div>
</div>
- {/* Easing function */}
<Dropdown
color={SnappingManager.userColor}
- formLabel="Timing Function"
+ formLabel="View"
formLabelPlacement="left"
closeOnSelect
- items={easeItems}
- selectedVal={this.activeItem.presentation_easeFunc ? (StrCast(this.activeItem.presentation_easeFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presentation_easeFunc)) : 'ease'}
- setSelectedVal={val => {
- if (typeof val === 'string') {
- if (val !== 'custom') {
- this.setEaseFunc(this.activeItem, val);
- } else {
- this.setBezierEditorVisibility(true);
- this.setEaseFunc(this.activeItem, TIMING_DEFAULT_MAPPINGS.ease);
- }
- }
- }}
+ items={movementItems}
+ selectedVal={this.movementName(activeItem)}
+ setSelectedVal={val => this.updateMovement(val as PresMovement)}
dropdownType={DropdownType.SELECT}
type={Type.TERT}
/>
- {/* Custom */}
- <div
- className="presBox-show-hide-dropdown"
- style={{ alignSelf: 'flex-start' }}
- onClick={e => {
- e.stopPropagation();
- this.setBezierEditorVisibility(!this._showBezierEditor);
- }}>
- TIMING EDITOR
- <FontAwesomeIcon icon={this._showBezierEditor ? 'chevron-down' : 'chevron-up'} />
+ <div className="ribbon-doubleButton" style={{ display: activeItem.presentation_movement === PresMovement.Zoom ? undefined : 'none' }}>
+ <Tooltip title={<div>How much (%) of screen target should occupy</div>}>
+ <div className="presBox-subheading">ZOOM %</div>
+ </Tooltip>
+ <div className="presBox-subheading-slider">{PresBox.inputter('0', '1', '100', zoom, activeItem.presentation_movement === PresMovement.Zoom, this.updateZoom)}</div>
+ <div className="ribbon-property" style={{ border: `solid 1px ${SnappingManager.userColor}`, display: 'flex', maxWidth: 60, width: '100%' }}>
+ <input className="presBox-inputNumber" readOnly type="number" value={zoom} onChange={e => this.updateZoom(e.target.value)} />
+ <span>%</span>
+ </div>
</div>
+ {/* Easing function */}
+ {[PresMovement.None, PresMovement.Jump, ''].includes(StrCast(activeItem.presentation_movement) as PresMovement) ? null : (
+ <Dropdown
+ color={SnappingManager.userColor}
+ formLabel="Timing"
+ formLabelPlacement="left"
+ closeOnSelect
+ items={easeItems}
+ selectedVal={this.activeItem.presentation_easeFunc ? (StrCast(this.activeItem.presentation_easeFunc).startsWith('cubic') ? 'custom' : StrCast(this.activeItem.presentation_easeFunc)) : 'ease'}
+ setSelectedVal={val => typeof val === 'string' && this.setEaseFunc(this.activeItem, val !== 'custom' ? val : TIMING_DEFAULT_MAPPINGS.ease)}
+ dropdownType={DropdownType.SELECT}
+ type={Type.TERT}
+ />
+ )}
</div>
</div>
{/* Cubic bezier editor */}
- {this._showBezierEditor && (
+ {StrCast(activeItem.presentation_easeFunc).includes('cubic-bezier') && (
<div className="presBox-option-block" style={{ paddingTop: 0, alignItems: 'center' }}>
<CubicBezierEditor setFunc={this.setBezierControlPoints} currPoints={this.currCPoints} />
</div>
)}
- {effect === PresEffect.None ? null : (
- <div className="presBox-previewContainer">
- <Button
- type={Type.TERT}
- tooltip="show preview of slide animation effect"
- size={Size.SMALL}
- color={SnappingManager.userColor}
- background={'transparent'}
- onClick={action(() => {
- this._showPreview = false;
- setTimeout(action(() => { this._showPreview = true; }) ); // prettier-ignore
- })}
- text="Preview Effect"
- />
- <div className="presBox-option-block presBox-option-center">
- <div className="presBox-effect-container">
- {!this._showPreview ? null : (
- <SlideEffect dir={direction} presEffect={effect} springSettings={timingConfig}>
- <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }} />
- </SlideEffect>
- )}
- </div>
- </div>
- </div>
- )}
-
- {/* This chatbox is for getting slide effect transition suggestions from gpt and visualizing them */}
- <div className="presBox-gpt-chat" style={{ display: SnappingManager.PropertiesWidth < 1 ? 'none' : undefined }}>
- {/* Custom */}
- <div
- className="presBox-show-hide-dropdown"
- style={{ alignSelf: 'flex-start' }}
- onClick={e => {
- e.stopPropagation();
- this.setShowAIGalleryVisibilty(!this._showAIGallery);
- }}>
- AI EFFECTS
- <FontAwesomeIcon icon={this._showAIGallery ? 'chevron-down' : 'chevron-up'} />
- </div>
- <div className="pres-chat" style={{ display: this._showAIGallery ? undefined : 'none' }}>
- <div className="pres-chatbox-container-ai">
- <ReactTextareaAutosize
- placeholder="Use AI to suggest effects. Leave blank for random results."
- className="pres-chatbox"
- ref={r => {
- setTimeout(() => {
- if (r && !r.textContent) {
- r.style.height = '';
- r.style.height = r.scrollHeight + 'px';
- }
- });
- }}
- value={this._animationChat}
- onChange={e => {
- e.currentTarget.style.height = '';
- e.currentTarget.style.height = e.currentTarget.scrollHeight + 'px';
- this.setAnimationChat(e.target.value);
- }}
- onKeyDown={e => {
- this.stopDictation();
- e.stopPropagation();
- }}
- />
- </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={SnappingManager.userVariantColor}
- onClick={this.customizeAnimations}
- />
- </div>
- <div style={{ display: this._showAIGallery ? 'flex' : 'none', alignItems: 'center' }}>
- Click a box to use the effect.
- {/* Preview Animations */}
- <div className="presBox-effects">
- {this.generatedAnimations.map((elem, i) => (
- <div
- key={i}
- className="presBox-effect-container"
- onClick={() => {
- this.updateEffect(elem.effect, false);
- this.updateEffectDirection(elem.direction);
- this.updateEffectTiming(this.activeItem, {
- type: SpringType.CUSTOM,
- stiffness: elem.stiffness,
- damping: elem.damping,
- mass: elem.mass,
- });
- }}>
- <SlideEffect dir={elem.direction} presEffect={elem.effect} springSettings={elem} infinite>
- <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[i] }} />
- </SlideEffect>
- </div>
- ))}
- </div>
- </div>
- </div>
-
<div
className={`presBox-ribbon ${this._transitionTools && this.layoutDoc.presentation_status === PresStatus.Edit ? 'active' : ''}`}
onPointerDown={StopEvent}
@@ -2017,10 +1992,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
})}>
<div className="presBox-option-block">
{/* Effect dropdown */}
- <div>
+ <div style={{ display: 'flex' }}>
<Dropdown
color={SnappingManager.userColor}
- formLabel="Slide Effect"
+ formLabel="Effect"
+ toolTip="Animation effect to apply when transitiong to slide"
formLabelPlacement="left"
closeOnSelect
items={effectItems}
@@ -2033,58 +2009,68 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
dropdownType={DropdownType.SELECT}
type={Type.TERT}
/>
+
+ <div
+ className={`ribbon-toggle ${this._showAIGallery ? 'active' : ''}`}
+ style={{
+ border: `solid 1px ${SnappingManager.userColor}`,
+ color: SnappingManager.userColor,
+ background: this._showAIGallery ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor,
+ }}
+ onClick={() => this.setShowAIGalleryVisibilty(!this._showAIGallery)}>
+ MORE
+ </div>
</div>
+ {this.aiEffects}
<div className="presBox-gpt-chat">
{/* Effect direction */}
{/* Only applies to certain effects */}
{(effect === PresEffect.Flip || effect === PresEffect.Bounce || effect === PresEffect.Roll) && (
- <>
- <div className="ribbon-doubleButton">
- <div className="presBox-subheading">EFFECT DIRECTION</div>
- <div style={{ width: '100%' }}>
- <div className="presBox-icon-list" style={{ width: 'fit-content', margin: 'auto' }}>
- <IconButton
- type={Type.TERT}
- color={activeItem.presentation_effectDirection === PresEffectDirection.Left ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
- tooltip="Left"
- icon={<FaArrowRight size="16px" />}
- onClick={() => this.updateEffectDirection(PresEffectDirection.Left)}
- />
- <IconButton
- type={Type.TERT}
- color={activeItem.presentation_effectDirection === PresEffectDirection.Right ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
- tooltip="Right"
- icon={<FaArrowLeft size="16px" />}
- onClick={() => this.updateEffectDirection(PresEffectDirection.Right)}
- />
- {effect !== PresEffect.Roll && (
- <>
- <IconButton
- type={Type.TERT}
- color={activeItem.presentation_effectDirection === PresEffectDirection.Top ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
- tooltip="Top"
- icon={<FaArrowDown size="16px" />}
- onClick={() => this.updateEffectDirection(PresEffectDirection.Top)}
- />
- <IconButton
- type={Type.TERT}
- color={activeItem.presentation_effectDirection === PresEffectDirection.Bottom ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
- tooltip="Bottom"
- icon={<FaArrowUp size="16px" />}
- onClick={() => this.updateEffectDirection(PresEffectDirection.Bottom)}
- />
- </>
- )}
- </div>
+ <div className="ribbon-doubleButton">
+ <div className="presBox-subheading">DIRECTION</div>
+ <div style={{ width: '100%' }}>
+ <div className="presBox-icon-list" style={{ width: 'fit-content', margin: 'auto' }}>
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Left ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Left"
+ icon={<FaArrowRight size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Left)}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Right ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Right"
+ icon={<FaArrowLeft size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Right)}
+ />
+ {effect !== PresEffect.Roll && (
+ <>
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Top ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Top"
+ icon={<FaArrowDown size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Top)}
+ />
+ <IconButton
+ type={Type.TERT}
+ color={activeItem.presentation_effectDirection === PresEffectDirection.Bottom ? SnappingManager.userVariantColor : SnappingManager.userBackgroundColor}
+ tooltip="Bottom"
+ icon={<FaArrowUp size="16px" />}
+ onClick={() => this.updateEffectDirection(PresEffectDirection.Bottom)}
+ />
+ </>
+ )}
</div>
</div>
- </>
+ </div>
)}
{effect !== PresEffect.Lightspeed && (
<>
<Dropdown
color={SnappingManager.userColor}
- formLabel="Effect Timing"
+ formLabel="Springiness"
formLabelPlacement="left"
closeOnSelect
items={effectTimings}
@@ -2095,20 +2081,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
/>
<div style={{ display: SnappingManager.PropertiesWidth < 1 ? 'none' : undefined }}>
- {/* Custom */}
- <div
- className="presBox-show-hide-dropdown"
- style={{ display: effect !== PresEffect.None ? undefined : 'none' }}
- onClick={e => {
- e.stopPropagation();
- this.setSpringEditorVisibility(!this._showSpringEditor);
- }}>
- SPRING SETTINGS
- <FontAwesomeIcon icon={this._showSpringEditor ? 'chevron-down' : 'chevron-up'} />
- </div>
- {/* Spring settings */}
{/* No spring settings for jackinthebox (lightspeed) */}
- {this._showSpringEditor && effect !== PresEffect.None && (
+ {StrCast(activeItem.presentation_effectTiming).includes('custom') && effect !== PresEffect.None && (
<>
<div className="presBox-springSlider">
<span>Tension</span>
@@ -2150,30 +2124,35 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
)}
</div>
</div>
+ </div>
- {/* Toggles */}
- <div className="presBox-option-block">
- <Toggle
- formLabel="Play Audio Annotation"
- toggleType={ToggleType.SWITCH}
- toggleStatus={BoolCast(activeItem.presentation_playAudio)}
- onClick={() => {
- activeItem.presentation_playAudio = !BoolCast(activeItem.presentation_playAudio);
- }}
- color={SnappingManager.userColor}
- />
- <Toggle
- formLabel="Zoom Text Selections"
- toggleType={ToggleType.SWITCH}
- toggleStatus={BoolCast(activeItem.presentation_zoomText)}
- onClick={() => {
- activeItem.presentation_zoomText = !BoolCast(activeItem.presentation_zoomText);
- }}
+ {effect === PresEffect.None ? null : (
+ <div className="presBox-previewContainer">
+ <Button
+ type={Type.TERT}
+ tooltip="show preview of slide animation effect"
+ size={Size.SMALL}
color={SnappingManager.userColor}
+ background={'transparent'}
+ onClick={action(() => {
+ this._showPreview = false;
+ setTimeout(action(() => { this._showPreview = true; }) ); // prettier-ignore
+ })}
+ text="Preview Effect"
/>
- <Button text="Apply to all" type={Type.TERT} color={SnappingManager.userVariantColor} onClick={() => this.applyTo(this.childDocs)} />
+ <div className="presBox-option-block presBox-option-center">
+ <div className="presBox-effect-container">
+ {!this._showPreview ? null : (
+ <SlideEffect dir={direction} presEffect={effect} springSettings={timingConfig}>
+ <div className="presBox-effect-demo-box" style={{ backgroundColor: springPreviewColors[0] }} />
+ </SlideEffect>
+ )}
+ </div>
+ </div>
</div>
- </div>
+ )}
+
+ <Button text="Apply to all slides" type={Type.TERT} color={SnappingManager.userVariantColor} onClick={() => this.applyTo(this.childDocs)} />
</>
);
}
@@ -2199,7 +2178,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div id="startTime" className="slider-number" style={{ color: SnappingManager.userColor, backgroundColor: SnappingManager.userBackgroundColor }}>
<input
className="presBox-input"
- style={{ textAlign: 'center', width: '100%', height: 15, fontSize: 10 }}
type="number"
readOnly
value={NumCast(activeItem.config_clipStart).toFixed(2)}
@@ -2226,7 +2204,6 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
<input
className="presBox-input"
onKeyDown={e => e.stopPropagation()}
- style={{ textAlign: 'center', width: '100%', height: 15, fontSize: 10 }}
type="number"
readOnly
value={configClipEnd.toFixed(2)}