TelegramPWA/src/components/left/settings/SettingsGeneral.tsx
2021-07-13 17:31:30 +03:00

281 lines
9.2 KiB
TypeScript

import React, {
FC, useCallback, memo, useEffect, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens, ISettings } from '../../../types';
import { ApiSticker, ApiStickerSet } from '../../../api/types';
import { IS_MAC_OS, IS_TOUCH_ENV } from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import useFlag from '../../../hooks/useFlag';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
import useHistoryBack from '../../../hooks/useHistoryBack';
import ListItem from '../../ui/ListItem';
import RangeSlider from '../../ui/RangeSlider';
import Checkbox from '../../ui/Checkbox';
import RadioGroup from '../../ui/RadioGroup';
import SettingsStickerSet from './SettingsStickerSet';
import StickerSetModal from '../../common/StickerSetModal.async';
type OwnProps = {
isActive?: boolean;
onScreenSelect: (screen: SettingsScreens) => void;
onReset: () => void;
};
type StateProps = Pick<ISettings, (
'messageTextSize' |
'animationLevel' |
'messageSendKeyCombo' |
'shouldAutoDownloadMediaFromContacts' |
'shouldAutoDownloadMediaInPrivateChats' |
'shouldAutoDownloadMediaInGroups' |
'shouldAutoDownloadMediaInChannels' |
'shouldAutoPlayGifs' |
'shouldAutoPlayVideos' |
'shouldSuggestStickers' |
'shouldLoopStickers'
)> & {
stickerSetIds?: string[];
stickerSetsById?: Record<string, ApiStickerSet>;
};
type DispatchProps = Pick<GlobalActions, (
'setSettingOption' | 'loadStickerSets' | 'loadAddedStickers'
)>;
const ANIMATION_LEVEL_OPTIONS = [
'Solid and Steady',
'Nice and Fast',
'Lots of Stuff',
];
const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
isActive,
onScreenSelect,
onReset,
stickerSetIds,
stickerSetsById,
messageTextSize,
animationLevel,
messageSendKeyCombo,
shouldAutoDownloadMediaFromContacts,
shouldAutoDownloadMediaInPrivateChats,
shouldAutoDownloadMediaInGroups,
shouldAutoDownloadMediaInChannels,
shouldAutoPlayGifs,
shouldAutoPlayVideos,
shouldSuggestStickers,
shouldLoopStickers,
setSettingOption,
loadStickerSets,
loadAddedStickers,
}) => {
// eslint-disable-next-line no-null/no-null
const stickerSettingsRef = useRef<HTMLDivElement>(null);
const { observe: observeIntersectionForCovers } = useIntersectionObserver({ rootRef: stickerSettingsRef });
const [isModalOpen, openModal, closeModal] = useFlag();
const [sticker, setSticker] = useState<ApiSticker>();
const lang = useLang();
const KEYBOARD_SEND_OPTIONS = !IS_TOUCH_ENV ? [
{ value: 'enter', label: lang('lng_settings_send_enter'), subLabel: 'New line by Shift + Enter' },
{
value: 'ctrl-enter',
label: lang(IS_MAC_OS ? 'lng_settings_send_cmdenter' : 'lng_settings_send_ctrlenter'),
subLabel: 'New line by Enter',
},
] : undefined;
useEffect(() => {
loadStickerSets();
}, [loadStickerSets]);
useEffect(() => {
if (stickerSetIds && stickerSetIds.length) {
loadAddedStickers();
}
}, [stickerSetIds, loadAddedStickers]);
const handleAnimationLevelChange = useCallback((newLevel: number) => {
ANIMATION_LEVEL_OPTIONS.forEach((_, i) => {
document.body.classList.toggle(`animation-level-${i}`, newLevel === i);
});
setSettingOption({ animationLevel: newLevel });
}, [setSettingOption]);
const handleMessageTextSizeChange = useCallback((newSize: number) => {
document.documentElement.style.setProperty('--message-text-size', `${newSize}px`);
setSettingOption({ messageTextSize: newSize });
}, [setSettingOption]);
const handleStickerSetClick = useCallback((value: ApiSticker) => {
setSticker(value);
openModal();
}, [openModal]);
const stickerSets = stickerSetIds && stickerSetIds.map((id: string) => {
return stickerSetsById && stickerSetsById[id] && stickerSetsById[id].installedDate ? stickerSetsById[id] : false;
}).filter<ApiStickerSet>(Boolean as any);
useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.General);
return (
<div className="settings-content custom-scroll">
<div className="settings-item pt-3">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{lang('SETTINGS')}</h4>
<RangeSlider
label={lang('TextSize')}
// TODO Remove memo-killer
range={{ min: 12, max: 20 }}
value={messageTextSize}
onChange={handleMessageTextSizeChange}
/>
<ListItem
icon="photo"
onClick={() => onScreenSelect(SettingsScreens.GeneralChatBackground)}
>
{lang('ChatBackground')}
</ListItem>
</div>
<div className="settings-item">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
Animation Level
</h4>
<p className="settings-item-description" dir={lang.isRtl ? 'rtl' : undefined}>
Choose the desired animations amount.
</p>
<RangeSlider
options={ANIMATION_LEVEL_OPTIONS}
value={animationLevel}
onChange={handleAnimationLevelChange}
/>
</div>
{KEYBOARD_SEND_OPTIONS && (
<div className="settings-item">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{lang('VoiceOver.Keyboard')}</h4>
<RadioGroup
name="keyboard-send-settings"
options={KEYBOARD_SEND_OPTIONS}
onChange={(value) => setSettingOption({ messageSendKeyCombo: value })}
selected={messageSendKeyCombo}
/>
</div>
)}
<div className="settings-item">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{lang('AutoDownloadMedia')}</h4>
<Checkbox
label={lang('Contacts')}
checked={shouldAutoDownloadMediaFromContacts}
onCheck={(isChecked) => setSettingOption({ shouldAutoDownloadMediaFromContacts: isChecked })}
/>
<Checkbox
label={lang('AutodownloadPrivateChats')}
checked={shouldAutoDownloadMediaInPrivateChats}
onCheck={(isChecked) => setSettingOption({ shouldAutoDownloadMediaInPrivateChats: isChecked })}
/>
<Checkbox
label={lang('AutodownloadGroupChats')}
checked={shouldAutoDownloadMediaInGroups}
onCheck={(isChecked) => setSettingOption({ shouldAutoDownloadMediaInGroups: isChecked })}
/>
<Checkbox
label={lang('FilterChannels')}
checked={shouldAutoDownloadMediaInChannels}
onCheck={(isChecked) => setSettingOption({ shouldAutoDownloadMediaInChannels: isChecked })}
/>
</div>
<div className="settings-item">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{lang('AutoplayMedia')}</h4>
<Checkbox
label={lang('GifsTab2')}
checked={shouldAutoPlayGifs}
onCheck={(isChecked) => setSettingOption({ shouldAutoPlayGifs: isChecked })}
/>
<Checkbox
label={lang('DataAndStorage.Autoplay.Videos')}
checked={shouldAutoPlayVideos}
onCheck={(isChecked) => setSettingOption({ shouldAutoPlayVideos: isChecked })}
/>
</div>
<div className="settings-item">
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{lang('AccDescrStickers')}</h4>
<Checkbox
label={lang('SuggestStickers')}
checked={shouldSuggestStickers}
onCheck={(isChecked) => setSettingOption({ shouldSuggestStickers: isChecked })}
/>
<Checkbox
label={lang('LoopAnimatedStickers')}
checked={shouldLoopStickers}
onCheck={(isChecked) => setSettingOption({ shouldLoopStickers: isChecked })}
/>
<div className="mt-4" ref={stickerSettingsRef}>
{stickerSets && stickerSets.map((stickerSet: ApiStickerSet) => (
<SettingsStickerSet
key={stickerSet.id}
stickerSet={stickerSet}
observeIntersection={observeIntersectionForCovers}
onClick={handleStickerSetClick}
/>
))}
</div>
{sticker && (
<StickerSetModal
isOpen={isModalOpen}
fromSticker={sticker}
onClose={closeModal}
/>
)}
</div>
</div>
);
};
export default memo(withGlobal<OwnProps>(
(global): StateProps => {
return {
...pick(global.settings.byKey, [
'messageTextSize',
'animationLevel',
'messageSendKeyCombo',
'shouldAutoDownloadMediaFromContacts',
'shouldAutoDownloadMediaInPrivateChats',
'shouldAutoDownloadMediaInGroups',
'shouldAutoDownloadMediaInChannels',
'shouldAutoPlayGifs',
'shouldAutoPlayVideos',
'shouldSuggestStickers',
'shouldLoopStickers',
'isSensitiveEnabled',
'canChangeSensitive',
]),
stickerSetIds: global.stickers.added.setIds,
stickerSetsById: global.stickers.setsById,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setSettingOption', 'loadStickerSets', 'loadAddedStickers',
]),
)(SettingsGeneral));