diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 12 | ||||
| -rw-r--r-- | src/client/views/nodes/IconTagBox.scss | 1 | ||||
| -rw-r--r-- | src/client/views/nodes/IconTagBox.tsx | 69 | ||||
| -rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 4 |
4 files changed, 56 insertions, 30 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index c3026d7be..070a13103 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -750,7 +750,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewProps & Field transform: `scale(${this.uiBtnScaling})`, bottom: Number.isNaN(this.maxWidgetSize) ? undefined : this.maxWidgetSize, }}> - {this._props.DocumentView?.() && !this._props.docViewPath().slice(-2)[0].ComponentView?.isUnstyledView?.() ? <TagsView Views={[this._props.DocumentView?.()]} /> : null} + {this._props.DocumentView?.() && !this._props.docViewPath().slice(-2)[0].ComponentView?.isUnstyledView?.() ? <TagsView background={this.backgroundBoxColor} Views={[this._props.DocumentView?.()]} /> : null} </div> ) : ( <> @@ -774,7 +774,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewProps & Field ref={r => this.historyRef(this._oldHistoryWheel, (this._oldHistoryWheel = r))}> <div className="documentView-editorView-resizer" /> {this._componentView?.componentAIView?.() ?? null} - {this._props.DocumentView?.() ? <TagsView Views={[this._props.DocumentView?.()]} /> : null} + {this._props.DocumentView?.() ? <TagsView background={this.backgroundBoxColor} Views={[this._props.DocumentView?.()]} /> : null} </div> </> )} @@ -1319,7 +1319,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { } public playAnnotation = () => { - const audioAnnoState = this.dataDoc.audioAnnoState ?? AudioAnnoState.stopped; + const audioAnnoState = this.Document._audioAnnoState ?? AudioAnnoState.stopped; const audioAnnos = Cast(this.dataDoc[this.LayoutFieldKey + '_audioAnnotations'], listSpec(AudioField), null); const anno = audioAnnos?.lastElement(); if (anno instanceof AudioField) { @@ -1331,13 +1331,13 @@ export class DocumentView extends DocComponent<DocumentViewProps>() { autoplay: true, loop: false, volume: 0.5, - onend: action(() => { this.dataDoc.audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore + onend: action(() => { this.Document._audioAnnoState = AudioAnnoState.stopped; }), // prettier-ignore }); - this.dataDoc.audioAnnoState = AudioAnnoState.playing; + this.Document._audioAnnoState = AudioAnnoState.playing; break; case AudioAnnoState.playing: (this.dataDoc[AudioPlay] as Howl)?.stop(); - this.dataDoc.audioAnnoState = AudioAnnoState.stopped; + this.Document._audioAnnoState = AudioAnnoState.stopped; break; default: } diff --git a/src/client/views/nodes/IconTagBox.scss b/src/client/views/nodes/IconTagBox.scss index 202b0c701..d6cf95958 100644 --- a/src/client/views/nodes/IconTagBox.scss +++ b/src/client/views/nodes/IconTagBox.scss @@ -4,7 +4,6 @@ display: flex; position: relative; pointer-events: none; - background-color: rgb(218, 218, 218); border-radius: 50px; align-items: center; gap: 5px; diff --git a/src/client/views/nodes/IconTagBox.tsx b/src/client/views/nodes/IconTagBox.tsx index ddabd61e1..e3924eca7 100644 --- a/src/client/views/nodes/IconTagBox.tsx +++ b/src/client/views/nodes/IconTagBox.tsx @@ -1,22 +1,23 @@ -import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Tooltip } from '@mui/material'; import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import React from 'react'; -import { returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; -import { emptyFunction } from '../../../Utils'; -import { Doc } from '../../../fields/Doc'; +import { Doc, StrListCast } from '../../../fields/Doc'; import { StrCast } from '../../../fields/Types'; +import { AudioAnnoState } from '../../../server/SharedMediaTypes'; import { undoable } from '../../util/UndoManager'; import { ObservableReactComponent } from '../ObservableReactComponent'; import { TagItem } from '../TagsView'; import { DocumentView } from './DocumentView'; import './IconTagBox.scss'; +import { Size, Toggle, ToggleType, Type } from '@dash/components'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; +import { StyleProp } from '../StyleProp'; export interface IconTagProps { Views: DocumentView[]; - IsEditing: boolean; + IsEditing: boolean | undefined; } /** @@ -52,13 +53,46 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { * @param key metadata icon button * @returns an icon for the metdata button */ - getButtonIcon = (doc: Doc, key: Doc): JSX.Element => { + getButtonIcon = (dv: DocumentView, key: Doc): JSX.Element => { const icon = StrCast(key.icon) as IconProp; const tag = StrCast(key.toolType); - const isActive = TagItem.docHasTag(doc, tag); - const color = isActive ? '#4476f7' : '#323232'; // TODO should use theme colors + const color = dv._props.styleProvider?.(dv.layoutDoc, dv.ComponentView?._props, StyleProp.FontColor) as string; + return ( + <Toggle + tooltip={`Click to add/remove the tag ${tag}`} + toggleStatus={TagItem.docHasTag(dv.Document, tag)} + toggleType={ToggleType.BUTTON} + icon={<FontAwesomeIcon className={`fontIconBox-icon-${ToggleType.BUTTON}`} icon={icon} color={color} />} + size={Size.XSMALL} + type={Type.PRIM} + onClick={() => this.setIconTag(tag, !TagItem.docHasTag(this.View.Document, tag))} + color={color} + /> + ); + }; - return <FontAwesomeIcon icon={icon} style={{ color, height: '20px', width: '20px' }} />; + /** + * Displays a button to play audio annotations on the document. + * NOTE: This should be generalized -- audio should + * @returns + */ + renderAudioButtons = (dv: DocumentView, anno: string) => { + const fcolor = dv._props.styleProvider?.(dv.layoutDoc, dv.ComponentView?._props, StyleProp.FontColor) as string; + const audioIconColors: { [key: string]: string } = { playing: 'green', stopped: fcolor ?? 'blue', recording: 'red' }; + const audioAnnoState = (audioDoc: Doc) => StrCast(audioDoc.audioAnnoState, AudioAnnoState.stopped); + const color = audioIconColors[audioAnnoState(this.View.Document)]; + return ( + <Toggle + tooltip={`click to play:${anno}`} + toggleStatus={true} + toggleType={ToggleType.BUTTON} + icon={<FontAwesomeIcon className={`fontIconBox-icon-${ToggleType.BUTTON}`} icon="file-audio" color={color} />} + size={Size.XSMALL} + type={Type.PRIM} + onClick={() => this.View?.playAnnotation()} + color={color} + /> + ); }; /** @@ -69,22 +103,15 @@ export class IconTagBox extends ObservableReactComponent<IconTagProps> { .map(key => ({ key, tag: StrCast(key.toolType) })) .filter(({ tag }) => this._props.IsEditing || TagItem.docHasTag(this.View.Document, tag) || (DocumentView.Selected().length === 1 && this.View.IsSelected)) .map(({ key, tag }) => ( - <Tooltip key={tag} title={<div className="dash-tooltip">Click to add/remove this card from the {tag} group</div>}> - <button - type="button" - onPointerDown={e => - setupMoveUpEvents(this, e, returnFalse, emptyFunction, clickEv => { - this.setIconTag(tag, !TagItem.docHasTag(this.View.Document, tag)); - clickEv.stopPropagation(); - }) - }> - {this.getButtonIcon(this.View.Document, key)} - </button> + <Tooltip key={tag} title={<div className="dash-tooltip">Click to add/remove the {tag} tag</div>}> + {this.getButtonIcon(this.View, key)} </Tooltip> )); // prettier-ignore - return !buttons.length ? null : ( + const audioannos = StrListCast(this.View.Document[Doc.LayoutFieldKey(this.View.Document) + '_audioAnnotations_text']); + return !buttons.length && !audioannos.length ? null : ( <div className="card-button-container" style={{ fontSize: '50px' }}> + {audioannos.length ? this.renderAudioButtons(this.View, audioannos.lastElement()) : null} {buttons} </div> ); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 51b9a4333..6955e5401 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -17,7 +17,7 @@ import { BsMarkdownFill } from 'react-icons/bs'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivWidth, returnFalse, returnZero, setupMoveUpEvents, simMouseEvent, smoothScroll, StopEvent } from '../../../../ClientUtils'; import { DateField } from '../../../../fields/DateField'; import { CreateLinkToActiveAudio, Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../../fields/Doc'; -import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, DocData, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; +import { AclAdmin, AclAugment, AclEdit, AclSelfEdit, DocCss, ForceServerWrite, UpdatingFromServer } from '../../../../fields/DocSymbols'; import { Id, ToString } from '../../../../fields/FieldSymbols'; import { InkTool } from '../../../../fields/InkField'; import { List } from '../../../../fields/List'; @@ -246,7 +246,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FormattedTextB anchor.followLinkAudio = true; let stopFunc: () => void = emptyFunction; target.$mediaState = mediaState.Recording; - DictationManager.recordAudioAnnotation(target[DocData], Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore + DictationManager.recordAudioAnnotation(target, Doc.LayoutFieldKey(target), stop => { stopFunc = stop }); // prettier-ignore const reactionDisposer = reaction( () => target.mediaState, |
