1
0
Fork 0
forked from gitea/nas

Merge commit 'dee69e4f83' into kb_migration

This commit is contained in:
KMY 2023-05-27 12:51:27 +09:00
commit f010acbde2
18 changed files with 286 additions and 59 deletions

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Api::V1::ReactionDeckController < Api::BaseController class Api::V1::ReactionDeckController < Api::BaseController
include RoutingHelper
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index] before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index]
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, only: [:create] before_action -> { doorkeeper_authorize! :write, :'write:lists' }, only: [:create]
@ -12,31 +14,76 @@ class Api::V1::ReactionDeckController < Api::BaseController
end end
def index def index
render json: @deck render json: remove_metas(@deck)
end end
def create def create
(deck_params['emojis'] || []).each do |data| deck = []
raise ArgumentError if data['id'].to_i >= 16 || data['id'].to_i.negative?
exists = @deck.find { |dd| dd['id'] == data['id'] } shortcodes = []
if exists (deck_params['emojis'] || []).each do |shortcode|
exists['emoji'] = data['emoji'].delete(':') shortcodes << shortcode.delete(':')
else break if shortcodes.length >= User::REACTION_DECK_MAX
@deck << { id: data['id'], emoji: data['emoji'].delete(':') }
end
end end
@deck = @deck.sort_by { |a| a['id'].to_i }
current_user.settings['reaction_deck'] = @deck.to_json custom_emojis = CustomEmoji.where(shortcode: shortcodes, domain: nil)
shortcodes.each do |shortcode|
custom_emoji = custom_emojis.find { |em| em.shortcode == shortcode }
emoji_data = {}
if custom_emoji
emoji_data['name'] = custom_emoji.shortcode
emoji_data['url'] = full_asset_url(custom_emoji.image.url)
emoji_data['static_url'] = full_asset_url(custom_emoji.image.url(:static))
emoji_data['width'] = custom_emoji.image_width
emoji_data['height'] = custom_emoji.image_height
emoji_data['custom_emoji_id'] = custom_emoji.id
else
emoji_data['name'] = shortcode
end
deck << emoji_data
end
current_user.settings['reaction_deck'] = deck.to_json
current_user.save! current_user.save!
render json: @deck render json: remove_metas(deck)
end end
private private
def set_deck def set_deck
@deck = current_user.setting_reaction_deck ? JSON.parse(current_user.setting_reaction_deck) : [] deck = current_user.setting_reaction_deck ? JSON.parse(current_user.setting_reaction_deck) : []
@deck = remove_unused_custom_emojis(deck)
end
def remove_unused_custom_emojis(deck)
custom_ids = []
deck.each do |item|
custom_ids << item['custom_emoji_id'].to_i if item.key?('custom_emoji_id')
end
custom_emojis = CustomEmoji.where(id: custom_ids)
deck.each do |item|
next if item['custom_emoji_id'].nil?
custom_emoji = custom_emojis.find { |em| em.id == item['custom_emoji_id'].to_i }
remove = custom_emoji.nil? || custom_emoji.disabled
item['remove'] = remove if remove
end
deck.filter { |item| !item.key?('remove') }
end
def remove_metas(deck)
deck.tap do |d|
d.each do |item|
item.delete('custom_emoji_id')
# item.delete('id') if item.key?('id')
end
end
end end
def deck_params def deck_params

View file

@ -43,11 +43,11 @@ export function fetchReactionDeckFail(error) {
}; };
} }
export function updateReactionDeck(id, emoji) { export function updateReactionDeck(emojis) {
return (dispatch, getState) => { return (dispatch, getState) => {
dispatch(updateReactionDeckRequest()); dispatch(updateReactionDeckRequest());
api(getState).post('/api/v1/reaction_deck', { emojis: [{ id, emoji: emoji.native || emoji.id }] }).then(response => { api(getState).post('/api/v1/reaction_deck', { emojis }).then(response => {
dispatch(updateReactionDeckSuccess(response.data)); dispatch(updateReactionDeckSuccess(response.data));
}).catch(error => { }).catch(error => {
dispatch(updateReactionDeckFail(error)); dispatch(updateReactionDeckFail(error));

View file

@ -6,7 +6,7 @@ import { hideRecentEmojis } from 'mastodon/initial_state';
import { useEmoji } from '../../../actions/emojis'; import { useEmoji } from '../../../actions/emojis';
import { changeSetting } from '../../../actions/settings'; import { changeSetting } from '../../../actions/settings';
import { shortCodes } from '../../emoji/emoji_mart_data_light'; import unicodeMapping from '../../emoji/emoji_unicode_mapping_light';
import EmojiPickerDropdown from '../components/emoji_picker_dropdown'; import EmojiPickerDropdown from '../components/emoji_picker_dropdown';
@ -34,7 +34,6 @@ const DEFAULTS = [
]; ];
const RECENT_SIZE = DEFAULTS.length; const RECENT_SIZE = DEFAULTS.length;
const DECK_SIZE = 16;
const getFrequentlyUsedEmojis = createSelector([ const getFrequentlyUsedEmojis = createSelector([
state => { return { state => { return {
@ -43,11 +42,12 @@ const getFrequentlyUsedEmojis = createSelector([
}; }, }; },
], data => { ], data => {
const { emojiCounters, reactionDeck } = data; const { emojiCounters, reactionDeck } = data;
let deckEmojis = reactionDeck let deckEmojis = reactionDeck
.toArray() .toArray()
.map((e) => e.get('emoji')) .map((e) => e.get('name'))
.filter((e) => e) .filter((e) => e)
.map((e) => shortCodes[e] || e); .map((e) => unicodeMapping[e] ? unicodeMapping[e].shortCode : e);
deckEmojis = [...new Set(deckEmojis)]; deckEmojis = [...new Set(deckEmojis)];
let emojis; let emojis;
@ -68,7 +68,9 @@ const getFrequentlyUsedEmojis = createSelector([
emojis = []; emojis = [];
} }
emojis = deckEmojis.slice(0, DECK_SIZE).concat(emojis); emojis = deckEmojis.concat(emojis);
if (emojis.length <= 0) emojis = ['+1'];
return emojis; return emojis;
}); });

View file

@ -7,7 +7,6 @@ import { unicodeToUnifiedName } from './unicode_to_unified_name';
const [ shortCodesToEmojiData, skins, categories, short_names ] = emojiCompressed; const [ shortCodesToEmojiData, skins, categories, short_names ] = emojiCompressed;
const emojis = {}; const emojis = {};
const shortCodes = {};
// decompress // decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => { Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
@ -34,12 +33,10 @@ Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
short_names, short_names,
unified, unified,
}; };
shortCodes[native] = shortCode;
}); });
export { export {
emojis, emojis,
shortCodes,
skins, skins,
categories, categories,
short_names, short_names,

View file

@ -13,7 +13,7 @@ import { registrationsOpen } from 'mastodon/initial_state';
const mapStateToProps = (state, { accountId }) => ({ const mapStateToProps = (state, { accountId }) => ({
displayNameHtml: state.getIn(['accounts', accountId, 'display_name_html']), displayNameHtml: state.getIn(['accounts', accountId, 'display_name_html']),
signupUrl: state.getIn(['server', 'server', 'registrations', 'url'], '/auth/sign_up'), signupUrl: state.getIn(['server', 'server', 'registrations', 'url'], '/auth/sign_up') || '/auth/sign_up',
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({

View file

@ -1,40 +1,44 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { updateReactionDeck } from 'mastodon/actions/reaction_deck'; import Button from 'mastodon/components/button';
import EmojiPickerDropdownContainer from 'mastodon/features/compose/containers/emoji_picker_dropdown_container'; import EmojiPickerDropdownContainer from 'mastodon/features/compose/containers/emoji_picker_dropdown_container';
import emojify from 'mastodon/features/emoji/emoji'; import emojify from 'mastodon/features/emoji/emoji';
import { autoPlayGif } from 'mastodon/initial_state'; import { autoPlayGif } from 'mastodon/initial_state';
const MapStateToProps = (state, { emojiId, emojiMap }) => ({ const messages = defineMessages({
emoji: (state.get('reaction_deck', ImmutableList()).toArray().find(em => em.get('id') === emojiId) || ImmutableMap({ emoji: '' })).get('emoji'), remove: { id: 'reaction_deck.remove', defaultMessage: 'Remove' },
emojiMap,
});
const mapDispatchToProps = (dispatch, { emojiId }) => ({
onChange: (emoji) => dispatch(updateReactionDeck(emojiId, emoji)),
}); });
class ReactionEmoji extends ImmutablePureComponent { class ReactionEmoji extends ImmutablePureComponent {
static propTypes = { static propTypes = {
index: PropTypes.number,
emoji: PropTypes.string, emoji: PropTypes.string,
emojiMap: ImmutablePropTypes.map.isRequired, emojiMap: ImmutablePropTypes.map.isRequired,
onChange: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
}; };
static defaultProps = { static defaultProps = {
emoji: '', emoji: '',
}; };
handleChange = (emoji) => {
this.props.onChange(this.props.index, emoji);
};
handleRemove = () => {
this.props.onRemove(this.props.index);
};
render () { render () {
const { emojiMap, emoji, onChange } = this.props; const { intl, emojiMap, emoji } = this.props;
let content = null; let content = null;
@ -61,9 +65,14 @@ class ReactionEmoji extends ImmutablePureComponent {
return ( return (
<div className='reaction_deck__emoji'> <div className='reaction_deck__emoji'>
<div className='reaction_deck__emoji__wrapper'> <div className='reaction_deck__emoji__wrapper'>
<EmojiPickerDropdownContainer onPickEmoji={onChange} /> <div className='reaction_deck__emoji__wrapper__content'>
<div> <EmojiPickerDropdownContainer onPickEmoji={this.handleChange} />
{content} <div>
{content}
</div>
</div>
<div className='reaction_deck__emoji__wrapper__options'>
<Button secondary text={intl.formatMessage(messages.remove)} onClick={this.handleRemove} />
</div> </div>
</div> </div>
</div> </div>
@ -72,4 +81,4 @@ class ReactionEmoji extends ImmutablePureComponent {
} }
export default connect(MapStateToProps, mapDispatchToProps)(injectIntl(ReactionEmoji)); export default connect()(injectIntl(ReactionEmoji));

View file

@ -1,4 +1,5 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useEffect, useState } from "react";
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
@ -10,20 +11,41 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
import { updateReactionDeck } from 'mastodon/actions/reaction_deck';
import Button from 'mastodon/components/button';
import ColumnHeader from 'mastodon/components/column_header'; import ColumnHeader from 'mastodon/components/column_header';
import LoadingIndicator from 'mastodon/components/loading_indicator'; import LoadingIndicator from 'mastodon/components/loading_indicator';
import ScrollableList from 'mastodon/components/scrollable_list'; import ScrollableList from 'mastodon/components/scrollable_list';
import Column from 'mastodon/features/ui/components/column'; import Column from 'mastodon/features/ui/components/column';
import ReactionEmoji from './components/reaction_emoji'; import ReactionEmoji from './components/reaction_emoji';
const DECK_SIZE = 16; // https://medium.com/@wbern/getting-react-18s-strict-mode-to-work-with-react-beautiful-dnd-47bc909348e4
/* eslint react/prop-types: 0 */
const StrictModeDroppable = ({ children, ...props }) => {
const [enabled, setEnabled] = useState(false);
useEffect(() => {
const animation = requestAnimationFrame(() => setEnabled(true));
return () => {
cancelAnimationFrame(animation);
setEnabled(false);
};
}, []);
if (!enabled) {
return null;
}
return <Droppable {...props}>{children}</Droppable>;
};
/* eslint react/prop-types: 0 */
const customEmojiMap = createSelector([state => state.get('custom_emojis')], items => items.reduce((map, emoji) => map.set(emoji.get('shortcode'), emoji), ImmutableMap())); const customEmojiMap = createSelector([state => state.get('custom_emojis')], items => items.reduce((map, emoji) => map.set(emoji.get('shortcode'), emoji), ImmutableMap()));
const messages = defineMessages({ const messages = defineMessages({
refresh: { id: 'refresh', defaultMessage: 'Refresh' }, reaction_deck_add: { id: 'reaction_deck.add', defaultMessage: 'Add' },
heading: { id: 'column.reaction_deck', defaultMessage: 'Reaction deck' }, heading: { id: 'column.reaction_deck', defaultMessage: 'Reaction deck' },
}); });
@ -33,17 +55,52 @@ const mapStateToProps = (state, props) => ({
emojiMap: customEmojiMap(state), emojiMap: customEmojiMap(state),
}); });
const mapDispatchToProps = (dispatch) => ({
onChange: (emojis) => dispatch(updateReactionDeck(emojis)),
});
class ReactionDeck extends ImmutablePureComponent { class ReactionDeck extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
deck: ImmutablePropTypes.list, deck: ImmutablePropTypes.list,
emojiMap: ImmutablePropTypes.map, emojiMap: ImmutablePropTypes.map,
multiColumn: PropTypes.bool, multiColumn: PropTypes.bool,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
}; };
deckToArray = () => {
const { deck } = this.props;
return deck.map((item) => item.get('name')).toArray();
};
handleReorder = (result) => {
const newDeck = this.deckToArray();
const deleted = newDeck.splice(result.source.index, 1);
newDeck.splice(result.destination.index, 0, deleted[0]);
this.props.onChange(newDeck);
};
handleChange = (index, emoji) => {
const newDeck = this.deckToArray();
newDeck[index] = emoji.native || emoji.id.replace(':', '');
this.props.onChange(newDeck);
};
handleRemove = (index) => {
const newDeck = this.deckToArray();
newDeck.splice(index, 1);
this.props.onChange(newDeck);
};
handleAdd = () => {
const newDeck = this.deckToArray();
newDeck.push('👍');
this.props.onChange(newDeck);
}
render () { render () {
const { intl, deck, emojiMap, multiColumn } = this.props; const { intl, deck, emojiMap, multiColumn } = this.props;
@ -69,9 +126,31 @@ class ReactionDeck extends ImmutablePureComponent {
scrollKey='reaction_deck' scrollKey='reaction_deck'
bindToDocument={!multiColumn} bindToDocument={!multiColumn}
> >
{[...Array(DECK_SIZE).keys()].map(emojiId => <DragDropContext onDragEnd={this.handleReorder}>
<ReactionEmoji key={emojiId} emojiMap={emojiMap} emojiId={emojiId} /> <StrictModeDroppable droppableId='deckitems'>
)} {(provided) => (
<div className='deckitems' {...provided.droppableProps} ref={provided.innerRef}>
{deck.map((emoji, index) => (
<Draggable key={index} draggableId={'' + index} index={index}>
{(provided2) => (
<div ref={provided2.innerRef} {...provided2.draggableProps} {...provided2.dragHandleProps}>
<ReactionEmoji emojiMap={emojiMap}
emoji={emoji.get('name')}
index={index}
onChange={this.handleChange}
onRemove={this.handleRemove}
/>
</div>
)}
</Draggable>
))}
{provided.placeholder}
<Button text={intl.formatMessage(messages.reaction_deck_add)} onClick={this.handleAdd} />
</div>
)}
</StrictModeDroppable>
</DragDropContext>
</ScrollableList> </ScrollableList>
<Helmet> <Helmet>
@ -83,4 +162,4 @@ class ReactionDeck extends ImmutablePureComponent {
} }
export default connect(mapStateToProps)(injectIntl(ReactionDeck)); export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(ReactionDeck));

View file

@ -61,7 +61,10 @@ class NavigationPanel extends Component {
</div> </div>
{signedIn && ( {signedIn && (
<ColumnLink transparent to='/home' icon='home' text={intl.formatMessage(messages.home)} /> <>
<ColumnLink transparent to='/notifications' icon={<NotificationsCounterIcon className='column-link__icon' />} text={intl.formatMessage(messages.notifications)} />
<ColumnLink transparent to='/home' icon='home' text={intl.formatMessage(messages.home)} />
</>
)} )}
{!signedIn && explorer} {!signedIn && explorer}
@ -82,7 +85,6 @@ class NavigationPanel extends Component {
{signedIn && ( {signedIn && (
<> <>
<ColumnLink transparent to='/notifications' icon={<NotificationsCounterIcon className='column-link__icon' />} text={intl.formatMessage(messages.notifications)} />
<FollowRequestsColumnLink /> <FollowRequestsColumnLink />
<ColumnLink transparent to='/conversations' icon='at' text={intl.formatMessage(messages.direct)} /> <ColumnLink transparent to='/conversations' icon='at' text={intl.formatMessage(messages.direct)} />
</> </>

View file

@ -17,7 +17,7 @@ const SignInBanner = () => {
let signupButton; let signupButton;
const signupUrl = useAppSelector((state) => state.getIn(['server', 'server', 'registrations', 'url'], '/auth/sign_up')); const signupUrl = useAppSelector((state) => state.getIn(['server', 'server', 'registrations', 'url'], '/auth/sign_up') || '/auth/sign_up');
if (registrationsOpen) { if (registrationsOpen) {
signupButton = ( signupButton = (

View file

@ -116,6 +116,7 @@
"column.notifications": "Notifications", "column.notifications": "Notifications",
"column.pins": "Pinned posts", "column.pins": "Pinned posts",
"column.public": "Federated timeline", "column.public": "Federated timeline",
"column.reaction_deck": "Reaction deck",
"column_back_button.label": "Back", "column_back_button.label": "Back",
"column_header.hide_settings": "Hide settings", "column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left", "column_header.moveLeft_settings": "Move column to the left",
@ -134,6 +135,8 @@
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is not public. Only public posts can be searched by hashtag.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is not public. Only public posts can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "locked", "compose_form.lock_disclaimer.lock": "locked",
"compose_form.markdown.marked": "Markdown is available",
"compose_form.markdown.unmarked": "Markdown is NOT available",
"compose_form.placeholder": "What's on your mind?", "compose_form.placeholder": "What's on your mind?",
"compose_form.searchability_warning": "Self only searchability is not available other mastodon servers. Others can search your post.", "compose_form.searchability_warning": "Self only searchability is not available other mastodon servers. Others can search your post.",
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
@ -371,6 +374,7 @@
"mute_modal.hide_notifications": "Hide notifications from this user?", "mute_modal.hide_notifications": "Hide notifications from this user?",
"mute_modal.indefinite": "Indefinite", "mute_modal.indefinite": "Indefinite",
"navigation_bar.about": "About", "navigation_bar.about": "About",
"navigation_bar.antennas": "Antenna",
"navigation_bar.blocks": "Blocked users", "navigation_bar.blocks": "Blocked users",
"navigation_bar.bookmarks": "Bookmarks", "navigation_bar.bookmarks": "Bookmarks",
"navigation_bar.community_timeline": "Local timeline", "navigation_bar.community_timeline": "Local timeline",
@ -392,6 +396,7 @@
"navigation_bar.pins": "Pinned posts", "navigation_bar.pins": "Pinned posts",
"navigation_bar.preferences": "Preferences", "navigation_bar.preferences": "Preferences",
"navigation_bar.public_timeline": "Federated timeline", "navigation_bar.public_timeline": "Federated timeline",
"navigation_bar.reaction_deck": "Reaction deck",
"navigation_bar.search": "Search", "navigation_bar.search": "Search",
"navigation_bar.security": "Security", "navigation_bar.security": "Security",
"not_signed_in_indicator.not_signed_in": "You need to login to access this resource.", "not_signed_in_indicator.not_signed_in": "You need to login to access this resource.",
@ -487,6 +492,8 @@
"privacy.change": "Change post privacy", "privacy.change": "Change post privacy",
"privacy.direct.long": "Visible for mentioned users only", "privacy.direct.long": "Visible for mentioned users only",
"privacy.direct.short": "Mentioned people only", "privacy.direct.short": "Mentioned people only",
"privacy.login.long": "Visible for login users only",
"privacy.login.short": "Login only",
"privacy.private.long": "Visible for followers only", "privacy.private.long": "Visible for followers only",
"privacy.private.short": "Followers only", "privacy.private.short": "Followers only",
"privacy.public.long": "Visible for all", "privacy.public.long": "Visible for all",
@ -497,6 +504,8 @@
"privacy.unlisted.short": "Unlisted", "privacy.unlisted.short": "Unlisted",
"privacy_policy.last_updated": "Last updated {date}", "privacy_policy.last_updated": "Last updated {date}",
"privacy_policy.title": "Privacy Policy", "privacy_policy.title": "Privacy Policy",
"reaction_deck.add": "Add",
"reaction_deck.remove": "Remove",
"refresh": "Refresh", "refresh": "Refresh",
"regeneration_indicator.label": "Loading…", "regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!", "regeneration_indicator.sublabel": "Your home feed is being prepared!",
@ -606,6 +615,7 @@
"status.edited": "Edited {date}", "status.edited": "Edited {date}",
"status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
"status.embed": "Embed", "status.embed": "Embed",
"status.expiration.add": "Set status expired time",
"status.favourite": "Favourite", "status.favourite": "Favourite",
"status.filter": "Filter this post", "status.filter": "Filter this post",
"status.filtered": "Filtered", "status.filtered": "Filtered",

View file

@ -117,6 +117,7 @@
"column.notifications": "通知", "column.notifications": "通知",
"column.pins": "固定された投稿", "column.pins": "固定された投稿",
"column.public": "連合タイムライン", "column.public": "連合タイムライン",
"column.reaction_deck": "絵文字デッキ",
"column_back_button.label": "戻る", "column_back_button.label": "戻る",
"column_header.hide_settings": "設定を隠す", "column_header.hide_settings": "設定を隠す",
"column_header.moveLeft_settings": "カラムを左に移動する", "column_header.moveLeft_settings": "カラムを左に移動する",
@ -135,6 +136,8 @@
"compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。", "compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。",
"compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。", "compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
"compose_form.lock_disclaimer.lock": "承認制", "compose_form.lock_disclaimer.lock": "承認制",
"compose_form.markdown.marked": "Markdown有効",
"compose_form.markdown.unmarked": "Markdownは有効になっていません",
"compose_form.placeholder": "今なにしてる?", "compose_form.placeholder": "今なにしてる?",
"compose_form.searchability_warning": "検索許可「自分のみ」はkmyblue内の検索でのみ有効です。他のサーバーでは「リアクションした人のみ」と同等に扱われます", "compose_form.searchability_warning": "検索許可「自分のみ」はkmyblue内の検索でのみ有効です。他のサーバーでは「リアクションした人のみ」と同等に扱われます",
"compose_form.poll.add_option": "追加", "compose_form.poll.add_option": "追加",
@ -373,6 +376,7 @@
"mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?", "mute_modal.hide_notifications": "このユーザーからの通知を隠しますか?",
"mute_modal.indefinite": "無期限", "mute_modal.indefinite": "無期限",
"navigation_bar.about": "概要", "navigation_bar.about": "概要",
"navigation_bar.antennas": "アンテナ",
"navigation_bar.blocks": "ブロックしたユーザー", "navigation_bar.blocks": "ブロックしたユーザー",
"navigation_bar.bookmarks": "ブックマーク", "navigation_bar.bookmarks": "ブックマーク",
"navigation_bar.community_timeline": "ローカルタイムライン", "navigation_bar.community_timeline": "ローカルタイムライン",
@ -395,6 +399,7 @@
"navigation_bar.pins": "固定した投稿", "navigation_bar.pins": "固定した投稿",
"navigation_bar.preferences": "ユーザー設定", "navigation_bar.preferences": "ユーザー設定",
"navigation_bar.public_timeline": "連合タイムライン", "navigation_bar.public_timeline": "連合タイムライン",
"navigation_bar.reaction_deck": "絵文字デッキ",
"navigation_bar.search": "検索", "navigation_bar.search": "検索",
"navigation_bar.security": "セキュリティ", "navigation_bar.security": "セキュリティ",
"not_signed_in_indicator.not_signed_in": "この機能を使うにはログインする必要があります。", "not_signed_in_indicator.not_signed_in": "この機能を使うにはログインする必要があります。",
@ -492,6 +497,8 @@
"privacy.change": "公開範囲を変更", "privacy.change": "公開範囲を変更",
"privacy.direct.long": "指定された相手のみ閲覧可", "privacy.direct.long": "指定された相手のみ閲覧可",
"privacy.direct.short": "指定された相手のみ", "privacy.direct.short": "指定された相手のみ",
"privacy.login.long": "ログインユーザーのみ閲覧可、公開",
"privacy.login.short": "ログインユーザーのみ",
"privacy.private.long": "フォロワーのみ閲覧可", "privacy.private.long": "フォロワーのみ閲覧可",
"privacy.private.short": "フォロワーのみ", "privacy.private.short": "フォロワーのみ",
"privacy.public.long": "誰でも閲覧可、ホームローカル連合TL", "privacy.public.long": "誰でも閲覧可、ホームローカル連合TL",
@ -502,6 +509,8 @@
"privacy.unlisted.short": "未収載", "privacy.unlisted.short": "未収載",
"privacy_policy.last_updated": "{date}に更新", "privacy_policy.last_updated": "{date}に更新",
"privacy_policy.title": "プライバシーポリシー", "privacy_policy.title": "プライバシーポリシー",
"reaction_deck.add": "追加",
"reaction_deck.remove": "削除",
"refresh": "更新", "refresh": "更新",
"regeneration_indicator.label": "読み込み中…", "regeneration_indicator.label": "読み込み中…",
"regeneration_indicator.sublabel": "ホームタイムラインは準備中です!", "regeneration_indicator.sublabel": "ホームタイムラインは準備中です!",
@ -612,6 +621,7 @@
"status.edited_x_times": "{count}回編集", "status.edited_x_times": "{count}回編集",
"status.embed": "埋め込み", "status.embed": "埋め込み",
"status.emoji_reaction": "スタンプ", "status.emoji_reaction": "スタンプ",
"status.expiration.add": "時限投稿を設定",
"status.favourite": "お気に入り", "status.favourite": "お気に入り",
"status.filter": "この投稿をフィルターする", "status.filter": "この投稿をフィルターする",
"status.filtered": "フィルターされました", "status.filtered": "フィルターされました",

View file

@ -7547,8 +7547,7 @@ noscript {
.reaction_deck__emoji { .reaction_deck__emoji {
&__wrapper { &__wrapper {
display: flex; display: flex;
margin: 8px 16px 8px 4px;
margin: 8px 4px;
height: 32px; height: 32px;
.emojione { .emojione {
@ -7561,6 +7560,11 @@ noscript {
margin-right: 24px; margin-right: 24px;
padding: 0; padding: 0;
} }
&__content {
display: flex;
flex: 1;
}
} }
} }

View file

@ -532,8 +532,8 @@ class Status < ApplicationRecord
elsif visibility == 'limited' elsif visibility == 'limited'
self.searchability = Status.searchabilities['limited'] self.searchability = Status.searchabilities['limited']
else else
s = [Status.searchabilities[searchability], Status.visibilities[visibility]].max s = [Status.searchabilities[searchability], Status.visibilities[visibility] - 1].max
s = [s, 3].max s = [s, 3].min
self.searchability = s self.searchability = s
end end
end end

View file

@ -65,6 +65,8 @@ class User < ApplicationRecord
# to check their feed # to check their feed
ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze ACTIVE_DURATION = ENV.fetch('USER_ACTIVE_DAYS', 7).to_i.days.freeze
REACTION_DECK_MAX = 256
devise :two_factor_authenticatable, devise :two_factor_authenticatable,
otp_secret_encryption_key: Rails.configuration.x.otp_secret otp_secret_encryption_key: Rails.configuration.x.otp_secret

View file

@ -86,7 +86,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
}, },
reaction_deck: { reaction_deck: {
max_items: 16, max_emojis: User::REACTION_DECK_MAX,
}, },
reactions: { reactions: {
@ -115,6 +115,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer
:searchability, :searchability,
:kmyblue_markdown, :kmyblue_markdown,
:kmyblue_reaction_deck, :kmyblue_reaction_deck,
:kmyblue_visibility_login,
] ]
capabilities << :profile_search unless Chewy.enabled? capabilities << :profile_search unless Chewy.enabled?

View file

@ -92,7 +92,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
}, },
reaction_deck: { reaction_deck: {
max_items: 16, max_emojis: User::REACTION_DECK_MAX,
}, },
reactions: { reactions: {
@ -124,6 +124,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
:searchability, :searchability,
:kmyblue_markdown, :kmyblue_markdown,
:kmyblue_reaction_deck, :kmyblue_reaction_deck,
:kmyblue_visibility_login,
] ]
capabilities << :profile_search unless Chewy.enabled? capabilities << :profile_search unless Chewy.enabled?

View file

@ -88,6 +88,7 @@
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"punycode": "^2.3.0", "punycode": "^2.3.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-hotkeys": "^1.1.4", "react-hotkeys": "^1.1.4",

View file

@ -1062,7 +1062,7 @@
dependencies: dependencies:
regenerator-runtime "^0.12.0" regenerator-runtime "^0.12.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.8", "@babel/runtime@^7.15.4", "@babel/runtime@^7.2.0", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.21.5" version "7.21.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
@ -2006,7 +2006,7 @@
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==
"@types/hoist-non-react-statics@^3.3.1": "@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1":
version "3.3.1" version "3.3.1"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
@ -2222,6 +2222,16 @@
dependencies: dependencies:
react-overlays "*" react-overlays "*"
"@types/react-redux@^7.1.20":
version "7.1.25"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.25.tgz#de841631205b24f9dfb4967dd4a7901e048f9a88"
integrity sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==
dependencies:
"@types/hoist-non-react-statics" "^3.3.0"
"@types/react" "*"
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
"@types/react-router-dom@^5.3.3": "@types/react-router-dom@^5.3.3":
version "5.3.3" version "5.3.3"
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83"
@ -4222,6 +4232,13 @@ crypto-random-string@^2.0.0:
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
css-box-model@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1"
integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
dependencies:
tiny-invariant "^1.0.6"
css-declaration-sorter@^6.3.1: css-declaration-sorter@^6.3.1:
version "6.3.1" version "6.3.1"
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec"
@ -7940,6 +7957,11 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
memoize-one@^5.1.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
memoize-one@^6.0.0: memoize-one@^6.0.0:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
@ -9445,6 +9467,11 @@ quick-lru@^4.0.1:
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f"
integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==
raf-schd@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
raf@^3.1.0: raf@^3.1.0:
version "3.4.1" version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
@ -9482,6 +9509,19 @@ raw-body@2.5.1:
iconv-lite "0.4.24" iconv-lite "0.4.24"
unpipe "1.0.0" unpipe "1.0.0"
react-beautiful-dnd@^13.1.1:
version "13.1.1"
resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz#b0f3087a5840920abf8bb2325f1ffa46d8c4d0a2"
integrity sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==
dependencies:
"@babel/runtime" "^7.9.2"
css-box-model "^1.2.0"
memoize-one "^5.1.1"
raf-schd "^4.0.2"
react-redux "^7.2.0"
redux "^4.0.4"
use-memo-one "^1.1.1"
react-dom@^18.2.0: react-dom@^18.2.0:
version "18.2.0" version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
@ -9568,7 +9608,7 @@ react-is@^16.13.1, react-is@^16.7.0:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^17.0.1: react-is@^17.0.1, react-is@^17.0.2:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
@ -9621,6 +9661,18 @@ react-redux-loading-bar@^5.0.4:
prop-types "^15.7.2" prop-types "^15.7.2"
react-lifecycles-compat "^3.0.4" react-lifecycles-compat "^3.0.4"
react-redux@^7.2.0:
version "7.2.9"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"
integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==
dependencies:
"@babel/runtime" "^7.15.4"
"@types/react-redux" "^7.1.20"
hoist-non-react-statics "^3.3.2"
loose-envify "^1.4.0"
prop-types "^15.7.2"
react-is "^17.0.2"
react-redux@^8.0.4: react-redux@^8.0.4:
version "8.0.5" version "8.0.5"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd"
@ -9871,7 +9923,7 @@ redux-thunk@^2.4.2:
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"
integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==
redux@^4.0.0, redux@^4.2.1: redux@^4.0.0, redux@^4.0.4, redux@^4.2.1:
version "4.2.1" version "4.2.1"
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
@ -11281,6 +11333,11 @@ tiny-invariant@^1.0.2:
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875"
integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
tiny-invariant@^1.0.6:
version "1.3.1"
resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==
tiny-queue@^0.2.1: tiny-queue@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046" resolved "https://registry.yarnpkg.com/tiny-queue/-/tiny-queue-0.2.1.tgz#25a67f2c6e253b2ca941977b5ef7442ef97a6046"
@ -11685,6 +11742,11 @@ use-latest@^1.2.1:
dependencies: dependencies:
use-isomorphic-layout-effect "^1.1.1" use-isomorphic-layout-effect "^1.1.1"
use-memo-one@^1.1.1:
version "1.1.3"
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
use-sync-external-store@^1.0.0: use-sync-external-store@^1.0.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"