declare let swellrt ; /**
  A Comment stands for a group of comment annotations sharing
  the same id.

  CommendsData is a SwellRT map<Key,Value>
  each comment use two different Keys:
  <comment-id> : array of replies
  <comment-id>-state : state of the comment

*/ export class Comment { public static readonly ANNOTATION_KEY = 'comment' ; public static readonly STATE_SUFFIX = '-state' ; private static calculateText ( annotationParts ) { let text = "" ; for ( let i in annotationParts [ Comment . ANNOTATION_KEY ] ) { text += annotationParts [ Comment . ANNOTATION_KEY ] [ i ] . text ; } return text ; } private static calculateContainerRange ( annotationParts ) { let last = annotationParts [ Comment . ANNOTATION_KEY ] . length - 1 ; return swellrt . Editor . Range . create ( annotationParts [ Comment . ANNOTATION_KEY ] [ 0 ] . range . start , annotationParts [ Comment . ANNOTATION_KEY ] [ last ] . range . end ) ; } public static setResolved ( id , commentsData , participantId ) { let commentState = commentsData . get ( id + Comment . STATE_SUFFIX ) ; if ( commentState . state != "resolved" ) { commentState . state = "resolved" ; commentState . participantId = participantId ; commentsData . put ( id + Comment . STATE_SUFFIX , commentState ) ; } } public static setOpen ( id , commentsData ) { let commentState = commentsData . get ( id + Comment . STATE_SUFFIX ) ; if ( ! commentState ) commentState = { } ; if ( ! commentState . state || commentState . state != "open" ) { commentState . state = "open" ; commentsData . put ( id + Comment . STATE_SUFFIX , commentState ) ; } } public static create ( range , commentText , user , editor , commentsData ) { let timestamp = ( new Date ( ) ) . getTime ( ) ; let sessionId = user . session . id ; let id = sessionId . slice ( - 5 ) + ( "" + timestamp ) . slice ( - 5 ) ; commentsData . put ( id , swellrt . List . create ( ) ) ; Comment . setOpen ( id , commentsData ) ; editor . setTextAnnotationOverlap ( Comment . ANNOTATION_KEY , id , range ) ; let annotationParts = editor . seekTextAnnotationsByValue ( Comment . ANNOTATION_KEY , id , range ) ; let comment = new Comment ( id , user , editor , commentsData ) ; comment . containerRange = Comment . calculateContainerRange ( annotationParts ) ; ; comment . text = Comment . calculateText ( annotationParts ) ; ; comment . reply ( commentText , user ) ; return comment ; } public static get ( id , annotation , user , editor , commentsData ) { let comment = new Comment ( id , user , editor , commentsData ) ; let annotationParts = editor . seekTextAnnotationsByValue ( Comment . ANNOTATION_KEY , id , swellrt . Editor . Range . ALL ) ; comment . containerRange = Comment . calculateContainerRange ( annotationParts ) ; ; comment . text = Comment . calculateText ( annotationParts ) ; ; return comment ; } private annotationHighlight : any ; private containerRange : any ; private text : string ; constructor ( public readonly id , private user , private editor , private commentsData ) { } public getText ( ) { return this . text ; } public isResolved ( ) { return this . commentsData . get ( this . id + Comment . STATE_SUFFIX ) . state == "resolved" ; } public getItems ( ) { let array = new Array ( ) ; let comments = this . commentsData . get ( this . id ) ; for ( let i = 0 ; i < comments . size ( ) ; i ++ ) array . push ( comments . get ( i ) ) ; return array ; } public deleteItem ( index ) { let comments = this . commentsData . get ( this . id ) ; comments . remove ( index ) ; } public highlight ( activate ) { if ( this . annotationHighlight ) { this . annotationHighlight . clear ( ) ; this . annotationHighlight = undefined ; } if ( activate ) { this . annotationHighlight = this . editor . setAnnotation ( '@mark' , "" + ( new Date ( ) ) . getTime ( ) , this . containerRange ) ; } } /** First replay is the comment */ public reply ( text , user ) { let timestamp = ( new Date ( ) ) . getTime ( ) ; let item = { participantId : this . user . profile . address , time : timestamp , text : text } ; this . commentsData . get ( this . id ) . add ( item ) ; } public resolve ( ) { Comment . setResolved ( this . id , this . commentsData , this . user . profile . address ) ; this . highlight ( false ) ; this . editor . clearTextAnnotationOverlap ( Comment . ANNOTATION_KEY , this . id , this . containerRange ) ; } }