postiz/apps/frontend/src/components/new-launch/store.ts

509 lines
14 KiB
TypeScript

'use client';
import { create } from 'zustand';
import dayjs from 'dayjs';
import { Integrations } from '@gitroom/frontend/components/launches/calendar.context';
import { createRef, RefObject } from 'react';
import { arrayMoveImmutable } from 'array-move';
import { PostComment } from '@gitroom/frontend/components/new-launch/providers/high.order.provider';
interface Values {
id: string;
content: string;
media: { id: string; path: string }[];
}
interface Internal {
integration: Integrations;
integrationValue: Values[];
}
interface SelectedIntegrations {
settings: any;
integration: Integrations;
ref?: RefObject<any>;
}
interface StoreState {
date: dayjs.Dayjs;
postComment: PostComment;
repeater?: number;
isCreateSet: boolean;
totalChars: number;
activateExitButton: boolean;
tags: { label: string; value: string }[];
tab: 0 | 1;
current: string;
locked: boolean;
hide: boolean;
setLocked: (locked: boolean) => void;
integrations: Integrations[];
selectedIntegrations: SelectedIntegrations[];
global: Values[];
internal: Internal[];
addGlobalValue: (index: number, value: Values[]) => void;
addInternalValue: (
index: number,
integrationId: string,
value: Values[]
) => void;
setGlobalValue: (value: Values[]) => void;
setInternalValue: (integrationId: string, value: Values[]) => void;
deleteGlobalValue: (index: number) => void;
deleteInternalValue: (integrationId: string, index: number) => void;
addRemoveInternal: (integrationId: string) => void;
changeOrderGlobal: (index: number, direction: 'up' | 'down') => void;
changeOrderInternal: (
integrationId: string,
index: number,
direction: 'up' | 'down'
) => void;
setGlobalValueText: (index: number, content: string) => void;
setGlobalValueMedia: (
index: number,
media: { id: string; path: string }[]
) => void;
setInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) => void;
addGlobalValueMedia: (
index: number,
media: { id: string; path: string }[]
) => void;
removeGlobalValueMedia: (index: number, mediaIndex: number) => void;
setInternalValueText: (
integrationId: string,
index: number,
content: string
) => void;
addInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) => void;
removeInternalValueMedia: (
integrationId: string,
index: number,
mediaIndex: number
) => void;
setAllIntegrations: (integrations: Integrations[]) => void;
setCurrent: (current: string) => void;
addOrRemoveSelectedIntegration: (
integration: Integrations,
settings: any
) => void;
reset: () => void;
setSelectedIntegrations: (
params: { selectedIntegrations: Integrations; settings: any }[]
) => void;
setTab: (tab: 0 | 1) => void;
setHide: (hide: boolean) => void;
setDate: (date: dayjs.Dayjs) => void;
setRepeater: (repeater: number) => void;
setTags: (tags: { label: string; value: string }[]) => void;
setIsCreateSet: (isCreateSet: boolean) => void;
setTotalChars?: (totalChars: number) => void;
appendInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) => void;
appendGlobalValueMedia: (
index: number,
media: { id: string; path: string }[]
) => void;
setPostComment: (postComment: PostComment) => void;
setActivateExitButton?: (activateExitButton: boolean) => void;
}
const initialState = {
activateExitButton: true,
date: dayjs(),
postComment: PostComment.ALL,
tags: [] as { label: string; value: string }[],
totalChars: 0,
tab: 0 as 0,
isCreateSet: false,
current: 'global',
locked: false,
hide: false,
integrations: [] as Integrations[],
selectedIntegrations: [] as SelectedIntegrations[],
global: [] as Values[],
internal: [] as Internal[],
};
export const useLaunchStore = create<StoreState>()((set) => ({
...initialState,
setCurrent: (current: string) =>
set((state) => ({
current: current,
})),
addOrRemoveSelectedIntegration: (
integration: Integrations,
settings: any
) => {
set((state) => {
const existing = state.selectedIntegrations.find(
(i) => i.integration.id === integration.id
);
if (existing) {
return {
...(existing.integration.id === state.current
? { current: 'global' }
: {}),
selectedIntegrations: state.selectedIntegrations.filter(
(s, index) => s.integration.id !== existing.integration.id
),
};
}
return {
selectedIntegrations: [
...state.selectedIntegrations,
{ integration, settings, ref: createRef() },
],
};
});
},
addGlobalValue: (index: number, value: Values[]) =>
set((state) => {
if (!state.global.length) {
return { global: value };
}
return {
global: state.global.reduce((acc, item, i) => {
acc.push(item);
if (i === index) {
acc.push(...value);
}
return acc;
}, []),
};
}),
// Add value after index, similar to addGlobalValue, but for a speciic integration (index starts from 0)
addInternalValue: (index: number, integrationId: string, value: Values[]) =>
set((state) => {
const integrationIndex = state.internal.findIndex(
(i) => i.integration.id === integrationId
);
if (integrationIndex === -1) {
return {
internal: [
...state.internal,
{
integration: state.selectedIntegrations.find(
(i) => i.integration.id === integrationId
)!.integration,
integrationValue: value,
},
],
};
}
const updatedIntegration = state.internal[integrationIndex];
const newValues = updatedIntegration.integrationValue.reduce(
(acc, item, i) => {
acc.push(item);
if (i === index) {
acc.push(...value);
}
return acc;
},
[] as Values[]
);
return {
internal: state.internal.map((i, idx) =>
idx === integrationIndex ? { ...i, integrationValue: newValues } : i
),
};
}),
deleteGlobalValue: (index: number) =>
set((state) => ({
global: state.global.filter((_, i) => i !== index),
})),
deleteInternalValue: (integrationId: string, index: number) =>
set((state) => {
return {
internal: state.internal.map((i) => {
if (i.integration.id === integrationId) {
return {
...i,
integrationValue: i.integrationValue.filter(
(_, idx) => idx !== index
),
};
}
return i;
}),
};
}),
addRemoveInternal: (integrationId: string) =>
set((state) => {
const integration = state.selectedIntegrations.find(
(i) => i.integration.id === integrationId
);
const findIntegrationIndex = state.internal.findIndex(
(i) => i.integration.id === integrationId
);
if (findIntegrationIndex > -1) {
return {
internal: state.internal.filter(
(i) => i.integration.id !== integrationId
),
};
}
return {
internal: [
...state.internal,
{
integration: integration.integration,
integrationValue: state.global.slice(0).map((p) => p),
},
],
};
}),
changeOrderGlobal: (index: number, direction: 'up' | 'down') =>
set((state) => {
return {
global: arrayMoveImmutable(
state.global,
index,
direction === 'up' ? index - 1 : index + 1
),
};
}),
changeOrderInternal: (
integrationId: string,
index: number,
direction: 'up' | 'down'
) =>
set((state) => {
return {
internal: state.internal.map((item) => {
if (item.integration.id === integrationId) {
return {
...item,
integrationValue: arrayMoveImmutable(
item.integrationValue,
index,
direction === 'up' ? index - 1 : index + 1
),
};
}
return item;
}),
};
}),
setGlobalValueText: (index: number, content: string) =>
set((state) => ({
global: state.global.map((item, i) =>
i === index ? { ...item, content } : item
),
})),
setInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) => {
return set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? {
...item,
integrationValue: item.integrationValue.map((v, i) =>
i === index ? { ...v, media } : v
),
}
: item
),
}));
},
setGlobalValueMedia: (index: number, media: { id: string; path: string }[]) =>
set((state) => ({
global: state.global.map((item, i) =>
i === index ? { ...item, media } : item
),
})),
addGlobalValueMedia: (index: number, media: { id: string; path: string }[]) =>
set((state) => ({
global: state.global.map((item, i) =>
i === index ? { ...item, media: [...item.media, ...media] } : item
),
})),
removeGlobalValueMedia: (index: number, mediaIndex: number) =>
set((state) => ({
global: state.global.map((item, i) =>
i === index
? {
...item,
media: item.media.filter((_, idx) => idx !== mediaIndex),
}
: item
),
})),
setInternalValueText: (
integrationId: string,
index: number,
content: string
) => {
set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? {
...item,
integrationValue: item.integrationValue.map((v, i) =>
i === index ? { ...v, content } : v
),
}
: item
),
}));
},
addInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) =>
set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? {
...item,
integrationValue: item.integrationValue.map((v, i) =>
i === index ? { ...v, media: [...v.media, ...media] } : v
),
}
: item
),
})),
removeInternalValueMedia: (
integrationId: string,
index: number,
mediaIndex: number
) =>
set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? {
...item,
integrationValue: item.integrationValue.map((v, i) =>
i === index
? {
...v,
media: v.media.filter((_, idx) => idx !== mediaIndex),
}
: v
),
}
: item
),
})),
reset: () =>
set((state) => ({
...state,
...initialState,
})),
setAllIntegrations: (integrations: Integrations[]) =>
set((state) => ({
integrations: integrations,
})),
setTab: (tab: 0 | 1) =>
set((state) => ({
tab: tab,
})),
setLocked: (locked: boolean) =>
set((state) => ({
locked: locked,
})),
setHide: (hide: boolean) =>
set((state) => ({
hide: hide,
})),
setDate: (date: dayjs.Dayjs) =>
set((state) => ({
date,
})),
setRepeater: (repeater: number) =>
set((state) => ({
repeater,
})),
setTags: (tags: { label: string; value: string }[]) =>
set((state) => ({
tags,
})),
setIsCreateSet: (isCreateSet: boolean) =>
set((state) => ({
isCreateSet,
})),
setSelectedIntegrations: (
params: { selectedIntegrations: Integrations; settings: any }[]
) =>
set((state) => ({
selectedIntegrations: params.map((p) => ({
integration: p.selectedIntegrations,
settings: p.settings,
ref: createRef(),
})),
})),
setGlobalValue: (value: Values[]) =>
set((state) => ({
global: value,
})),
setInternalValue: (integrationId: string, value: Values[]) =>
set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? { ...item, integrationValue: value }
: item
),
})),
setTotalChars: (totalChars: number) =>
set((state) => ({
totalChars,
})),
appendInternalValueMedia: (
integrationId: string,
index: number,
media: { id: string; path: string }[]
) =>
set((state) => ({
internal: state.internal.map((item) =>
item.integration.id === integrationId
? {
...item,
integrationValue: item.integrationValue.map((v, i) =>
i === index ? { ...v, media: [...v.media, ...media] } : v
),
}
: item
),
})),
appendGlobalValueMedia: (
index: number,
media: { id: string; path: string }[]
) =>
set((state) => ({
global: state.global.map((item, i) =>
i === index ? { ...item, media: [...item.media, ...media] } : item
),
})),
setPostComment: (postComment: PostComment) =>
set((state) => ({
postComment,
})),
setActivateExitButton: (activateExitButton: boolean) =>
set((state) => ({
activateExitButton,
})),
}));