Selects custom color when created
This commit is contained in:
parent
6d82acd23c
commit
53d6065c00
8 changed files with 158 additions and 79 deletions
|
@ -24,17 +24,19 @@ const SAMPLE_CUSTOM_COLOR = {
|
|||
|
||||
const createProps = (): PropsType => ({
|
||||
addCustomColor: action('addCustomColor'),
|
||||
colorSelected: action('colorSelected'),
|
||||
editCustomColor: action('editCustomColor'),
|
||||
getConversationsWithCustomColor: (_: string) => [],
|
||||
i18n,
|
||||
onChatColorReset: action('onChatColorReset'),
|
||||
onSelectColor: action('onSelectColor'),
|
||||
removeCustomColor: action('removeCustomColor'),
|
||||
removeCustomColorOnConversations: action('removeCustomColorOnConversations'),
|
||||
resetAllChatColors: action('resetAllChatColors'),
|
||||
resetDefaultChatColor: action('resetDefaultChatColor'),
|
||||
selectedColor: select('selectedColor', ConversationColors, 'basil' as const),
|
||||
selectedCustomColor: {},
|
||||
setGlobalDefaultConversationColor: action(
|
||||
'setGlobalDefaultConversationColor'
|
||||
),
|
||||
});
|
||||
|
||||
story.add('Default', () => <ChatColorPicker {...createProps()} />);
|
||||
|
|
|
@ -24,48 +24,60 @@ type CustomColorDataType = {
|
|||
};
|
||||
|
||||
export type PropsDataType = {
|
||||
conversationId?: string;
|
||||
customColors?: Record<string, CustomColorType>;
|
||||
getConversationsWithCustomColor: (colorId: string) => Array<ConversationType>;
|
||||
i18n: LocalizerType;
|
||||
isGlobal?: boolean;
|
||||
onChatColorReset?: () => unknown;
|
||||
onSelectColor: (
|
||||
selectedColor?: ConversationColorType;
|
||||
selectedCustomColor: CustomColorDataType;
|
||||
};
|
||||
|
||||
type PropsActionType = {
|
||||
addCustomColor: (
|
||||
color: CustomColorType,
|
||||
nextAction: (uuid: string) => unknown
|
||||
) => unknown;
|
||||
colorSelected: (payload: {
|
||||
conversationId: string;
|
||||
conversationColor?: ConversationColorType;
|
||||
customColorData?: {
|
||||
id: string;
|
||||
value: CustomColorType;
|
||||
};
|
||||
}) => unknown;
|
||||
editCustomColor: (colorId: string, color: CustomColorType) => unknown;
|
||||
removeCustomColor: (colorId: string) => unknown;
|
||||
removeCustomColorOnConversations: (colorId: string) => unknown;
|
||||
resetAllChatColors: () => unknown;
|
||||
resetDefaultChatColor: () => unknown;
|
||||
setGlobalDefaultConversationColor: (
|
||||
color: ConversationColorType,
|
||||
customColorData?: {
|
||||
id: string;
|
||||
value: CustomColorType;
|
||||
}
|
||||
) => unknown;
|
||||
selectedColor?: ConversationColorType;
|
||||
selectedCustomColor: CustomColorDataType;
|
||||
};
|
||||
|
||||
type PropsActionType = {
|
||||
addCustomColor: (color: CustomColorType) => unknown;
|
||||
editCustomColor: (colorId: string, color: CustomColorType) => unknown;
|
||||
removeCustomColor: (colorId: string) => unknown;
|
||||
removeCustomColorOnConversations: (colorId: string) => unknown;
|
||||
resetAllChatColors: () => unknown;
|
||||
resetDefaultChatColor: () => unknown;
|
||||
};
|
||||
|
||||
export type PropsType = PropsDataType & PropsActionType;
|
||||
|
||||
export const ChatColorPicker = ({
|
||||
addCustomColor,
|
||||
colorSelected,
|
||||
conversationId,
|
||||
customColors = {},
|
||||
editCustomColor,
|
||||
getConversationsWithCustomColor,
|
||||
i18n,
|
||||
isGlobal = false,
|
||||
onChatColorReset,
|
||||
onSelectColor,
|
||||
removeCustomColor,
|
||||
removeCustomColorOnConversations,
|
||||
resetAllChatColors,
|
||||
resetDefaultChatColor,
|
||||
selectedColor = ConversationColors[0],
|
||||
selectedCustomColor,
|
||||
setGlobalDefaultConversationColor,
|
||||
}: PropsType): JSX.Element => {
|
||||
const [confirmResetAll, setConfirmResetAll] = useState(false);
|
||||
const [confirmResetWhat, setConfirmResetWhat] = useState(false);
|
||||
|
@ -73,6 +85,30 @@ export const ChatColorPicker = ({
|
|||
CustomColorDataType | undefined
|
||||
>(undefined);
|
||||
|
||||
const onSelectColor = (
|
||||
conversationColor: ConversationColorType,
|
||||
customColorData?: { id: string; value: CustomColorType }
|
||||
): void => {
|
||||
if (conversationId) {
|
||||
colorSelected({
|
||||
conversationId,
|
||||
conversationColor,
|
||||
customColorData,
|
||||
});
|
||||
} else {
|
||||
setGlobalDefaultConversationColor(conversationColor, customColorData);
|
||||
}
|
||||
};
|
||||
|
||||
const onColorAdded = (value: CustomColorType) => {
|
||||
return (id: string) => {
|
||||
onSelectColor('custom', {
|
||||
id,
|
||||
value,
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const renderCustomColorEditorWrapper = () => (
|
||||
<CustomColorEditorWrapper
|
||||
customColorToEdit={customColorToEdit}
|
||||
|
@ -87,7 +123,7 @@ export const ChatColorPicker = ({
|
|||
value: color,
|
||||
});
|
||||
} else {
|
||||
addCustomColor(color);
|
||||
addCustomColor(color, onColorAdded(color));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
@ -192,7 +228,7 @@ export const ChatColorPicker = ({
|
|||
removeCustomColorOnConversations(colorId);
|
||||
}}
|
||||
onDupe={() => {
|
||||
addCustomColor(colorValues);
|
||||
addCustomColor(colorValues, onColorAdded(colorValues));
|
||||
}}
|
||||
onEdit={() => {
|
||||
setCustomColorToEdit({ id: colorId, value: colorValues });
|
||||
|
@ -218,10 +254,12 @@ export const ChatColorPicker = ({
|
|||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
{onChatColorReset ? (
|
||||
{conversationId ? (
|
||||
<PanelRow
|
||||
label={i18n('ChatColorPicker__reset')}
|
||||
onClick={onChatColorReset}
|
||||
onClick={() => {
|
||||
colorSelected({ conversationId });
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
<PanelRow
|
||||
|
|
|
@ -4,17 +4,11 @@
|
|||
import React from 'react';
|
||||
import { Modal } from './Modal';
|
||||
import { LocalizerType } from '../types/Util';
|
||||
import { ConversationColorType } from '../types/Colors';
|
||||
|
||||
type PropsType = {
|
||||
i18n: LocalizerType;
|
||||
isChatColorEditorVisible: boolean;
|
||||
renderChatColorPicker: (actions: {
|
||||
setGlobalDefaultConversationColor: (
|
||||
color: ConversationColorType
|
||||
) => unknown;
|
||||
}) => JSX.Element;
|
||||
setGlobalDefaultConversationColor: (color: ConversationColorType) => unknown;
|
||||
renderChatColorPicker: () => JSX.Element;
|
||||
toggleChatColorEditor: () => unknown;
|
||||
};
|
||||
|
||||
|
@ -22,7 +16,6 @@ export const GlobalModalContainer = ({
|
|||
i18n,
|
||||
isChatColorEditorVisible,
|
||||
renderChatColorPicker,
|
||||
setGlobalDefaultConversationColor,
|
||||
toggleChatColorEditor,
|
||||
}: PropsType): JSX.Element | null => {
|
||||
if (isChatColorEditorVisible) {
|
||||
|
@ -35,9 +28,7 @@ export const GlobalModalContainer = ({
|
|||
onClose={toggleChatColorEditor}
|
||||
title={i18n('ChatColorPicker__global-chat-color')}
|
||||
>
|
||||
{renderChatColorPicker({
|
||||
setGlobalDefaultConversationColor,
|
||||
})}
|
||||
{renderChatColorPicker()}
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -342,6 +342,7 @@ export const getConversationCallMode = (
|
|||
|
||||
// Actions
|
||||
|
||||
const COLOR_SELECTED = 'conversations/COLOR_SELECTED';
|
||||
const COLORS_CHANGED = 'conversations/COLORS_CHANGED';
|
||||
const CUSTOM_COLOR_REMOVED = 'conversations/CUSTOM_COLOR_REMOVED';
|
||||
|
||||
|
@ -377,6 +378,18 @@ type ColorsChangedActionType = {
|
|||
};
|
||||
};
|
||||
};
|
||||
type ColorSelectedPayloadType = {
|
||||
conversationId: string;
|
||||
conversationColor?: ConversationColorType;
|
||||
customColorData?: {
|
||||
id: string;
|
||||
value: CustomColorType;
|
||||
};
|
||||
};
|
||||
export type ColorSelectedActionType = {
|
||||
type: typeof COLOR_SELECTED;
|
||||
payload: ColorSelectedPayloadType;
|
||||
};
|
||||
type CustomColorRemovedActionType = {
|
||||
type: typeof CUSTOM_COLOR_REMOVED;
|
||||
payload: {
|
||||
|
@ -637,6 +650,7 @@ export type ConversationActionType =
|
|||
| ConversationRemovedActionType
|
||||
| ConversationUnloadedActionType
|
||||
| ColorsChangedActionType
|
||||
| ColorSelectedActionType
|
||||
| CustomColorRemovedActionType
|
||||
| CreateGroupFulfilledActionType
|
||||
| CreateGroupPendingActionType
|
||||
|
@ -689,6 +703,7 @@ export const actions = {
|
|||
conversationChanged,
|
||||
conversationRemoved,
|
||||
conversationUnloaded,
|
||||
colorSelected,
|
||||
createGroup,
|
||||
messageChanged,
|
||||
messageDeleted,
|
||||
|
@ -798,6 +813,50 @@ function resetAllChatColors(): ThunkAction<
|
|||
};
|
||||
}
|
||||
|
||||
function colorSelected({
|
||||
conversationId,
|
||||
conversationColor,
|
||||
customColorData,
|
||||
}: ColorSelectedPayloadType): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
unknown,
|
||||
ColorSelectedActionType
|
||||
> {
|
||||
return async dispatch => {
|
||||
// We don't want to trigger a model change because we're updating redux
|
||||
// here manually ourselves. Au revoir Backbone!
|
||||
const conversation = window.ConversationController.get(conversationId);
|
||||
if (conversation) {
|
||||
if (conversationColor) {
|
||||
conversation.attributes.conversationColor = conversationColor;
|
||||
if (customColorData) {
|
||||
conversation.attributes.customColor = customColorData.value;
|
||||
conversation.attributes.customColorId = customColorData.id;
|
||||
} else {
|
||||
delete conversation.attributes.customColor;
|
||||
delete conversation.attributes.customColorId;
|
||||
}
|
||||
} else {
|
||||
delete conversation.attributes.conversationColor;
|
||||
delete conversation.attributes.customColor;
|
||||
delete conversation.attributes.customColorId;
|
||||
}
|
||||
|
||||
await window.Signal.Data.updateConversation(conversation.attributes);
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: COLOR_SELECTED,
|
||||
payload: {
|
||||
conversationId,
|
||||
conversationColor,
|
||||
customColorData,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function cantAddContactToGroup(
|
||||
conversationId: string
|
||||
): CantAddContactToGroupActionType {
|
||||
|
@ -2531,6 +2590,36 @@ export function reducer(
|
|||
return nextState;
|
||||
}
|
||||
|
||||
if (action.type === COLOR_SELECTED) {
|
||||
const { conversationLookup } = state;
|
||||
const {
|
||||
conversationId,
|
||||
conversationColor,
|
||||
customColorData,
|
||||
} = action.payload;
|
||||
|
||||
const existing = conversationLookup[conversationId];
|
||||
if (!existing) {
|
||||
return state;
|
||||
}
|
||||
|
||||
const changed = {
|
||||
...existing,
|
||||
conversationColor,
|
||||
customColor: customColorData?.value,
|
||||
customColorId: customColorData?.id,
|
||||
};
|
||||
|
||||
return {
|
||||
...state,
|
||||
conversationLookup: {
|
||||
...conversationLookup,
|
||||
[conversationId]: changed,
|
||||
},
|
||||
...updateConversationLookups(changed, existing, state),
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === CUSTOM_COLOR_REMOVED) {
|
||||
const { conversationLookup } = state;
|
||||
const { colorId, defaultConversationColor } = action.payload;
|
||||
|
|
|
@ -141,7 +141,8 @@ function getDefaultCustomColorData() {
|
|||
}
|
||||
|
||||
function addCustomColor(
|
||||
payload: CustomColorType
|
||||
customColor: CustomColorType,
|
||||
nextAction: (uuid: string) => unknown
|
||||
): ThunkAction<void, RootStateType, unknown, ItemPutAction> {
|
||||
return (dispatch, getState) => {
|
||||
const { customColors = getDefaultCustomColorData() } = getState().items;
|
||||
|
@ -155,11 +156,12 @@ function addCustomColor(
|
|||
...customColors,
|
||||
colors: {
|
||||
...customColors.colors,
|
||||
[uuid]: payload,
|
||||
[uuid]: customColor,
|
||||
},
|
||||
};
|
||||
|
||||
dispatch(putItem('customColors', nextCustomColors));
|
||||
nextAction(uuid);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
ChatColorPicker,
|
||||
PropsDataType,
|
||||
} from '../../components/ChatColorPicker';
|
||||
import { ConversationColorType, CustomColorType } from '../../types/Colors';
|
||||
import { StateType } from '../reducer';
|
||||
import {
|
||||
getConversationSelector,
|
||||
|
@ -19,15 +18,6 @@ import { getIntl } from '../selectors/user';
|
|||
|
||||
export type SmartChatColorPickerProps = {
|
||||
conversationId?: string;
|
||||
isGlobal?: boolean;
|
||||
onChatColorReset?: () => unknown;
|
||||
onSelectColor: (
|
||||
color: ConversationColorType,
|
||||
customColorData?: {
|
||||
id: string;
|
||||
value: CustomColorType;
|
||||
}
|
||||
) => unknown;
|
||||
};
|
||||
|
||||
const mapStateToProps = (
|
||||
|
|
|
@ -8,19 +8,9 @@ import { GlobalModalContainer } from '../../components/GlobalModalContainer';
|
|||
import { StateType } from '../reducer';
|
||||
import { getIntl } from '../selectors/user';
|
||||
import { SmartChatColorPicker } from './ChatColorPicker';
|
||||
import { ConversationColorType } from '../../types/Colors';
|
||||
|
||||
function renderChatColorPicker({
|
||||
setGlobalDefaultConversationColor,
|
||||
}: {
|
||||
setGlobalDefaultConversationColor: (color: ConversationColorType) => unknown;
|
||||
}): JSX.Element {
|
||||
return (
|
||||
<SmartChatColorPicker
|
||||
isGlobal
|
||||
onSelectColor={setGlobalDefaultConversationColor}
|
||||
/>
|
||||
);
|
||||
function renderChatColorPicker(): JSX.Element {
|
||||
return <SmartChatColorPicker />;
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: StateType) => {
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import { AttachmentType } from '../types/Attachment';
|
||||
import { ConversationColorType, CustomColorType } from '../types/Colors';
|
||||
import { ConversationModel } from '../models/conversations';
|
||||
import { GroupV2PendingMemberType } from '../model-types.d';
|
||||
import { LinkPreviewType } from '../types/message/LinkPreviews';
|
||||
|
@ -3235,28 +3234,6 @@ Whisper.ConversationView = Whisper.View.extend({
|
|||
className: 'panel',
|
||||
JSX: window.Signal.State.Roots.createChatColorPicker(window.reduxStore, {
|
||||
conversationId: conversation.get('id'),
|
||||
onSelectColor: (
|
||||
color: ConversationColorType,
|
||||
customColorData?: {
|
||||
id: string;
|
||||
value: CustomColorType;
|
||||
}
|
||||
) => {
|
||||
conversation.set('conversationColor', color);
|
||||
if (customColorData) {
|
||||
conversation.set('customColor', customColorData.value);
|
||||
conversation.set('customColorId', customColorData.id);
|
||||
} else {
|
||||
conversation.unset('customColor');
|
||||
conversation.unset('customColorId');
|
||||
}
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
},
|
||||
onChatColorReset: () => {
|
||||
conversation.set('conversationColor', undefined);
|
||||
conversation.unset('customColor');
|
||||
window.Signal.Data.updateConversation(conversation.attributes);
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue