Support duplicate attachments in lightbox

This commit is contained in:
Fedor Indutny 2023-09-26 17:38:21 +02:00 committed by GitHub
parent b885ced90d
commit 1a2976dae4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 45 deletions

View file

@ -19,7 +19,7 @@ export type Props = {
loadRecentMediaItems: (id: string, limit: number) => void; loadRecentMediaItems: (id: string, limit: number) => void;
showAllMedia: () => void; showAllMedia: () => void;
showLightboxWithMedia: ( showLightboxWithMedia: (
selectedAttachmentPath: string | undefined, selectedIndex: number,
media: ReadonlyArray<ReadonlyDeep<MediaItemType>> media: ReadonlyArray<ReadonlyDeep<MediaItemType>>
) => void; ) => void;
}; };
@ -66,9 +66,7 @@ export function ConversationDetailsMediaList({
key={`${mediaItem.message.id}-${mediaItem.index}`} key={`${mediaItem.message.id}-${mediaItem.index}`}
mediaItem={mediaItem} mediaItem={mediaItem}
i18n={i18n} i18n={i18n}
onClick={() => onClick={() => showLightboxWithMedia(mediaItem.index, mediaItems)}
showLightboxWithMedia(mediaItem.attachment.path, mediaItems)
}
/> />
))} ))}
</div> </div>

View file

@ -35,7 +35,7 @@ export function AttachmentSection({
const { message, index, attachment } = mediaItem; const { message, index, attachment } = mediaItem;
const onClick = () => { const onClick = () => {
onItemClick({ type, message, attachment }); onItemClick({ type, message, attachment, index: mediaItem.index });
}; };
switch (type) { switch (type) {

View file

@ -29,7 +29,7 @@ export type Props = {
media: Array<MediaItemType>; media: Array<MediaItemType>;
saveAttachment: SaveAttachmentActionCreatorType; saveAttachment: SaveAttachmentActionCreatorType;
showLightboxWithMedia: ( showLightboxWithMedia: (
selectedAttachmentPath: string | undefined, selectedIndex: number,
media: Array<MediaItemType> media: Array<MediaItemType>
) => void; ) => void;
}; };
@ -106,7 +106,7 @@ function MediaSection({
} }
case 'media': { case 'media': {
showLightboxWithMedia(event.attachment.path, media); showLightboxWithMedia(event.index, media);
break; break;
} }

View file

@ -7,5 +7,6 @@ import type { AttachmentType } from '../../../../types/Attachment';
export type ItemClickEvent = { export type ItemClickEvent = {
message: Pick<MessageAttributesType, 'sent_at'>; message: Pick<MessageAttributesType, 'sent_at'>;
attachment: AttachmentType; attachment: AttachmentType;
index: number;
type: 'media' | 'documents'; type: 'media' | 'documents';
}; };

View file

@ -48,12 +48,12 @@ export type LightboxStateType =
media: ReadonlyArray<ReadonlyDeep<MediaItemType>>; media: ReadonlyArray<ReadonlyDeep<MediaItemType>>;
hasPrevMessage: boolean; hasPrevMessage: boolean;
hasNextMessage: boolean; hasNextMessage: boolean;
selectedAttachmentPath: string | undefined; selectedIndex: number | undefined;
}; };
const CLOSE_LIGHTBOX = 'lightbox/CLOSE'; const CLOSE_LIGHTBOX = 'lightbox/CLOSE';
const SHOW_LIGHTBOX = 'lightbox/SHOW'; const SHOW_LIGHTBOX = 'lightbox/SHOW';
const SET_SELECTED_LIGHTBOX_PATH = 'lightbox/SET_SELECTED_LIGHTBOX_PATH'; const SET_SELECTED_LIGHTBOX_INDEX = 'lightbox/SET_SELECTED_LIGHTBOX_INDEX';
type CloseLightboxActionType = ReadonlyDeep<{ type CloseLightboxActionType = ReadonlyDeep<{
type: typeof CLOSE_LIGHTBOX; type: typeof CLOSE_LIGHTBOX;
@ -67,13 +67,13 @@ type ShowLightboxActionType = {
media: ReadonlyArray<ReadonlyDeep<MediaItemType>>; media: ReadonlyArray<ReadonlyDeep<MediaItemType>>;
hasPrevMessage: boolean; hasPrevMessage: boolean;
hasNextMessage: boolean; hasNextMessage: boolean;
selectedAttachmentPath: string | undefined; selectedIndex: number | undefined;
}; };
}; };
type SetSelectedLightboxPathActionType = ReadonlyDeep<{ type SetSelectedLightboxIndexActionType = ReadonlyDeep<{
type: typeof SET_SELECTED_LIGHTBOX_PATH; type: typeof SET_SELECTED_LIGHTBOX_INDEX;
payload: string | undefined; payload: number;
}>; }>;
// eslint-disable-next-line local-rules/type-alias-readonlydeep // eslint-disable-next-line local-rules/type-alias-readonlydeep
@ -83,7 +83,7 @@ type LightboxActionType =
| MessageDeletedActionType | MessageDeletedActionType
| MessageExpiredActionType | MessageExpiredActionType
| ShowLightboxActionType | ShowLightboxActionType
| SetSelectedLightboxPathActionType; | SetSelectedLightboxIndexActionType;
function closeLightbox(): ThunkAction< function closeLightbox(): ThunkAction<
void, void,
@ -116,7 +116,7 @@ function closeLightbox(): ThunkAction<
} }
function showLightboxWithMedia( function showLightboxWithMedia(
selectedAttachmentPath: string | undefined, selectedIndex: number | undefined,
media: ReadonlyArray<ReadonlyDeep<MediaItemType>> media: ReadonlyArray<ReadonlyDeep<MediaItemType>>
): ShowLightboxActionType { ): ShowLightboxActionType {
return { return {
@ -124,7 +124,7 @@ function showLightboxWithMedia(
payload: { payload: {
isViewOnce: false, isViewOnce: false,
media, media,
selectedAttachmentPath, selectedIndex,
hasPrevMessage: false, hasPrevMessage: false,
hasNextMessage: false, hasNextMessage: false,
}, },
@ -202,7 +202,7 @@ function showLightboxForViewOnceMedia(
payload: { payload: {
isViewOnce: true, isViewOnce: true,
media, media,
selectedAttachmentPath: undefined, selectedIndex: undefined,
hasPrevMessage: false, hasPrevMessage: false,
hasNextMessage: false, hasNextMessage: false,
}, },
@ -335,7 +335,7 @@ function showLightbox(opts: {
payload: { payload: {
isViewOnce: false, isViewOnce: false,
media, media,
selectedAttachmentPath: attachment.path, selectedIndex: media.findIndex(({ path }) => path === attachment.path),
hasPrevMessage: hasPrevMessage:
older.length > 0 && filterValidAttachments(older[0]).length > 0, older.length > 0 && filterValidAttachments(older[0]).length > 0,
hasNextMessage: hasNextMessage:
@ -464,12 +464,12 @@ function showLightboxForPrevMessage(): ThunkAction<
return showLightboxForAdjacentMessage(AdjacentMessageDirection.Previous); return showLightboxForAdjacentMessage(AdjacentMessageDirection.Previous);
} }
function setSelectedLightboxPath( function setSelectedLightboxIndex(
path: string | undefined index: number
): SetSelectedLightboxPathActionType { ): SetSelectedLightboxIndexActionType {
return { return {
type: SET_SELECTED_LIGHTBOX_PATH, type: SET_SELECTED_LIGHTBOX_INDEX,
payload: path, payload: index,
}; };
} }
@ -480,7 +480,7 @@ export const actions = {
showLightboxWithMedia, showLightboxWithMedia,
showLightboxForPrevMessage, showLightboxForPrevMessage,
showLightboxForNextMessage, showLightboxForNextMessage,
setSelectedLightboxPath, setSelectedLightboxIndex,
}; };
export const useLightboxActions = (): BoundActionCreatorsMapObject< export const useLightboxActions = (): BoundActionCreatorsMapObject<
@ -508,14 +508,17 @@ export function reducer(
}; };
} }
if (action.type === SET_SELECTED_LIGHTBOX_PATH) { if (action.type === SET_SELECTED_LIGHTBOX_INDEX) {
if (!state.isShowingLightbox) { if (!state.isShowingLightbox) {
return state; return state;
} }
return { return {
...state, ...state,
selectedAttachmentPath: action.payload, selectedIndex: Math.max(
0,
Math.min(state.media.length - 1, action.payload)
),
}; };
} }

View file

@ -27,11 +27,7 @@ export const getSelectedIndex = createSelector(
return 0; return 0;
} }
const index = state.media.findIndex( return state.selectedIndex ?? 0;
item => item.attachment.path === state.selectedAttachmentPath
);
return index > 0 ? index : 0;
} }
); );

View file

@ -32,7 +32,7 @@ export function SmartLightbox(): JSX.Element | null {
closeLightbox, closeLightbox,
showLightboxForNextMessage, showLightboxForNextMessage,
showLightboxForPrevMessage, showLightboxForPrevMessage,
setSelectedLightboxPath, setSelectedLightboxIndex,
} = useLightboxActions(); } = useLightboxActions();
const { toggleForwardMessagesModal } = useGlobalModalActions(); const { toggleForwardMessagesModal } = useGlobalModalActions();
const { pauseVoiceNotePlayer } = useAudioPlayerActions(); const { pauseVoiceNotePlayer } = useAudioPlayerActions();
@ -58,12 +58,11 @@ export function SmartLightbox(): JSX.Element | null {
} }
return; return;
} }
setSelectedLightboxPath(media[selectedIndex - 1]?.attachment.path); setSelectedLightboxIndex(selectedIndex - 1);
}, [ }, [
showLightboxForPrevMessage, showLightboxForPrevMessage,
media,
selectedIndex, selectedIndex,
setSelectedLightboxPath, setSelectedLightboxIndex,
hasPrevMessage, hasPrevMessage,
]); ]);
@ -74,22 +73,15 @@ export function SmartLightbox(): JSX.Element | null {
} }
return; return;
} }
setSelectedLightboxPath(media[selectedIndex + 1]?.attachment.path); setSelectedLightboxIndex(selectedIndex + 1);
}, [ }, [
showLightboxForNextMessage, showLightboxForNextMessage,
media, media,
selectedIndex, selectedIndex,
setSelectedLightboxPath, setSelectedLightboxIndex,
hasNextMessage, hasNextMessage,
]); ]);
const onSelectAttachment = useCallback(
(newIndex: number) => {
setSelectedLightboxPath(media[newIndex]?.attachment.path);
},
[setSelectedLightboxPath, media]
);
if (!isShowingLightbox) { if (!isShowingLightbox) {
return null; return null;
} }
@ -107,7 +99,7 @@ export function SmartLightbox(): JSX.Element | null {
onMediaPlaybackStart={pauseVoiceNotePlayer} onMediaPlaybackStart={pauseVoiceNotePlayer}
onPrevAttachment={onPrevAttachment} onPrevAttachment={onPrevAttachment}
onNextAttachment={onNextAttachment} onNextAttachment={onNextAttachment}
onSelectAttachment={onSelectAttachment} onSelectAttachment={setSelectedLightboxIndex}
hasNextMessage={hasNextMessage} hasNextMessage={hasNextMessage}
hasPrevMessage={hasPrevMessage} hasPrevMessage={hasPrevMessage}
/> />