-
chris authoredaef0388d
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
Forked from
Coko Org / Products / ketty / editoria-app
731 commits behind the upstream repository.
CommentBubble.js 3.67 KiB
import {
createAnnotation,
DefaultDOMElement,
FontAwesomeIcon as Icon,
Tool
} from 'substance'
class CommentBubble extends Tool {
render ($$) {
const mode = this.getMode()
const title = 'Create a new comment'
if (mode === 'delete') return $$('div')
// console.log('bubble commands', commands.mode)
const icon = $$(Icon, { icon: 'fa-comment' })
.addClass('sc-comment-icon')
const bubble = $$('div')
.attr('title', title)
.addClass('sc-overlay-bubble')
.addClass('sc-overlay-bubble-hidden')
.on('click', this.createComment)
.append(icon)
return bubble
}
// reset bubble position on window resize
// only works on the horizontal level, as the vertical position gets
// calculated relative to the overlay container, which gets positioned
// wrong on resize (substance bug -- TODO)
didMount () {
this.position()
DefaultDOMElement.getBrowserWindow().on('resize', this.didUpdate, this)
}
didUpdate () {
this.position()
}
dispose () {
DefaultDOMElement.getBrowserWindow().off(this)
}
position () {
if (this.el.getChildCount() === 0) return
this.setBubblePosition()
}
setBubblePosition () {
// without this check, the editor will break on first load
const surface = this.getSurface()
if (!surface) return
const documentElement = document.querySelector('.se-content')
const overlayContainer = document.querySelector('.sc-overlay-container')
setTimeout(() => { // read comment below
const documentElementWidth = documentElement.offsetWidth
const overlayContainerLeft = overlayContainer.offsetLeft
const left = documentElementWidth - overlayContainerLeft - 15
// unhide it first, as the bubble has no height otherwise
this.el.removeClass('sc-overlay-bubble-hidden')
const hints = surface.getBoundingRectangleForSelection()
const selectionHeight = hints.height
const bubbleHeight = this.el.getHeight()
const cheat = 3
const moveUp = (selectionHeight / 2) + (bubbleHeight / 2) + cheat
const top = '-' + moveUp + 'px'
this.el.css('left', left)
this.el.css('top', top)
})
/*
There is a race condition with overlayContainer's position.
If it gets rendered fast enough, this is fine.
Otherwise, the overlayContainerLeft variable won't have been updated by
substance for us to get the correct value.
There is no event letting us know that this has been updated,
and it's probably not worth creating a listener.
*/
}
getCommentState () {
const { commandManager } = this.context
const commandStates = commandManager.getCommandStates()
return commandStates.comment
}
getDocumentSession () {
return this.context.documentSession
}
getMode () {
const commentState = this.getCommentState()
return commentState.mode
}
getProvider () {
return this.context.commentsProvider
}
getSelection () {
const documentSession = this.getDocumentSession()
return documentSession.getSelection()
}
getSurface () {
const surfaceManager = this.context.surfaceManager
return surfaceManager.getFocusedSurface()
}
// TODO -- move to provider?
createComment () {
const mode = this.getMode()
const provider = this.getProvider()
const selection = this.getSelection()
const surface = this.getSurface()
if (mode === 'delete') return
const newNode = {
selection: selection,
node: { type: 'comment' }
}
surface.transaction((tx, args) => {
const annotation = createAnnotation(tx, newNode)
provider.focusTextArea(annotation.node.id)
})
}
}
export default CommentBubble