const removeContact = (state: Contacts, username: string) => { const people: List<Contact> = state.get('people'); return state.set('people', people.withMutations(p => { p.delete(p.findIndex(c => c.get('username') === username)); })); };
(state: Contacts, key: string, value) => { const people: List<Contact> = state.get('availablePeople'); return state.set('availablePeople', people.withMutations(l => { for (let i = 0; i < l.count(); ++i) { l.update(i, v => v.set(key, value)); } })); };
const addMessage = (state: Contacts, username: string, source: MessageSource, message: string) => { const people: List<Contact> = state.get('people'); const m = { source, message }; return state.set('people', people.withMutations(p => { const index = p.findIndex(c => c.get('username') === username); p.update(index, v => v.mergeDeep(fromJS({ messages: p.get(index).get('messages').concat([m]) }))); })); };
const addMessage = (state: Contacts, username: string, source: MessageSource, message: string) => { const people: List<Contact> = state.get('people'); const m = { source, message }; return state.set('people', people.withMutations(p => { const index = p.findIndex(c => c.get('username') === username); if (index < 0) { // automatically add to contacts p.push(fromJS({ username, messages: [m], presence: Presence.Online, })); } else { p.update(index, v => v.mergeDeep(fromJS({ messages: p.get(index).get('messages').concat([m]) }))); } })); };
export function embedAnnotations(timelineDuration: number, annotationStacks: List<List<Record<Annotation>>>, annotationStackIndex: number, addAnnotations: List<Record<Annotation>>, removeAnnotations: List<Record<Annotation>>): List<List<Record<Annotation>>> { if(annotationStackIndex < 0 || annotationStackIndex >= annotationStacks.size) { return annotationStacks } const selStack = annotationStacks.get(annotationStackIndex)! const withRemovals = selStack.filter(a => { return removeAnnotations.find(annotation => { return annotation.get('id', null) === a.get('id', null) }) === undefined }) let updatedStacks = annotationStacks.set(annotationStackIndex, withRemovals) const vCollisions = findVerticalCollisions(timelineDuration, updatedStacks, annotationStackIndex+1, removeAnnotations) updatedStacks = updatedStacks.withMutations(mStacks => { mStacks.forEach((stack, stackIndex) => { const filtered = stack.filter((annotation, annotationIndex) => { return vCollisions.find(vColl => { return vColl.index === annotationIndex && vColl.annotationStackIndex === stackIndex }) === undefined }) mStacks.set(stackIndex, filtered) }) }) const withInsertions = withRemovals.concat(addAnnotations).sort(recordSort) const insertionIndices = addAnnotations.map(mapIndicesFunc(withInsertions)) const hCollisions: {annotation: Record<Annotation>, index: number}[] = findHorizontalCollisions(timelineDuration, withInsertions, insertionIndices) const collisions = vCollisions.map(({annotation, index}) => ({annotation, index})).concat(hCollisions) if(collisions.length > 0) { const withoutHCollisions = withInsertions.filter((a, i) => { return hCollisions.find(({index}) => { return i === index }) === undefined }) const stackInsertions = updatedStacks.set(annotationStackIndex, withoutHCollisions) const stacksFitted = fitOptimized(timelineDuration, stackInsertions, List(collisions.map(({annotation}) => annotation))) const maxSize = Math.max(stackInsertions.size, stacksFitted.size) const tmp: List<List<Record<Annotation>>> = List() const ret = tmp.withMutations(mRet => { for(let i = 0; i < maxSize; i++) { if(i < stackInsertions.size && i < stacksFitted.size) { mRet.push(stackInsertions.get(i)!.concat(stacksFitted.get(i)!).sort(recordSort)) } else if(i < stackInsertions.size) { mRet.push(stackInsertions.get(i)!) } else { mRet.push(stacksFitted.get(i)!) } } }) return ret.filter(stack => stack.size > 0) } else { return annotationStacks.set(annotationStackIndex, withInsertions) } }