Remember frequently used languages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
2e43f8967f
commit
32db7c6fad
5 changed files with 50 additions and 4 deletions
|
@ -15,6 +15,7 @@ import { getFeatures, parseVersion } from 'soapbox/utils/features';
|
|||
|
||||
import { chooseEmoji } from './emojis';
|
||||
import { importFetchedAccounts } from './importer';
|
||||
import { rememberLanguageUse } from './languages';
|
||||
import { uploadFile, updateMedia } from './media';
|
||||
import { openModal, closeModal } from './modals';
|
||||
import { getSettings } from './settings';
|
||||
|
@ -361,6 +362,10 @@ const submitCompose = (composeId: string, opts: SubmitComposeOpts = {}) =>
|
|||
dispatch(submitComposeRequest(composeId));
|
||||
dispatch(closeModal());
|
||||
|
||||
if (compose.language && !statusId) {
|
||||
dispatch(rememberLanguageUse(compose.language));
|
||||
}
|
||||
|
||||
const idempotencyKey = compose.idempotencyKey;
|
||||
|
||||
const params: Record<string, any> = {
|
||||
|
|
16
src/actions/languages.ts
Normal file
16
src/actions/languages.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { saveSettings } from './settings';
|
||||
|
||||
import type { AppDispatch } from 'soapbox/store';
|
||||
|
||||
const LANGUAGE_USE = 'LANGUAGE_USE' as const;
|
||||
|
||||
const rememberLanguageUse = (language: string) => (dispatch: AppDispatch) => {
|
||||
dispatch({
|
||||
type: LANGUAGE_USE,
|
||||
language,
|
||||
});
|
||||
|
||||
dispatch(saveSettings());
|
||||
};
|
||||
|
||||
export { LANGUAGE_USE, rememberLanguageUse };
|
|
@ -2,13 +2,24 @@ import { offset, useFloating, flip, arrow, shift } from '@floating-ui/react';
|
|||
import clsx from 'clsx';
|
||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||
import fuzzysort from 'fuzzysort';
|
||||
import { Map as ImmutableMap } from 'immutable';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
import { changeComposeLanguage } from 'soapbox/actions/compose';
|
||||
import { Button, Icon, Input, Portal } from 'soapbox/components/ui';
|
||||
import { type Language, languages as languagesObject } from 'soapbox/features/preferences';
|
||||
import { useAppDispatch, useCompose } from 'soapbox/hooks';
|
||||
import { useAppDispatch, useAppSelector, useCompose } from 'soapbox/hooks';
|
||||
|
||||
const getFrequentlyUsedLanguages = createSelector([
|
||||
state => state.settings.get('frequentlyUsedLanguages', ImmutableMap()),
|
||||
], (languageCounters: ImmutableMap<Language, number>) => (
|
||||
languageCounters.keySeq()
|
||||
.sort((a, b) => languageCounters.get(a, 0) - languageCounters.get(b, 0))
|
||||
.reverse()
|
||||
.toArray()
|
||||
));
|
||||
|
||||
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
|
||||
|
||||
|
@ -26,14 +37,15 @@ interface ILanguageDropdown {
|
|||
const LanguageDropdown: React.FC<ILanguageDropdown> = ({ composeId }) => {
|
||||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
const frequentlyUsedLanguages = useAppSelector(getFrequentlyUsedLanguages);
|
||||
|
||||
const node = useRef<HTMLDivElement>(null);
|
||||
const focusedItem = useRef<HTMLDivElement>(null);
|
||||
const arrowRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
|
||||
const arrowRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { x, y, strategy, refs, middlewareData, placement } = useFloating<HTMLButtonElement>({
|
||||
placement: 'top',
|
||||
|
@ -131,7 +143,12 @@ const LanguageDropdown: React.FC<ILanguageDropdown> = ({ composeId }) => {
|
|||
} else if (b[0] === language) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
// Sort according to frequently used languages
|
||||
|
||||
const indexOfA = frequentlyUsedLanguages.indexOf(a[0]);
|
||||
const indexOfB = frequentlyUsedLanguages.indexOf(b[0]);
|
||||
|
||||
return ((indexOfA > -1 ? indexOfA : Infinity) - (indexOfB > -1 ? indexOfB : Infinity));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -415,6 +415,7 @@
|
|||
"compose.edit_success": "Your post was edited",
|
||||
"compose.invalid_schedule": "You must schedule a post at least 5 minutes out.",
|
||||
"compose.language_dropdown.prompt": "Select language",
|
||||
"compose.language_dropdown.search": "Search language…",
|
||||
"compose.reply_group_indicator.message": "Posting to {groupLink}",
|
||||
"compose.submit_success": "Your post was sent!",
|
||||
"compose_event.create": "Create",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Map as ImmutableMap, fromJS } from 'immutable';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { LANGUAGE_USE } from 'soapbox/actions/languages';
|
||||
import { ME_FETCH_SUCCESS } from 'soapbox/actions/me';
|
||||
|
||||
import { EMOJI_CHOOSE } from '../actions/emojis';
|
||||
|
@ -18,7 +19,11 @@ import type { APIEntity } from 'soapbox/types/entities';
|
|||
|
||||
type State = ImmutableMap<string, any>;
|
||||
|
||||
const updateFrequentEmojis = (state: State, emoji: Emoji) => state.update('frequentlyUsedEmojis', ImmutableMap(), map => map.update(emoji.id, 0, (count: number) => count + 1)).set('saved', false);
|
||||
const updateFrequentEmojis = (state: State, emoji: Emoji) =>
|
||||
state.update('frequentlyUsedEmojis', ImmutableMap(), map => map.update(emoji.id, 0, (count: number) => count + 1)).set('saved', false);
|
||||
|
||||
const updateFrequentLanguages = (state: State, language: string) =>
|
||||
state.update('frequentlyUsedLanguages', ImmutableMap<string, number>(), map => map.update(language, 0, (count: number) => count + 1)).set('saved', false);
|
||||
|
||||
const importSettings = (state: State, account: APIEntity) => {
|
||||
account = fromJS(account);
|
||||
|
@ -45,6 +50,8 @@ const settings = (
|
|||
.set('saved', false);
|
||||
case EMOJI_CHOOSE:
|
||||
return updateFrequentEmojis(state, action.emoji);
|
||||
case LANGUAGE_USE:
|
||||
return updateFrequentLanguages(state, action.language);
|
||||
case SETTING_SAVE:
|
||||
return state.set('saved', true);
|
||||
case SETTINGS_UPDATE:
|
||||
|
|
Loading…
Reference in a new issue