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)
}
}