<commit_before>import './settingsModal.css';

import {isEqual} from 'lodash';
import React, {Fragment, useCallback, useMemo, useState} from 'react';

import {BTDScrollbarsMode} from '../../features/changeScrollbars';
import {BTDTweetActionsPosition} from '../../features/changeTweetActions';
import {Handler, Renderer} from '../../helpers/typeHelpers';
import {OnSettingsUpdate} from '../../inject/setupSettings';
import {AbstractTweetDeckSettings} from '../../types/abstractTweetDeckSettings';
import {BTDSettings} from '../../types/betterTweetDeck/btdSettingsTypes';
import {AvatarsShape} from './components/avatarsShape';
import {BooleanSettingsRow} from './components/booleanSettingRow';
import {CheckboxSelectSettingsRow} from './components/checkboxSelectSettingsRow';
import {CustomAccentColor} from './components/customAccentColor';
import {
  BTDRadioSelectSettingsRow,
  TDRadioSelectSettingsRow,
} from './components/radioSelectSettingsRow';
import {SettingsSeperator} from './components/settingsSeperator';
import {ThemeSelector} from './components/themeSelector';

interface SettingsModalProps {
  onOpenTDSettings: Handler;
  btdSettings: BTDSettings;
  tdSettings: AbstractTweetDeckSettings;
  onSettingsUpdate: OnSettingsUpdate;
}

interface MenuItem {
  id: string;
  label: string;
  renderContent: Renderer;
}

export const SettingsModal = (props: SettingsModalProps) => {
  const {onSettingsUpdate, onOpenTDSettings} = props;
  const [btdSettings, setBtdSettings] = useState<BTDSettings>(props.btdSettings);
  const [tdSettings, setTdSettings] = useState<AbstractTweetDeckSettings>(props.tdSettings);
  const [isDirty, setIsDirty] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(0);

  const makeOnSettingsChange = useCallback(<T extends keyof BTDSettings>(key: T) => {
    return (val: BTDSettings[T]) => {
      setBtdSettings((currentSettings) => {
        return {
          ...currentSettings,
          [key]: val,
        };
      });
      setIsDirty(true);
    };
  }, []);

  const makeOnTdSettingsChange = useCallback(
    <T extends keyof AbstractTweetDeckSettings>(key: T) => {
      return (val: AbstractTweetDeckSettings[T]) => {
        console.log('TD', key, val);
        setTdSettings((currentSettings) => {
          return {
            ...currentSettings,
            [key]: val,
          };
        });
        setIsDirty(true);
      };
    },
    []
  );

  const updateSettings = useCallback(() => {
    onSettingsUpdate(btdSettings, tdSettings);
    setIsDirty(false);
  }, [onSettingsUpdate, btdSettings, tdSettings]);

  const canSave = useMemo(() => isDirty, [isDirty]);

  const reloadNeeded = useMemo(() => !isEqual(props.btdSettings, btdSettings) && isDirty, [
    btdSettings,
    isDirty,
    props.btdSettings,
  ]);

  const menu: readonly MenuItem[] = [
    {
      id: 'general',
      label: 'General',
      renderContent: () => {
        return (
          <Fragment>
            <BooleanSettingsRow
              settingsKey="useStream"
              initialValue={tdSettings.useStream}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('useStream')}>
              Stream Tweets in realtime
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="showStartupNotifications"
              initialValue={tdSettings.showStartupNotifications}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('showStartupNotifications')}>
              Show notifications on startup
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="displaySensitiveMedia"
              initialValue={tdSettings.displaySensitiveMedia}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('displaySensitiveMedia')}>
              Display media that may contain sensitive content
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="autoplayGifs"
              initialValue={tdSettings.autoPlayGifs}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('autoPlayGifs')}>
              Autoplay GIFs
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="badgesOnTopOfAvatars"
              initialValue={btdSettings.badgesOnTopOfAvatars}
              alignToTheLeft
              onChange={makeOnSettingsChange('badgesOnTopOfAvatars')}>
              Show badges on top of avatars
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="collapseReadDms"
              initialValue={btdSettings.collapseReadDms}
              alignToTheLeft
              onChange={makeOnSettingsChange('collapseReadDms')}>
              Collapse read DMs
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="disableGifsInProfilePictures"
              initialValue={btdSettings.disableGifsInProfilePictures}
              alignToTheLeft
              onChange={makeOnSettingsChange('disableGifsInProfilePictures')}>
              Freeze GIFs in profile pictures
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="removeRedirectionOnLinks"
              initialValue={btdSettings.removeRedirectionOnLinks}
              alignToTheLeft
              onChange={makeOnSettingsChange('removeRedirectionOnLinks')}>
              Remove t.co redirection on links
            </BooleanSettingsRow>
          </Fragment>
        );
      },
    },
    {
      id: 'theme-tweaks',
      label: 'Theme',
      renderContent: () => (
        <Fragment>
          <CustomAccentColor
            initialValue={btdSettings.customAccentColor}<commit_msg>smallComposerButtons<commit_after>import './settingsModal.css';

import {isEqual} from 'lodash';
import React, {Fragment, useCallback, useMemo, useState} from 'react';

import {BTDScrollbarsMode} from '../../features/changeScrollbars';
import {BTDTweetActionsPosition} from '../../features/changeTweetActions';
import {Handler, Renderer} from '../../helpers/typeHelpers';
import {OnSettingsUpdate} from '../../inject/setupSettings';
import {AbstractTweetDeckSettings} from '../../types/abstractTweetDeckSettings';
import {BTDSettings} from '../../types/betterTweetDeck/btdSettingsTypes';
import {AvatarsShape} from './components/avatarsShape';
import {BooleanSettingsRow} from './components/booleanSettingRow';
import {CheckboxSelectSettingsRow} from './components/checkboxSelectSettingsRow';
import {CustomAccentColor} from './components/customAccentColor';
import {
  BTDRadioSelectSettingsRow,
  TDRadioSelectSettingsRow,
} from './components/radioSelectSettingsRow';
import {SettingsSeperator} from './components/settingsSeperator';
import {ThemeSelector} from './components/themeSelector';

interface SettingsModalProps {
  onOpenTDSettings: Handler;
  btdSettings: BTDSettings;
  tdSettings: AbstractTweetDeckSettings;
  onSettingsUpdate: OnSettingsUpdate;
}

interface MenuItem {
  id: string;
  label: string;
  renderContent: Renderer;
}

export const SettingsModal = (props: SettingsModalProps) => {
  const {onSettingsUpdate, onOpenTDSettings} = props;
  const [btdSettings, setBtdSettings] = useState<BTDSettings>(props.btdSettings);
  const [tdSettings, setTdSettings] = useState<AbstractTweetDeckSettings>(props.tdSettings);
  const [isDirty, setIsDirty] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(0);

  const makeOnSettingsChange = useCallback(<T extends keyof BTDSettings>(key: T) => {
    return (val: BTDSettings[T]) => {
      setBtdSettings((currentSettings) => {
        return {
          ...currentSettings,
          [key]: val,
        };
      });
      setIsDirty(true);
    };
  }, []);

  const makeOnTdSettingsChange = useCallback(
    <T extends keyof AbstractTweetDeckSettings>(key: T) => {
      return (val: AbstractTweetDeckSettings[T]) => {
        console.log('TD', key, val);
        setTdSettings((currentSettings) => {
          return {
            ...currentSettings,
            [key]: val,
          };
        });
        setIsDirty(true);
      };
    },
    []
  );

  const updateSettings = useCallback(() => {
    onSettingsUpdate(btdSettings, tdSettings);
    setIsDirty(false);
  }, [onSettingsUpdate, btdSettings, tdSettings]);

  const canSave = useMemo(() => isDirty, [isDirty]);

  const reloadNeeded = useMemo(() => !isEqual(props.btdSettings, btdSettings) && isDirty, [
    btdSettings,
    isDirty,
    props.btdSettings,
  ]);

  const menu: readonly MenuItem[] = [
    {
      id: 'general',
      label: 'General',
      renderContent: () => {
        return (
          <Fragment>
            <BooleanSettingsRow
              settingsKey="useStream"
              initialValue={tdSettings.useStream}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('useStream')}>
              Stream Tweets in realtime
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="showStartupNotifications"
              initialValue={tdSettings.showStartupNotifications}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('showStartupNotifications')}>
              Show notifications on startup
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="displaySensitiveMedia"
              initialValue={tdSettings.displaySensitiveMedia}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('displaySensitiveMedia')}>
              Display media that may contain sensitive content
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="autoplayGifs"
              initialValue={tdSettings.autoPlayGifs}
              alignToTheLeft
              onChange={makeOnTdSettingsChange('autoPlayGifs')}>
              Autoplay GIFs
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="badgesOnTopOfAvatars"
              initialValue={btdSettings.badgesOnTopOfAvatars}
              alignToTheLeft
              onChange={makeOnSettingsChange('badgesOnTopOfAvatars')}>
              Show badges on top of avatars
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="collapseReadDms"
              initialValue={btdSettings.collapseReadDms}
              alignToTheLeft
              onChange={makeOnSettingsChange('collapseReadDms')}>
              Collapse read DMs
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="disableGifsInProfilePictures"
              initialValue={btdSettings.disableGifsInProfilePictures}
              alignToTheLeft
              onChange={makeOnSettingsChange('disableGifsInProfilePictures')}>
              Freeze GIFs in profile pictures
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="removeRedirectionOnLinks"
              initialValue={btdSettings.removeRedirectionOnLinks}
              alignToTheLeft
              onChange={makeOnSettingsChange('removeRedirectionOnLinks')}>
              Remove t.co redirection on links
            </BooleanSettingsRow>
            <BooleanSettingsRow
              settingsKey="smallComposerButtons"
              initialValue={btdSettings.smallComposerButtons}
              alignToTheLeft
              onChange={makeOnSettingsChange('smallComposerButtons')}>
              Make buttons smaller in the composer
            </BooleanSettingsRow>
          </Fragment>
        );
      },
    },
    {
      id: 'theme-tweaks',
      label: 'Theme',
      renderContent: () => (
        <Fragment>
          <CustomAccentColor
            initialValue={btdSettings.customAccentColor}
{'fraction_non_alphanumeric': 0.1010570824524313, 'fraction_numerical': 0.00016913319238900633, 'mean_word_length': 2.6852602056715487, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 75, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2260844', 'n_tokens_mistral': 3074, 'n_tokens_neox': 3114, 'n_words': 559}