Sticky Dates: Support opening history calendar
This commit is contained in:
parent
b9dbcab72c
commit
36c4901e5f
@ -4,6 +4,7 @@ export { default as ForwardPicker } from '../components/main/ForwardPicker';
|
|||||||
export { default as Errors } from '../components/main/Errors';
|
export { default as Errors } from '../components/main/Errors';
|
||||||
export { default as Notifications } from '../components/main/Notifications';
|
export { default as Notifications } from '../components/main/Notifications';
|
||||||
export { default as SafeLinkModal } from '../components/main/SafeLinkModal';
|
export { default as SafeLinkModal } from '../components/main/SafeLinkModal';
|
||||||
|
export { default as HistoryCalendar } from '../components/main/HistoryCalendar';
|
||||||
|
|
||||||
export { default as CalendarModal } from '../components/common/CalendarModal';
|
export { default as CalendarModal } from '../components/common/CalendarModal';
|
||||||
export { default as DeleteMessageModal } from '../components/common/DeleteMessageModal';
|
export { default as DeleteMessageModal } from '../components/common/DeleteMessageModal';
|
||||||
|
|||||||
16
src/components/main/HistoryCalendar.async.tsx
Normal file
16
src/components/main/HistoryCalendar.async.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import React, { FC, memo } from '../../lib/teact/teact';
|
||||||
|
import { Bundles } from '../../util/moduleLoader';
|
||||||
|
|
||||||
|
import { OwnProps } from './HistoryCalendar';
|
||||||
|
|
||||||
|
import useModuleLoader from '../../hooks/useModuleLoader';
|
||||||
|
|
||||||
|
const HistoryCalendarAsync: FC<OwnProps> = (props) => {
|
||||||
|
const { isOpen } = props;
|
||||||
|
const HistoryCalendar = useModuleLoader(Bundles.Extra, 'HistoryCalendar', !isOpen);
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||||
|
return HistoryCalendar ? <HistoryCalendar {...props} /> : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(HistoryCalendarAsync);
|
||||||
52
src/components/main/HistoryCalendar.tsx
Normal file
52
src/components/main/HistoryCalendar.tsx
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
||||||
|
import { withGlobal } from '../../lib/teact/teactn';
|
||||||
|
|
||||||
|
import { GlobalActions } from '../../global/types';
|
||||||
|
|
||||||
|
import { pick } from '../../util/iteratees';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
|
import CalendarModal from '../common/CalendarModal';
|
||||||
|
|
||||||
|
export type OwnProps = {
|
||||||
|
isOpen: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type StateProps = {
|
||||||
|
selectedAt?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type DispatchProps = Pick<GlobalActions, 'searchMessagesByDate' | 'closeHistoryCalendar'>;
|
||||||
|
|
||||||
|
const HistoryCalendar: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||||
|
isOpen, selectedAt, searchMessagesByDate, closeHistoryCalendar,
|
||||||
|
}) => {
|
||||||
|
const handleJumpToDate = useCallback((date: Date) => {
|
||||||
|
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
|
||||||
|
closeHistoryCalendar();
|
||||||
|
}, [closeHistoryCalendar, searchMessagesByDate]);
|
||||||
|
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CalendarModal
|
||||||
|
isOpen={isOpen}
|
||||||
|
selectedAt={selectedAt}
|
||||||
|
isPastMode
|
||||||
|
submitButtonLabel={lang('JumpToDate')}
|
||||||
|
onClose={closeHistoryCalendar}
|
||||||
|
onSubmit={handleJumpToDate}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(withGlobal<OwnProps>(
|
||||||
|
(global): StateProps => {
|
||||||
|
return {
|
||||||
|
selectedAt: global.historyCalendarSelectedAt,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||||
|
'searchMessagesByDate', 'closeHistoryCalendar',
|
||||||
|
]),
|
||||||
|
)(HistoryCalendar));
|
||||||
@ -30,6 +30,7 @@ import Notifications from './Notifications.async';
|
|||||||
import Errors from './Errors.async';
|
import Errors from './Errors.async';
|
||||||
import ForwardPicker from './ForwardPicker.async';
|
import ForwardPicker from './ForwardPicker.async';
|
||||||
import SafeLinkModal from './SafeLinkModal.async';
|
import SafeLinkModal from './SafeLinkModal.async';
|
||||||
|
import HistoryCalendar from './HistoryCalendar.async';
|
||||||
|
|
||||||
import './Main.scss';
|
import './Main.scss';
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ type StateProps = {
|
|||||||
hasErrors: boolean;
|
hasErrors: boolean;
|
||||||
audioMessage?: ApiMessage;
|
audioMessage?: ApiMessage;
|
||||||
safeLinkModalUrl?: string;
|
safeLinkModalUrl?: string;
|
||||||
|
isHistoryCalendarOpen: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, 'loadAnimatedEmojis'>;
|
type DispatchProps = Pick<GlobalActions, 'loadAnimatedEmojis'>;
|
||||||
@ -58,7 +60,6 @@ let DEBUG_isLogged = false;
|
|||||||
|
|
||||||
const Main: FC<StateProps & DispatchProps> = ({
|
const Main: FC<StateProps & DispatchProps> = ({
|
||||||
lastSyncTime,
|
lastSyncTime,
|
||||||
loadAnimatedEmojis,
|
|
||||||
isLeftColumnShown,
|
isLeftColumnShown,
|
||||||
isRightColumnShown,
|
isRightColumnShown,
|
||||||
isMediaViewerOpen,
|
isMediaViewerOpen,
|
||||||
@ -68,6 +69,8 @@ const Main: FC<StateProps & DispatchProps> = ({
|
|||||||
hasErrors,
|
hasErrors,
|
||||||
audioMessage,
|
audioMessage,
|
||||||
safeLinkModalUrl,
|
safeLinkModalUrl,
|
||||||
|
isHistoryCalendarOpen,
|
||||||
|
loadAnimatedEmojis,
|
||||||
}) => {
|
}) => {
|
||||||
if (DEBUG && !DEBUG_isLogged) {
|
if (DEBUG && !DEBUG_isLogged) {
|
||||||
DEBUG_isLogged = true;
|
DEBUG_isLogged = true;
|
||||||
@ -171,6 +174,7 @@ const Main: FC<StateProps & DispatchProps> = ({
|
|||||||
<Errors isOpen={hasErrors} />
|
<Errors isOpen={hasErrors} />
|
||||||
{audioMessage && <AudioPlayer key={audioMessage.id} message={audioMessage} noUi />}
|
{audioMessage && <AudioPlayer key={audioMessage.id} message={audioMessage} noUi />}
|
||||||
<SafeLinkModal url={safeLinkModalUrl} />
|
<SafeLinkModal url={safeLinkModalUrl} />
|
||||||
|
<HistoryCalendar isOpen={isHistoryCalendarOpen} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -206,6 +210,7 @@ export default memo(withGlobal(
|
|||||||
hasErrors: Boolean(global.errors.length),
|
hasErrors: Boolean(global.errors.length),
|
||||||
audioMessage,
|
audioMessage,
|
||||||
safeLinkModalUrl: global.safeLinkModalUrl,
|
safeLinkModalUrl: global.safeLinkModalUrl,
|
||||||
|
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, ['loadAnimatedEmojis']),
|
(setGlobal, actions): DispatchProps => pick(actions, ['loadAnimatedEmojis']),
|
||||||
|
|||||||
@ -186,11 +186,23 @@
|
|||||||
|
|
||||||
body:not(.is-scrolling-messages) &.stuck {
|
body:not(.is-scrolling-messages) &.stuck {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
|
span {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.animation-level-0 & {
|
body.animation-level-0 & {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.interactive {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.scrolled .sticky-date {
|
&.scrolled .sticky-date {
|
||||||
|
|||||||
@ -22,7 +22,8 @@ import {
|
|||||||
selectScrollOffset,
|
selectScrollOffset,
|
||||||
selectThreadTopMessageId,
|
selectThreadTopMessageId,
|
||||||
selectFirstMessageId,
|
selectFirstMessageId,
|
||||||
selectScheduledMessages, selectCurrentMessageIds,
|
selectScheduledMessages,
|
||||||
|
selectCurrentMessageIds,
|
||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import {
|
import {
|
||||||
getMessageOriginalId,
|
getMessageOriginalId,
|
||||||
@ -92,7 +93,7 @@ type StateProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'loadViewportMessages' | 'markMessageListRead' | 'markMessagesRead' | 'setScrollOffset'
|
'loadViewportMessages' | 'markMessageListRead' | 'markMessagesRead' | 'setScrollOffset' | 'openHistoryCalendar'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
const BOTTOM_THRESHOLD = 100;
|
const BOTTOM_THRESHOLD = 100;
|
||||||
@ -138,6 +139,7 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
botDescription,
|
botDescription,
|
||||||
threadTopMessageId,
|
threadTopMessageId,
|
||||||
hasLinkedChat,
|
hasLinkedChat,
|
||||||
|
openHistoryCalendar,
|
||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
@ -557,9 +559,10 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
type,
|
type,
|
||||||
threadTopMessageId,
|
threadTopMessageId,
|
||||||
threadFirstMessageId,
|
threadFirstMessageId,
|
||||||
hasLinkedChat,
|
Boolean(hasLinkedChat),
|
||||||
messageGroups ? type === 'scheduled' : false,
|
messageGroups ? type === 'scheduled' : false,
|
||||||
!messageGroups || !shouldAnimateAppearanceRef.current,
|
!messageGroups || !shouldAnimateAppearanceRef.current,
|
||||||
|
openHistoryCalendar,
|
||||||
)}
|
)}
|
||||||
</MessageScroll>
|
</MessageScroll>
|
||||||
) : (
|
) : (
|
||||||
@ -580,11 +583,12 @@ function renderMessages(
|
|||||||
memoFirstUnreadIdRef: { current: number | undefined },
|
memoFirstUnreadIdRef: { current: number | undefined },
|
||||||
threadId: number,
|
threadId: number,
|
||||||
type: MessageListType,
|
type: MessageListType,
|
||||||
threadTopMessageId?: number,
|
threadTopMessageId: number | undefined,
|
||||||
threadFirstMessageId?: number,
|
threadFirstMessageId: number | undefined,
|
||||||
hasLinkedChat?: boolean,
|
hasLinkedChat: boolean,
|
||||||
isSchedule = false,
|
isSchedule: boolean,
|
||||||
noAppearanceAnimation = false,
|
noAppearanceAnimation: boolean,
|
||||||
|
openHistoryCalendar: Function,
|
||||||
) {
|
) {
|
||||||
const unreadDivider = (
|
const unreadDivider = (
|
||||||
<div className={buildClassName(UNREAD_DIVIDER_CLASS, 'local-action-message')} key="unread-messages">
|
<div className={buildClassName(UNREAD_DIVIDER_CLASS, 'local-action-message')} key="unread-messages">
|
||||||
@ -701,7 +705,11 @@ function renderMessages(
|
|||||||
key={dateGroup.datetime}
|
key={dateGroup.datetime}
|
||||||
teactFastList
|
teactFastList
|
||||||
>
|
>
|
||||||
<div className="sticky-date" key="date-header">
|
<div
|
||||||
|
className={buildClassName('sticky-date', !isSchedule && 'interactive')}
|
||||||
|
key="date-header"
|
||||||
|
onClick={!isSchedule ? () => openHistoryCalendar({ selectedAt: dateGroup.datetime }) : undefined}
|
||||||
|
>
|
||||||
<span dir="auto">
|
<span dir="auto">
|
||||||
{isSchedule && dateGroup.originalDate === SCHEDULED_WHEN_ONLINE && (
|
{isSchedule && dateGroup.originalDate === SCHEDULED_WHEN_ONLINE && (
|
||||||
lang('MessageScheduledUntilOnline')
|
lang('MessageScheduledUntilOnline')
|
||||||
@ -785,5 +793,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'markMessageListRead',
|
'markMessageListRead',
|
||||||
'markMessagesRead',
|
'markMessagesRead',
|
||||||
'setScrollOffset',
|
'setScrollOffset',
|
||||||
|
'openHistoryCalendar',
|
||||||
]),
|
]),
|
||||||
)(MessageList));
|
)(MessageList));
|
||||||
|
|||||||
@ -9,12 +9,10 @@ import { GlobalActions } from '../../global/types';
|
|||||||
import { debounce } from '../../util/schedulers';
|
import { debounce } from '../../util/schedulers';
|
||||||
import { selectCurrentTextSearch, selectCurrentChat } from '../../modules/selectors';
|
import { selectCurrentTextSearch, selectCurrentChat } from '../../modules/selectors';
|
||||||
import { pick } from '../../util/iteratees';
|
import { pick } from '../../util/iteratees';
|
||||||
import useFlag from '../../hooks/useFlag';
|
import { getDayStartAt } from '../../util/dateFormat';
|
||||||
import useLang from '../../hooks/useLang';
|
|
||||||
|
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
import SearchInput from '../ui/SearchInput';
|
import SearchInput from '../ui/SearchInput';
|
||||||
import CalendarModal from '../common/CalendarModal';
|
|
||||||
|
|
||||||
import './MobileSearch.scss';
|
import './MobileSearch.scss';
|
||||||
|
|
||||||
@ -28,10 +26,11 @@ type StateProps = {
|
|||||||
query?: string;
|
query?: string;
|
||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
foundIds?: number[];
|
foundIds?: number[];
|
||||||
|
isHistoryCalendarOpen?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'setLocalTextSearchQuery' | 'searchTextMessagesLocal' | 'closeLocalTextSearch' | 'searchMessagesByDate' |
|
'setLocalTextSearchQuery' | 'searchTextMessagesLocal' | 'closeLocalTextSearch' | 'openHistoryCalendar' |
|
||||||
'focusMessage'
|
'focusMessage'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
@ -43,16 +42,16 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
query,
|
query,
|
||||||
totalCount,
|
totalCount,
|
||||||
foundIds,
|
foundIds,
|
||||||
|
isHistoryCalendarOpen,
|
||||||
setLocalTextSearchQuery,
|
setLocalTextSearchQuery,
|
||||||
searchTextMessagesLocal,
|
searchTextMessagesLocal,
|
||||||
focusMessage,
|
focusMessage,
|
||||||
closeLocalTextSearch,
|
closeLocalTextSearch,
|
||||||
searchMessagesByDate,
|
openHistoryCalendar,
|
||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
const [focusedIndex, setFocusedIndex] = useState(0);
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
||||||
const [isCalendarOpen, openCalendar, closeCalendar] = useFlag();
|
|
||||||
|
|
||||||
// Fix for iOS keyboard
|
// Fix for iOS keyboard
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -113,7 +112,7 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const searchInput = document.querySelector<HTMLInputElement>('#MobileSearch input')!;
|
const searchInput = document.querySelector<HTMLInputElement>('#MobileSearch input')!;
|
||||||
searchInput.blur();
|
searchInput.blur();
|
||||||
}, [isCalendarOpen]);
|
}, [isHistoryCalendarOpen]);
|
||||||
|
|
||||||
const handleMessageSearchQueryChange = useCallback((newQuery: string) => {
|
const handleMessageSearchQueryChange = useCallback((newQuery: string) => {
|
||||||
setLocalTextSearchQuery({ query: newQuery });
|
setLocalTextSearchQuery({ query: newQuery });
|
||||||
@ -123,11 +122,6 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
}
|
}
|
||||||
}, [searchTextMessagesLocal, setLocalTextSearchQuery]);
|
}, [searchTextMessagesLocal, setLocalTextSearchQuery]);
|
||||||
|
|
||||||
const handleJumpToDate = useCallback((date: Date) => {
|
|
||||||
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
|
|
||||||
closeCalendar();
|
|
||||||
}, [closeCalendar, searchMessagesByDate]);
|
|
||||||
|
|
||||||
const handleUp = useCallback(() => {
|
const handleUp = useCallback(() => {
|
||||||
if (chat && foundIds) {
|
if (chat && foundIds) {
|
||||||
const newFocusIndex = focusedIndex + 1;
|
const newFocusIndex = focusedIndex + 1;
|
||||||
@ -144,8 +138,6 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
}
|
}
|
||||||
}, [chat, focusedIndex, focusMessage, foundIds]);
|
}, [chat, focusedIndex, focusMessage, foundIds]);
|
||||||
|
|
||||||
const lang = useLang();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="MobileSearch" className={isActive ? 'active' : ''}>
|
<div id="MobileSearch" className={isActive ? 'active' : ''}>
|
||||||
<div className="header">
|
<div className="header">
|
||||||
@ -178,7 +170,7 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
round
|
round
|
||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
onClick={openCalendar}
|
onClick={() => openHistoryCalendar({ selectedAt: getDayStartAt(Date.now()) })}
|
||||||
ariaLabel="Search messages by date"
|
ariaLabel="Search messages by date"
|
||||||
>
|
>
|
||||||
<i className="icon-calendar" />
|
<i className="icon-calendar" />
|
||||||
@ -204,13 +196,6 @@ const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
|
|||||||
<i className="icon-down" />
|
<i className="icon-down" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<CalendarModal
|
|
||||||
isOpen={isCalendarOpen}
|
|
||||||
isPastMode
|
|
||||||
submitButtonLabel={lang('JumpToDate')}
|
|
||||||
onClose={closeCalendar}
|
|
||||||
onSubmit={handleJumpToDate}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -230,6 +215,7 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
query,
|
query,
|
||||||
totalCount,
|
totalCount,
|
||||||
foundIds,
|
foundIds,
|
||||||
|
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||||
@ -237,6 +223,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'searchTextMessagesLocal',
|
'searchTextMessagesLocal',
|
||||||
'focusMessage',
|
'focusMessage',
|
||||||
'closeLocalTextSearch',
|
'closeLocalTextSearch',
|
||||||
'searchMessagesByDate',
|
'openHistoryCalendar',
|
||||||
]),
|
]),
|
||||||
)(MobileSearchFooter));
|
)(MobileSearchFooter));
|
||||||
|
|||||||
@ -19,14 +19,13 @@ import {
|
|||||||
} from '../../modules/selectors';
|
} from '../../modules/selectors';
|
||||||
import { isChatAdmin, isChatChannel, isChatPrivate } from '../../modules/helpers';
|
import { isChatAdmin, isChatChannel, isChatPrivate } from '../../modules/helpers';
|
||||||
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
|
||||||
import useFlag from '../../hooks/useFlag';
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
|
|
||||||
import CalendarModal from '../common/CalendarModal.async';
|
|
||||||
import SearchInput from '../ui/SearchInput';
|
import SearchInput from '../ui/SearchInput';
|
||||||
import Button from '../ui/Button';
|
import Button from '../ui/Button';
|
||||||
import Transition from '../ui/Transition';
|
import Transition from '../ui/Transition';
|
||||||
import './RightHeader.scss';
|
import './RightHeader.scss';
|
||||||
|
import { getDayStartAt } from '../../util/dateFormat';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
chatId?: number;
|
chatId?: number;
|
||||||
@ -52,7 +51,7 @@ type StateProps = {
|
|||||||
|
|
||||||
type DispatchProps = Pick<GlobalActions, (
|
type DispatchProps = Pick<GlobalActions, (
|
||||||
'setLocalTextSearchQuery' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
|
'setLocalTextSearchQuery' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
|
||||||
'searchTextMessagesLocal' | 'toggleManagement' | 'searchMessagesByDate'
|
'searchTextMessagesLocal' | 'toggleManagement' | 'openHistoryCalendar'
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
const COLUMN_CLOSE_DELAY_MS = 300;
|
const COLUMN_CLOSE_DELAY_MS = 300;
|
||||||
@ -102,13 +101,11 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
setGifSearchQuery,
|
setGifSearchQuery,
|
||||||
searchTextMessagesLocal,
|
searchTextMessagesLocal,
|
||||||
toggleManagement,
|
toggleManagement,
|
||||||
searchMessagesByDate,
|
openHistoryCalendar,
|
||||||
}) => {
|
}) => {
|
||||||
// eslint-disable-next-line no-null/no-null
|
// eslint-disable-next-line no-null/no-null
|
||||||
const backButtonRef = useRef<HTMLDivElement>(null);
|
const backButtonRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [isCalendarOpen, openCalendar, closeCalendar] = useFlag();
|
|
||||||
|
|
||||||
const handleMessageSearchQueryChange = useCallback((query: string) => {
|
const handleMessageSearchQueryChange = useCallback((query: string) => {
|
||||||
setLocalTextSearchQuery({ query });
|
setLocalTextSearchQuery({ query });
|
||||||
|
|
||||||
@ -117,11 +114,6 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
}
|
}
|
||||||
}, [searchTextMessagesLocal, setLocalTextSearchQuery]);
|
}, [searchTextMessagesLocal, setLocalTextSearchQuery]);
|
||||||
|
|
||||||
const handleJumpToDate = useCallback((date: Date) => {
|
|
||||||
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
|
|
||||||
closeCalendar();
|
|
||||||
}, [closeCalendar, searchMessagesByDate]);
|
|
||||||
|
|
||||||
const handleStickerSearchQueryChange = useCallback((query: string) => {
|
const handleStickerSearchQueryChange = useCallback((query: string) => {
|
||||||
setStickerSearchQuery({ query });
|
setStickerSearchQuery({ query });
|
||||||
}, [setStickerSearchQuery]);
|
}, [setStickerSearchQuery]);
|
||||||
@ -205,7 +197,7 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
round
|
round
|
||||||
size="smaller"
|
size="smaller"
|
||||||
color="translucent"
|
color="translucent"
|
||||||
onClick={openCalendar}
|
onClick={() => openHistoryCalendar({ selectedAt: getDayStartAt(Date.now()) })}
|
||||||
ariaLabel="Search messages by date"
|
ariaLabel="Search messages by date"
|
||||||
>
|
>
|
||||||
<i className="icon-calendar" />
|
<i className="icon-calendar" />
|
||||||
@ -312,15 +304,6 @@ const RightHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
|||||||
>
|
>
|
||||||
{renderHeaderContent}
|
{renderHeaderContent}
|
||||||
</Transition>
|
</Transition>
|
||||||
{!IS_MOBILE_SCREEN && (
|
|
||||||
<CalendarModal
|
|
||||||
isOpen={isCalendarOpen}
|
|
||||||
isPastMode
|
|
||||||
submitButtonLabel={lang('JumpToDate')}
|
|
||||||
onClose={closeCalendar}
|
|
||||||
onSubmit={handleJumpToDate}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -356,6 +339,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
'setGifSearchQuery',
|
'setGifSearchQuery',
|
||||||
'searchTextMessagesLocal',
|
'searchTextMessagesLocal',
|
||||||
'toggleManagement',
|
'toggleManagement',
|
||||||
'searchMessagesByDate',
|
'openHistoryCalendar',
|
||||||
]),
|
]),
|
||||||
)(RightHeader));
|
)(RightHeader));
|
||||||
|
|||||||
@ -389,6 +389,7 @@ export type GlobalState = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
safeLinkModalUrl?: string;
|
safeLinkModalUrl?: string;
|
||||||
|
historyCalendarSelectedAt?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ActionTypes = (
|
export type ActionTypes = (
|
||||||
@ -397,7 +398,7 @@ export type ActionTypes = (
|
|||||||
'showNotification' | 'dismissNotification' | 'showError' | 'dismissError' |
|
'showNotification' | 'dismissNotification' | 'showError' | 'dismissError' |
|
||||||
// ui
|
// ui
|
||||||
'toggleChatInfo' | 'setIsUiReady' | 'addRecentEmoji' | 'addRecentSticker' | 'toggleLeftColumn' |
|
'toggleChatInfo' | 'setIsUiReady' | 'addRecentEmoji' | 'addRecentSticker' | 'toggleLeftColumn' |
|
||||||
'toggleSafeLinkModal' |
|
'toggleSafeLinkModal' | 'openHistoryCalendar' | 'closeHistoryCalendar' |
|
||||||
// auth
|
// auth
|
||||||
'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' |
|
'setAuthPhoneNumber' | 'setAuthCode' | 'setAuthPassword' | 'signUp' | 'returnToAuthPhoneNumber' | 'signOut' |
|
||||||
'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' |
|
'setAuthRememberMe' | 'clearAuthError' | 'uploadProfilePhoto' | 'gotToAuthQrCode' | 'clearCache' |
|
||||||
|
|||||||
@ -199,3 +199,19 @@ addReducer('toggleSafeLinkModal', (global, actions, payload) => {
|
|||||||
safeLinkModalUrl,
|
safeLinkModalUrl,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addReducer('openHistoryCalendar', (global, actions, payload) => {
|
||||||
|
const { selectedAt } = payload;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
historyCalendarSelectedAt: selectedAt,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
addReducer('closeHistoryCalendar', (global) => {
|
||||||
|
return {
|
||||||
|
...global,
|
||||||
|
historyCalendarSelectedAt: undefined,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user