main

mattermost/focalboard

Last updated at: 29/12/2023 09:41

attachments.ts

TLDR

The attachments.ts file in the Demo Projects project is responsible for managing attachments in the Redux store. It defines a state slice, attachments, with methods to update attachments and upload progress.

Methods

updateAttachments

This method updates the attachments state in Redux based on the provided AttachmentBlock array. It adds new attachments, removes deleted attachments, and updates existing attachments.

updateUploadPercent

This method updates the uploading percentage of a specific attachment block. It takes a payload object with blockId and uploadPercent properties and updates the corresponding attachment block in the state.

END

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import {createSlice, PayloadAction} from '@reduxjs/toolkit'

import {AttachmentBlock} from '../blocks/attachmentBlock'

import {loadBoardData, initialReadOnlyLoad} from './initialLoad'

import {RootState} from './index'

type AttachmentsState = {
    attachments: {[key: string]: AttachmentBlock}
    attachmentsByCard: {[key: string]: AttachmentBlock[]}
}

const attachmentSlice = createSlice({
    name: 'attachments',
    initialState: {attachments: {}, attachmentsByCard: {}} as AttachmentsState,
    reducers: {
        updateAttachments: (state, action: PayloadAction<AttachmentBlock[]>) => {
            for (const attachment of action.payload) {
                if (attachment.deleteAt === 0) {
                    state.attachments[attachment.id] = attachment
                    if (!state.attachmentsByCard[attachment.parentId]) {
                        state.attachmentsByCard[attachment.parentId] = [attachment]
                        return
                    }
                    if (state.attachmentsByCard[attachment.parentId].findIndex((a) => a.id === attachment.id) === -1) {
                        state.attachmentsByCard[attachment.parentId].push(attachment)
                    }
                } else {
                    const parentId = state.attachments[attachment.id]?.parentId
                    if (!state.attachmentsByCard[parentId]) {
                        delete state.attachments[attachment.id]
                        return
                    }
                    for (let i = 0; i < state.attachmentsByCard[parentId].length; i++) {
                        if (state.attachmentsByCard[parentId][i].id === attachment.id) {
                            state.attachmentsByCard[parentId].splice(i, 1)
                        }
                    }
                    delete state.attachments[attachment.id]
                }
            }
        },
        updateUploadPrecent: (state, action: PayloadAction<{blockId: string, uploadPercent: number}>) => {
            state.attachments[action.payload.blockId].uploadingPercent = action.payload.uploadPercent
        },
    },
    extraReducers: (builder) => {
        builder.addCase(initialReadOnlyLoad.fulfilled, (state, action) => {
            state.attachments = {}
            state.attachmentsByCard = {}
            for (const block of action.payload.blocks) {
                if (block.type === 'attachment') {
                    state.attachments[block.id] = block as AttachmentBlock
                    state.attachmentsByCard[block.parentId] = state.attachmentsByCard[block.parentId] || []
                    state.attachmentsByCard[block.parentId].push(block as AttachmentBlock)
                }
            }
            Object.values(state.attachmentsByCard).forEach((arr) => arr.sort((a, b) => a.createAt - b.createAt))
        })
        builder.addCase(loadBoardData.fulfilled, (state, action) => {
            state.attachments = {}
            state.attachmentsByCard = {}
            for (const block of action.payload.blocks) {
                if (block.type === 'attachment') {
                    state.attachments[block.id] = block as AttachmentBlock
                    state.attachmentsByCard[block.parentId] = state.attachmentsByCard[block.parentId] || []
                    state.attachmentsByCard[block.parentId].push(block as AttachmentBlock)
                }
            }
            Object.values(state.attachmentsByCard).forEach((arr) => arr.sort((a, b) => a.createAt - b.createAt))
        })
    },
})

export const {updateAttachments, updateUploadPrecent} = attachmentSlice.actions
export const {reducer} = attachmentSlice

export function getCardAttachments(cardId: string): (state: RootState) => AttachmentBlock[] {
    return (state: RootState): AttachmentBlock[] => {
        return (state.attachments?.attachmentsByCard && state.attachments.attachmentsByCard[cardId]) || []
    }
}

export function getUploadPercent(blockId: string): (state: RootState) => number {
    return (state: RootState): number => {
        return (state.attachments.attachments[blockId].uploadingPercent)
    }
}