diff --git a/.github/actions/setup-javascript/action.yml b/.github/actions/setup-javascript/action.yml index 7f29265c1c..0188c2edd9 100644 --- a/.github/actions/setup-javascript/action.yml +++ b/.github/actions/setup-javascript/action.yml @@ -16,7 +16,7 @@ runs: # The following is needed because we can not use `cache: true` for `setup-node`, as it does not support Corepack yet and mess up with the cache location if ran after Node is installed - name: Enable corepack shell: bash - run: corepack enable + run: npm i -g corepack - name: Get yarn cache directory path id: yarn-cache-dir-path diff --git a/Dockerfile b/Dockerfile index 102a917d1c..036781826a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -342,7 +342,7 @@ COPY --from=node /usr/local/lib /usr/local/lib RUN \ # Configure Corepack rm /usr/local/bin/yarn*; \ - corepack enable; \ + npm i -g corepack; \ corepack prepare --activate; # hadolint ignore=DL3008 diff --git a/Gemfile b/Gemfile index 9fc75ee37d..f9edab7dac 100644 --- a/Gemfile +++ b/Gemfile @@ -58,6 +58,7 @@ gem 'httplog', '~> 1.8.0', require: false gem 'i18n' gem 'idn-ruby', require: 'idn' gem 'inline_svg' +gem 'ipaddr', '~> 1.2' gem 'irb', '~> 1.8' gem 'kaminari', '~> 1.2' gem 'link_header', '~> 0.0' diff --git a/Gemfile.lock b/Gemfile.lock index 3aa782cbe6..1797e38f97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -343,6 +343,7 @@ GEM activesupport (>= 3.0) nokogiri (>= 1.6) io-console (0.8.2) + ipaddr (1.2.9) irb (1.18.0) pp (>= 0.6.0) prism (>= 1.3.0) @@ -992,6 +993,7 @@ DEPENDENCIES i18n-tasks (~> 1.0) idn-ruby inline_svg + ipaddr (~> 1.2) irb (~> 1.8) jd-paperclip-azure (~> 3.0) json diff --git a/Vagrantfile b/Vagrantfile index a2c0b13b14..e2d703fac2 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -115,7 +115,7 @@ gem install bundler foreman bundle install # Install node modules -sudo corepack enable +sudo npm i -g corepack corepack prepare yarn install diff --git a/app/controllers/redirect/collections_controller.rb b/app/controllers/redirect/collections_controller.rb new file mode 100644 index 0000000000..f5e177d102 --- /dev/null +++ b/app/controllers/redirect/collections_controller.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class Redirect::CollectionsController < Redirect::BaseController + private + + def set_resource + @resource = Collection.find(params[:id]) + not_found if @resource.local? || @resource&.account&.suspended? + end +end diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb index 7bfd5e2c27..29c64d50c7 100644 --- a/app/helpers/context_helper.rb +++ b/app/helpers/context_helper.rb @@ -49,9 +49,9 @@ module ContextHelper }, quote_authorizations: { 'gts' => 'https://gotosocial.org/ns#', - 'quoteAuthorization' => { '@id' => 'https://w3id.org/fep/044f#quoteAuthorization', '@type' => '@id' }, - 'interactingObject' => { '@id' => 'gts:interactingObject' }, - 'interactionTarget' => { '@id' => 'gts:interactionTarget' }, + 'QuoteAuthorization' => 'https://w3id.org/fep/044f#QuoteAuthorization', + 'interactingObject' => { '@id' => 'gts:interactingObject', '@type' => '@id' }, + 'interactionTarget' => { '@id' => 'gts:interactionTarget', '@type' => '@id' }, }, }.freeze diff --git a/app/javascript/flavours/glitch/components/account_header/buttons.tsx b/app/javascript/flavours/glitch/components/account_header/buttons.tsx index e8e286a0da..c90048fa66 100644 --- a/app/javascript/flavours/glitch/components/account_header/buttons.tsx +++ b/app/javascript/flavours/glitch/components/account_header/buttons.tsx @@ -3,8 +3,6 @@ import type { FC } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import classNames from 'classnames'; - import { followAccount } from '@/flavours/glitch/actions/accounts'; import { useAccount } from '@/flavours/glitch/hooks/useAccount'; import { getAccountHidden } from '@/flavours/glitch/selectors/accounts'; @@ -18,6 +16,7 @@ import { FollowButton } from '../follow_button'; import { IconButton } from '../icon_button'; import { AccountMenu } from './menu'; +import classes from './styles.module.scss'; const messages = defineMessages({ enableNotifications: { @@ -49,7 +48,7 @@ export const AccountButtons: FC = ({ const me = useAppSelector((state) => state.meta.get('me') as string); return ( -
+
{!hidden && ( )} @@ -94,7 +93,7 @@ const AccountButtonsOther: FC< {!isMovedAndUnfollowedAccount && ( )} diff --git a/app/javascript/flavours/glitch/components/account_header/fields.tsx b/app/javascript/flavours/glitch/components/account_header/fields.tsx index 1de53eec46..6a9c657759 100644 --- a/app/javascript/flavours/glitch/components/account_header/fields.tsx +++ b/app/javascript/flavours/glitch/components/account_header/fields.tsx @@ -108,11 +108,9 @@ const FieldCard: FC<{ }> = ({ htmlHandlers, field }) => { const intl = useIntl(); const { - name, name_emojified, nameHasEmojis, value_emojified, - value_plain, valueHasEmojis, verified_at, } = field; @@ -138,8 +136,7 @@ const FieldCard: FC<{ )} label={ void; @@ -183,9 +178,7 @@ type FieldHTMLProps = { const FieldHTML: FC = ({ className, - extraEmojis, text, - textEmojified, textHasCustomEmoji, isOverflowing, onOverflowClick, @@ -198,7 +191,7 @@ const FieldHTML: FC = ({ const html = ( +
{!hidden && account.memorial && } {!hidden && account.moved && ( )} {!suspendedOrHidden && !account.moved && relationship?.requested_by && ( )} -
+
{!suspendedOrHidden && ( -
-
+
+ -
+
-
- {me && account.id !== me && ( - - )} +
+ {me && account.id !== me && } - + - -
+ {!me && account.email_subscriptions && ( diff --git a/app/javascript/flavours/glitch/components/account_header/styles.module.scss b/app/javascript/flavours/glitch/components/account_header/styles.module.scss index 2953fd0ec2..65775147cd 100644 --- a/app/javascript/flavours/glitch/components/account_header/styles.module.scss +++ b/app/javascript/flavours/glitch/components/account_header/styles.module.scss @@ -1,26 +1,79 @@ +.moved { + opacity: 0.5; +} + +// Account header .header { height: 120px; + overflow: hidden; background: var(--color-bg-secondary); + border-bottom: 1px solid var(--color-border-primary); + + img { + object-fit: cover; + display: block; + width: 100%; + height: 100%; + margin: 0; + } @container (width >= 500px) { height: 160px; } + + :global(.inactive) & { + filter: grayscale(100%); + } } +// Wraps everything except the header image. .barWrapper { - border-bottom: none; padding-inline: 16px; } +// Avatar .avatarWrapper { margin-top: -64px; padding-top: 0; + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 8px; + overflow: hidden; + margin-inline-start: -2px; // aligns the pfp with content below +} + +.avatar { + background: var(--color-bg-primary); + border: 1px solid var(--color-border-primary); + border-radius: var(--avatar-border-radius); + + .moved & { + filter: grayscale(100%); + } } .displayNameWrapper { display: flex; align-items: start; gap: 16px; + margin-top: 16px; + margin-bottom: 16px; + + h1 { + font-size: 17px; + line-height: 22px; + color: var(--color-text-primary); + font-weight: 600; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + :global(.emojione) { + width: 22px; + height: 22px; + } } .nameWrapper { @@ -112,21 +165,6 @@ } } -$button-breakpoint: 420px; -$button-fallback-breakpoint: $button-breakpoint + 55px; - -.buttonsDesktop { - @container (width < #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (max-width: #{$button-fallback-breakpoint}) { - display: none; - } - } -} - .handleCopy { border: 1px solid var(--color-border-primary); border-radius: 8px; @@ -147,6 +185,45 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; } } +$button-breakpoint: 420px; +$button-fallback-breakpoint: $button-breakpoint + 55px; + +.buttonsDesktop, +.buttonsMobile { + display: flex; + align-items: center; + gap: 8px; + + :global(.button) { + flex-shrink: 1; + white-space: nowrap; + min-width: 80px; + } + + :global(.icon-button) { + border: 1px solid var(--color-border-primary); + border-radius: 4px; + box-sizing: content-box; + padding: 5px; + + &:global(.copied) { + border-color: var(--color-text-success); + } + } +} + +.buttonsDesktop { + @container (width < #{$button-breakpoint}) { + display: none; + } + + @supports (not (container-type: inline-size)) { + @media (max-width: #{$button-fallback-breakpoint}) { + display: none; + } + } +} + .buttonsMobile { position: sticky; bottom: var(--mobile-bottom-nav-height); @@ -188,6 +265,7 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; .bio { font-size: 15px; + color: var(--color-text-primary); } .familiarFollowers { @@ -420,3 +498,13 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; background: var(--color-bg-primary); } } + +// Buttons + +.followButton { + flex-grow: 1; +} + +.bioButtonsWrapper { + margin-top: 16px; +} diff --git a/app/javascript/flavours/glitch/components/error_boundary.jsx b/app/javascript/flavours/glitch/components/error_boundary.jsx index 82ea7dc89f..82de329e79 100644 --- a/app/javascript/flavours/glitch/components/error_boundary.jsx +++ b/app/javascript/flavours/glitch/components/error_boundary.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import StackTrace from 'stacktrace-js'; diff --git a/app/javascript/flavours/glitch/components/hover_card_account.tsx b/app/javascript/flavours/glitch/components/hover_card_account.tsx index c1f51e9b7b..1c4a31537f 100644 --- a/app/javascript/flavours/glitch/components/hover_card_account.tsx +++ b/app/javascript/flavours/glitch/components/hover_card_account.tsx @@ -158,17 +158,19 @@ export const HoverCardAccount = forwardRef< {(isMutual || isFollower) && ( <> · - {isMutual ? ( - - ) : ( - - )} + + {isMutual ? ( + + ) : ( + + )} + )}
diff --git a/app/javascript/flavours/glitch/containers/mastodon.jsx b/app/javascript/flavours/glitch/containers/mastodon.jsx index 0eb0f749f2..180024f438 100644 --- a/app/javascript/flavours/glitch/containers/mastodon.jsx +++ b/app/javascript/flavours/glitch/containers/mastodon.jsx @@ -1,6 +1,6 @@ import { PureComponent } from 'react'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Route } from 'react-router-dom'; import { Provider as ReduxProvider } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/about/index.jsx b/app/javascript/flavours/glitch/features/about/index.jsx index 60a2d68f2f..207900f673 100644 --- a/app/javascript/flavours/glitch/features/about/index.jsx +++ b/app/javascript/flavours/glitch/features/about/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/account_edit/components/column.tsx b/app/javascript/flavours/glitch/features/account_edit/components/column.tsx index 5cfbf42092..79e63b8019 100644 --- a/app/javascript/flavours/glitch/features/account_edit/components/column.tsx +++ b/app/javascript/flavours/glitch/features/account_edit/components/column.tsx @@ -2,9 +2,10 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { Column } from '@/flavours/glitch/components/column'; import { ColumnHeader } from '@/flavours/glitch/components/column_header'; import { LoadingIndicator } from '@/flavours/glitch/components/loading_indicator'; diff --git a/app/javascript/flavours/glitch/features/account_featured/index.tsx b/app/javascript/flavours/glitch/features/account_featured/index.tsx index d76a6de0ee..b8d18439b8 100644 --- a/app/javascript/flavours/glitch/features/account_featured/index.tsx +++ b/app/javascript/flavours/glitch/features/account_featured/index.tsx @@ -24,6 +24,7 @@ import Column from '@/flavours/glitch/features/ui/components/column'; import { useAccount } from '@/flavours/glitch/hooks/useAccount'; import { useAccountId } from '@/flavours/glitch/hooks/useAccountId'; import { useAccountVisibility } from '@/flavours/glitch/hooks/useAccountVisibility'; +import { me } from '@/flavours/glitch/initial_state'; import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store'; import AddIcon from '@/material-icons/400-24px/add.svg?react'; @@ -173,12 +174,14 @@ const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({ defaultMessage='Collections' /> - - - + {accountId === me && ( + + + + )} {hasCollections ? ( diff --git a/app/javascript/flavours/glitch/features/bookmarked_statuses/index.tsx b/app/javascript/flavours/glitch/features/bookmarked_statuses/index.tsx index a2a2bd790b..fbea34b713 100644 --- a/app/javascript/flavours/glitch/features/bookmarked_statuses/index.tsx +++ b/app/javascript/flavours/glitch/features/bookmarked_statuses/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; import { diff --git a/app/javascript/flavours/glitch/features/collections/components/collection_menu.tsx b/app/javascript/flavours/glitch/features/collections/components/collection_menu.tsx index da3c5b2481..709fd1a522 100644 --- a/app/javascript/flavours/glitch/features/collections/components/collection_menu.tsx +++ b/app/javascript/flavours/glitch/features/collections/components/collection_menu.tsx @@ -131,7 +131,7 @@ export const CollectionMenu: React.FC<{ { text: intl.formatMessage(messages.copyLink), action: () => { - void navigator.clipboard.writeText(getCollectionPath(id)); + void navigator.clipboard.writeText(collection.url); dispatch(showAlert({ message: messages.copyLinkConfirmation })); }, }, @@ -196,13 +196,14 @@ export const CollectionMenu: React.FC<{ id, openShareModal, isOwnCollection, + collection.url, dispatch, openDeleteConfirmation, context, currentAccountInCollection, openReportModal, - openBlockModal, openRevokeConfirmation, + openBlockModal, ]); return ( diff --git a/app/javascript/flavours/glitch/features/collections/components/share_modal.tsx b/app/javascript/flavours/glitch/features/collections/components/share_modal.tsx index 91c3a45e8b..2fccae2df7 100644 --- a/app/javascript/flavours/glitch/features/collections/components/share_modal.tsx +++ b/app/javascript/flavours/glitch/features/collections/components/share_modal.tsx @@ -42,7 +42,7 @@ export const CollectionShareModal: React.FC<{ const isNew = !!location.state?.newCollection; const isOwnCollection = collection.account_id === me; - const collectionLink = `${window.location.origin}/collections/${collection.id}`; + const collectionLink = collection.url; const handleShareOnDevice = useCallback(() => { void navigator.share({ diff --git a/app/javascript/flavours/glitch/features/collections/detail/accounts_list.tsx b/app/javascript/flavours/glitch/features/collections/detail/accounts_list.tsx index 8595c52b8a..5b0da98fee 100644 --- a/app/javascript/flavours/glitch/features/collections/detail/accounts_list.tsx +++ b/app/javascript/flavours/glitch/features/collections/detail/accounts_list.tsx @@ -138,12 +138,16 @@ export const CollectionAccountsList: React.FC<{ const renderAccountItemButton = useCallback( ({ relationship, accountId }: RenderButtonOptions) => { + if (!me || !relationship) { + // Show follow button when logged out (it will trigger the remote interaction modal) + return ; + } + // When viewing your own collection, only show the Follow button // for accounts you're not following anymore. const withoutButton = - !relationship || - (collectionOwnerId === me && - (relationship.following || relationship.requested)); + collectionOwnerId === me && + (relationship.following || relationship.requested); if (withoutButton) return null; diff --git a/app/javascript/flavours/glitch/features/collections/detail/index.tsx b/app/javascript/flavours/glitch/features/collections/detail/index.tsx index 3f75a904d7..151bf8ff17 100644 --- a/app/javascript/flavours/glitch/features/collections/detail/index.tsx +++ b/app/javascript/flavours/glitch/features/collections/detail/index.tsx @@ -2,10 +2,11 @@ import { useCallback, useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useHistory, useLocation, useParams } from 'react-router'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import HelpIcon from '@/material-icons/400-24px/help.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import ShareIcon from '@/material-icons/400-24px/share.svg?react'; diff --git a/app/javascript/flavours/glitch/features/collections/editor/index.tsx b/app/javascript/flavours/glitch/features/collections/editor/index.tsx index c50edc8ba7..ed7cba63b7 100644 --- a/app/javascript/flavours/glitch/features/collections/editor/index.tsx +++ b/app/javascript/flavours/glitch/features/collections/editor/index.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Switch, Route, @@ -12,6 +11,8 @@ import { useLocation, } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { Callout } from '@/flavours/glitch/components/callout'; import { useCurrentAccountId } from '@/flavours/glitch/hooks/useAccountId'; import { initialState } from '@/flavours/glitch/initial_state'; diff --git a/app/javascript/flavours/glitch/features/collections/index.tsx b/app/javascript/flavours/glitch/features/collections/index.tsx index b38978f313..76cf8fc262 100644 --- a/app/javascript/flavours/glitch/features/collections/index.tsx +++ b/app/javascript/flavours/glitch/features/collections/index.tsx @@ -1,8 +1,9 @@ import { defineMessages, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Route, Switch, useRouteMatch } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { TabLink, TabList } from '@/flavours/glitch/components/tab_list'; import { Column } from 'flavours/glitch/components/column'; import { ColumnHeader } from 'flavours/glitch/components/column_header'; diff --git a/app/javascript/flavours/glitch/features/community_timeline/index.jsx b/app/javascript/flavours/glitch/features/community_timeline/index.jsx index 3845f3063f..27eca02946 100644 --- a/app/javascript/flavours/glitch/features/community_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/community_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/compose/index.tsx b/app/javascript/flavours/glitch/features/compose/index.tsx index 56e91b7f48..f9a9e9031f 100644 --- a/app/javascript/flavours/glitch/features/compose/index.tsx +++ b/app/javascript/flavours/glitch/features/compose/index.tsx @@ -2,11 +2,12 @@ import { useEffect, useCallback, useState } from 'react'; import { useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; import type { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import elephantUIPlane from '@/images/elephant_ui_plane.svg'; import EditIcon from '@/material-icons/400-24px/edit_square.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; diff --git a/app/javascript/flavours/glitch/features/direct_timeline/index.jsx b/app/javascript/flavours/glitch/features/direct_timeline/index.jsx index 25f0dd9997..95aadc387b 100644 --- a/app/javascript/flavours/glitch/features/direct_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/direct_timeline/index.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useDispatch, useSelector } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/directory/index.tsx b/app/javascript/flavours/glitch/features/directory/index.tsx index 2a53e68297..c6b1f5d8c7 100644 --- a/app/javascript/flavours/glitch/features/directory/index.tsx +++ b/app/javascript/flavours/glitch/features/directory/index.tsx @@ -3,10 +3,10 @@ import { useCallback, useEffect, useRef } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; import { addColumn, diff --git a/app/javascript/flavours/glitch/features/domain_blocks/index.tsx b/app/javascript/flavours/glitch/features/domain_blocks/index.tsx index 9a88d01525..117007c724 100644 --- a/app/javascript/flavours/glitch/features/domain_blocks/index.tsx +++ b/app/javascript/flavours/glitch/features/domain_blocks/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react'; import { apiGetDomainBlocks } from 'flavours/glitch/api/domain_blocks'; diff --git a/app/javascript/flavours/glitch/features/explore/index.tsx b/app/javascript/flavours/glitch/features/explore/index.tsx index 1bfa5bb6b3..e147fdd978 100644 --- a/app/javascript/flavours/glitch/features/explore/index.tsx +++ b/app/javascript/flavours/glitch/features/explore/index.tsx @@ -2,9 +2,10 @@ import { useCallback, useRef } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { NavLink, Switch, Route } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import TrendingUpIcon from '@/material-icons/400-24px/trending_up.svg?react'; import { Column } from 'flavours/glitch/components/column'; import type { ColumnRef } from 'flavours/glitch/components/column'; diff --git a/app/javascript/flavours/glitch/features/favourited_statuses/index.tsx b/app/javascript/flavours/glitch/features/favourited_statuses/index.tsx index 1f0b875944..dab9ca7dbe 100644 --- a/app/javascript/flavours/glitch/features/favourited_statuses/index.tsx +++ b/app/javascript/flavours/glitch/features/favourited_statuses/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import { diff --git a/app/javascript/flavours/glitch/features/favourites/index.jsx b/app/javascript/flavours/glitch/features/favourites/index.jsx index 14bd9c3ac9..830bc4dc4c 100644 --- a/app/javascript/flavours/glitch/features/favourites/index.jsx +++ b/app/javascript/flavours/glitch/features/favourites/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/firehose/index.jsx b/app/javascript/flavours/glitch/features/firehose/index.jsx index 4d70642e3c..baa0c07c75 100644 --- a/app/javascript/flavours/glitch/features/firehose/index.jsx +++ b/app/javascript/flavours/glitch/features/firehose/index.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { NavLink } from 'react-router-dom'; import { useIdentity } from '@/flavours/glitch/identity_context'; diff --git a/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx b/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx index 82023ba0e3..9e70613ef9 100644 --- a/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx +++ b/app/javascript/flavours/glitch/features/follow_requests/components/account_authorize.jsx @@ -8,11 +8,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { AccountBio } from '@/flavours/glitch/components/account_bio'; import { Avatar } from '@/flavours/glitch/components/avatar'; import { DisplayName } from '@/flavours/glitch/components/display_name'; import { IconButton } from '@/flavours/glitch/components/icon_button'; import { injectIntl } from '@/flavours/glitch/components/intl'; -import { EmojiHTML } from '@/flavours/glitch/components/emoji/html'; import { Permalink } from '@/flavours/glitch/components/permalink'; const messages = defineMessages({ @@ -40,11 +40,7 @@ class AccountAuthorize extends ImmutablePureComponent { - +
diff --git a/app/javascript/flavours/glitch/features/follow_requests/index.jsx b/app/javascript/flavours/glitch/features/follow_requests/index.jsx index eff7aed1ab..34f6a15f7a 100644 --- a/app/javascript/flavours/glitch/features/follow_requests/index.jsx +++ b/app/javascript/flavours/glitch/features/follow_requests/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/followed_tags/index.tsx b/app/javascript/flavours/glitch/features/followed_tags/index.tsx index cfe199eb4c..37ec13481e 100644 --- a/app/javascript/flavours/glitch/features/followed_tags/index.tsx +++ b/app/javascript/flavours/glitch/features/followed_tags/index.tsx @@ -2,10 +2,10 @@ import { useEffect, useCallback, useRef } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { isFulfilled } from '@reduxjs/toolkit'; +import { Helmet } from '@unhead/react/helmet'; + import TagIcon from '@/material-icons/400-24px/tag.svg?react'; import { fetchFollowedHashtags, diff --git a/app/javascript/flavours/glitch/features/followers/components/list.tsx b/app/javascript/flavours/glitch/features/followers/components/list.tsx index d833fc0c54..012c8ed67a 100644 --- a/app/javascript/flavours/glitch/features/followers/components/list.tsx +++ b/app/javascript/flavours/glitch/features/followers/components/list.tsx @@ -30,6 +30,7 @@ interface AccountListProps { list?: AccountList | null; loadMore: () => void; prependAccountId?: string | null; + withoutFollowsYouBadge?: boolean; scrollKey: string; } @@ -42,6 +43,7 @@ export const AccountList: FC = ({ list, loadMore, prependAccountId, + withoutFollowsYouBadge, scrollKey, }) => { const account = useAccount(accountId); @@ -59,6 +61,7 @@ export const AccountList: FC = ({ key={followerId} accountId={followerId} withBio={false} + badge={withoutFollowsYouBadge ? false : null} /> )) ?? []; @@ -68,11 +71,12 @@ export const AccountList: FC = ({ key={prependAccountId} accountId={prependAccountId} withBio={false} + badge={withoutFollowsYouBadge ? false : null} />, ); } return children; - }, [prependAccountId, list, forceEmptyState]); + }, [prependAccountId, list, forceEmptyState, withoutFollowsYouBadge]); const columnRef = useRef(null); const handleHeaderClick = useCallback(() => { diff --git a/app/javascript/flavours/glitch/features/followers/index.tsx b/app/javascript/flavours/glitch/features/followers/index.tsx index 0dc62b8cc9..6ac6adb3ac 100644 --- a/app/javascript/flavours/glitch/features/followers/index.tsx +++ b/app/javascript/flavours/glitch/features/followers/index.tsx @@ -12,6 +12,7 @@ import { import { useAccount } from '@/flavours/glitch/hooks/useAccount'; import { useAccountId } from '@/flavours/glitch/hooks/useAccountId'; import { useRelationship } from '@/flavours/glitch/hooks/useRelationship'; +import { me } from '@/flavours/glitch/initial_state'; import { selectUserListWithoutMe } from '@/flavours/glitch/selectors/user_lists'; import { useAppDispatch, useAppSelector } from '@/flavours/glitch/store'; @@ -88,6 +89,7 @@ const Followers: FC = () => { list={followerList} loadMore={loadMore} prependAccountId={followerId} + withoutFollowsYouBadge={accountId === me} scrollKey='followers' /> ); diff --git a/app/javascript/flavours/glitch/features/getting_started/index.tsx b/app/javascript/flavours/glitch/features/getting_started/index.tsx index 23a0d4b433..f30598bb49 100644 --- a/app/javascript/flavours/glitch/features/getting_started/index.tsx +++ b/app/javascript/flavours/glitch/features/getting_started/index.tsx @@ -1,6 +1,6 @@ import { useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Column } from 'flavours/glitch/components/column'; diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx index 4483d7a760..fbd78eea65 100644 --- a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/home_timeline/index.jsx b/app/javascript/flavours/glitch/features/home_timeline/index.jsx index ee83e1bbc9..483eb46a69 100644 --- a/app/javascript/flavours/glitch/features/home_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/home_timeline/index.jsx @@ -4,7 +4,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/interaction_modal/index.tsx b/app/javascript/flavours/glitch/features/interaction_modal/index.tsx index f112f25063..dde414c84c 100644 --- a/app/javascript/flavours/glitch/features/interaction_modal/index.tsx +++ b/app/javascript/flavours/glitch/features/interaction_modal/index.tsx @@ -483,11 +483,19 @@ const InteractionModal: React.FC<{ />

- + {intent === 'follow' ? ( + + ) : ( + + )}

diff --git a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx index 7faf1209f8..aa656fc2b8 100644 --- a/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx +++ b/app/javascript/flavours/glitch/features/keyboard_shortcuts/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/link_timeline/index.tsx b/app/javascript/flavours/glitch/features/link_timeline/index.tsx index c615b25b39..72e1f61fad 100644 --- a/app/javascript/flavours/glitch/features/link_timeline/index.tsx +++ b/app/javascript/flavours/glitch/features/link_timeline/index.tsx @@ -1,8 +1,9 @@ import { useRef, useEffect, useCallback } from 'react'; -import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import TrendingUpIcon from '@/material-icons/400-24px/trending_up.svg?react'; import { expandLinkTimeline } from 'flavours/glitch/actions/timelines'; import { Column } from 'flavours/glitch/components/column'; diff --git a/app/javascript/flavours/glitch/features/list_timeline/index.jsx b/app/javascript/flavours/glitch/features/list_timeline/index.jsx index 5b8194f666..9a5e47af4c 100644 --- a/app/javascript/flavours/glitch/features/list_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/list_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Link, withRouter } from 'react-router-dom'; import ImmutablePropTypes from 'react-immutable-proptypes'; diff --git a/app/javascript/flavours/glitch/features/lists/index.tsx b/app/javascript/flavours/glitch/features/lists/index.tsx index 5aca35bffb..197e3cab9b 100644 --- a/app/javascript/flavours/glitch/features/lists/index.tsx +++ b/app/javascript/flavours/glitch/features/lists/index.tsx @@ -2,9 +2,10 @@ import { useEffect, useMemo, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import AddIcon from '@/material-icons/400-24px/add.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; diff --git a/app/javascript/flavours/glitch/features/lists/members.tsx b/app/javascript/flavours/glitch/features/lists/members.tsx index 9df96cf7c2..16424474a2 100644 --- a/app/javascript/flavours/glitch/features/lists/members.tsx +++ b/app/javascript/flavours/glitch/features/lists/members.tsx @@ -2,9 +2,10 @@ import { useCallback, useState, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useParams, Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react'; import { fetchRelationships } from 'flavours/glitch/actions/accounts'; diff --git a/app/javascript/flavours/glitch/features/lists/new.tsx b/app/javascript/flavours/glitch/features/lists/new.tsx index c3415d6b7c..1ba356dd10 100644 --- a/app/javascript/flavours/glitch/features/lists/new.tsx +++ b/app/javascript/flavours/glitch/features/lists/new.tsx @@ -2,11 +2,12 @@ import { useCallback, useState, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useParams, useHistory, Link } from 'react-router-dom'; import { isFulfilled } from '@reduxjs/toolkit'; +import { Helmet } from '@unhead/react/helmet'; + import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import { fetchList } from 'flavours/glitch/actions/lists'; diff --git a/app/javascript/flavours/glitch/features/mutes/index.jsx b/app/javascript/flavours/glitch/features/mutes/index.jsx index d02f1b23ca..7f579e33d2 100644 --- a/app/javascript/flavours/glitch/features/mutes/index.jsx +++ b/app/javascript/flavours/glitch/features/mutes/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/notifications/request.jsx b/app/javascript/flavours/glitch/features/notifications/request.jsx index 910e31997b..bfaed4ff96 100644 --- a/app/javascript/flavours/glitch/features/notifications/request.jsx +++ b/app/javascript/flavours/glitch/features/notifications/request.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useSelector, useDispatch } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/notifications/requests.jsx b/app/javascript/flavours/glitch/features/notifications/requests.jsx index 606417c819..08847abda8 100644 --- a/app/javascript/flavours/glitch/features/notifications/requests.jsx +++ b/app/javascript/flavours/glitch/features/notifications/requests.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useSelector, useDispatch } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/notifications_v2/index.tsx b/app/javascript/flavours/glitch/features/notifications_v2/index.tsx index 73dc3d6593..9cdca8daee 100644 --- a/app/javascript/flavours/glitch/features/notifications_v2/index.tsx +++ b/app/javascript/flavours/glitch/features/notifications_v2/index.tsx @@ -2,8 +2,7 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - +import { Helmet } from '@unhead/react/helmet'; import { isEqual } from 'lodash'; import { useDebouncedCallback } from 'use-debounce'; diff --git a/app/javascript/flavours/glitch/features/onboarding/follows.tsx b/app/javascript/flavours/glitch/features/onboarding/follows.tsx index ffd1a8dcdc..e8ab620929 100644 --- a/app/javascript/flavours/glitch/features/onboarding/follows.tsx +++ b/app/javascript/flavours/glitch/features/onboarding/follows.tsx @@ -2,9 +2,9 @@ import { useEffect, useState, useCallback, useRef } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; import { useDebouncedCallback } from 'use-debounce'; import PersonIcon from '@/material-icons/400-24px/person.svg?react'; diff --git a/app/javascript/flavours/glitch/features/onboarding/profile.tsx b/app/javascript/flavours/glitch/features/onboarding/profile.tsx index 0f524b2d45..2735d13ce7 100644 --- a/app/javascript/flavours/glitch/features/onboarding/profile.tsx +++ b/app/javascript/flavours/glitch/features/onboarding/profile.tsx @@ -3,9 +3,10 @@ import { useState, useMemo, useCallback, createRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; import { useHistory } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import AddPhotoAlternateIcon from '@/material-icons/400-24px/add_photo_alternate.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import PersonIcon from '@/material-icons/400-24px/person.svg?react'; diff --git a/app/javascript/flavours/glitch/features/pinned_statuses/index.jsx b/app/javascript/flavours/glitch/features/pinned_statuses/index.jsx index b32c9e7ba9..b505afe2d0 100644 --- a/app/javascript/flavours/glitch/features/pinned_statuses/index.jsx +++ b/app/javascript/flavours/glitch/features/pinned_statuses/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/privacy_policy/index.tsx b/app/javascript/flavours/glitch/features/privacy_policy/index.tsx index 400cc92d8e..a055594a9b 100644 --- a/app/javascript/flavours/glitch/features/privacy_policy/index.tsx +++ b/app/javascript/flavours/glitch/features/privacy_policy/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { apiGetPrivacyPolicy } from 'flavours/glitch/api/instance'; import type { ApiPrivacyPolicyJSON } from 'flavours/glitch/api_types/instance'; diff --git a/app/javascript/flavours/glitch/features/public_timeline/index.jsx b/app/javascript/flavours/glitch/features/public_timeline/index.jsx index 7e028b0e53..d4063b4aa3 100644 --- a/app/javascript/flavours/glitch/features/public_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/public_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/flavours/glitch/features/quotes/index.tsx b/app/javascript/flavours/glitch/features/quotes/index.tsx index 6990266a61..f815d4a054 100644 --- a/app/javascript/flavours/glitch/features/quotes/index.tsx +++ b/app/javascript/flavours/glitch/features/quotes/index.tsx @@ -2,10 +2,10 @@ import { useCallback, useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import RefreshIcon from '@/material-icons/400-24px/refresh.svg?react'; import { fetchQuotes } from 'flavours/glitch/actions/interactions_typed'; import { ColumnHeader } from 'flavours/glitch/components/column_header'; diff --git a/app/javascript/flavours/glitch/features/reblogs/index.jsx b/app/javascript/flavours/glitch/features/reblogs/index.jsx index ac9b5950be..e1b5eadbc0 100644 --- a/app/javascript/flavours/glitch/features/reblogs/index.jsx +++ b/app/javascript/flavours/glitch/features/reblogs/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/flavours/glitch/features/search/index.tsx b/app/javascript/flavours/glitch/features/search/index.tsx index b7ba59e93f..28252e5250 100644 --- a/app/javascript/flavours/glitch/features/search/index.tsx +++ b/app/javascript/flavours/glitch/features/search/index.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; diff --git a/app/javascript/flavours/glitch/features/status/index.jsx b/app/javascript/flavours/glitch/features/status/index.jsx index 2974328a84..7bf1f9466e 100644 --- a/app/javascript/flavours/glitch/features/status/index.jsx +++ b/app/javascript/flavours/glitch/features/status/index.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { defineMessages } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { withRouter } from 'react-router-dom'; import { difference } from 'lodash'; diff --git a/app/javascript/flavours/glitch/features/terms_of_service/index.tsx b/app/javascript/flavours/glitch/features/terms_of_service/index.tsx index 0b566ed7bd..bc5a15e0bb 100644 --- a/app/javascript/flavours/glitch/features/terms_of_service/index.tsx +++ b/app/javascript/flavours/glitch/features/terms_of_service/index.tsx @@ -7,9 +7,10 @@ import { defineMessages, } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link, useParams } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { apiGetTermsOfService } from 'flavours/glitch/api/instance'; import type { ApiTermsOfServiceJSON } from 'flavours/glitch/api_types/instance'; import { Column } from 'flavours/glitch/components/column'; diff --git a/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx b/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx index a76d9fdfdd..6fd5d1ebca 100644 --- a/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/bundle_column_error.jsx @@ -4,7 +4,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Link } from 'react-router-dom'; import { Button } from 'flavours/glitch/components/button'; diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx b/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx index 79f41da604..32b487dc22 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import Base from 'flavours/glitch/components/modal_root'; import { AltTextModal } from 'flavours/glitch/features/alt_text_modal'; diff --git a/app/javascript/flavours/glitch/features/ui/util/intersection_observer_wrapper.js b/app/javascript/flavours/glitch/features/ui/util/intersection_observer_wrapper.js index 2b24c65831..456bde11b5 100644 --- a/app/javascript/flavours/glitch/features/ui/util/intersection_observer_wrapper.js +++ b/app/javascript/flavours/glitch/features/ui/util/intersection_observer_wrapper.js @@ -25,7 +25,7 @@ class IntersectionObserverWrapper { this.observerBacklog.forEach(([ id, node, callback ]) => { this.observe(id, node, callback); }); - this.observerBacklog = null; + this.observerBacklog = []; } observe (id, node, callback) { diff --git a/app/javascript/flavours/glitch/main.tsx b/app/javascript/flavours/glitch/main.tsx index 144f850151..395e80d0ba 100644 --- a/app/javascript/flavours/glitch/main.tsx +++ b/app/javascript/flavours/glitch/main.tsx @@ -1,3 +1,4 @@ +import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import { Globals } from '@react-spring/web'; @@ -33,7 +34,11 @@ function main() { await initializeEmoji(); const root = createRoot(mountNode); - root.render(); + root.render( + + + , + ); store.dispatch(setupBrowserNotifications()); if (isProduction() && me && 'serviceWorker' in navigator) { diff --git a/app/javascript/flavours/glitch/styles/mastodon/accounts.scss b/app/javascript/flavours/glitch/styles/mastodon/accounts.scss index 886e6faf3e..d91cb72f5d 100644 --- a/app/javascript/flavours/glitch/styles/mastodon/accounts.scss +++ b/app/javascript/flavours/glitch/styles/mastodon/accounts.scss @@ -238,75 +238,6 @@ border-color: var(--color-border-on-bg-warning-softer); } -.account__header__fields { - max-width: 100vw; - padding: 0; - margin: 15px -15px -15px; - border: 0 none; - border-top: 1px solid var(--color-border-primary); - border-bottom: 1px solid var(--color-border-primary); - font-size: 14px; - line-height: 20px; - - dl { - display: flex; - border-bottom: 1px solid var(--color-border-primary); - } - - dt, - dd { - box-sizing: border-box; - padding: 14px; - text-align: center; - max-height: 48px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - dt { - font-weight: 500; - width: 120px; - flex: 0 0 auto; - color: var(--color-text-primary); - background: var(--color-bg-secondary); - } - - dd { - flex: 1 1 auto; - color: var(--color-text-secondary); - } - - a { - color: var(--color-text-brand); - text-decoration: none; - - &:hover, - &:focus, - &:active { - text-decoration: underline; - } - } - - .verified { - border: 1px solid var(--color-border-success-soft); - background: var(--color-bg-success-softest); - - a { - color: var(--color-text-success); - font-weight: 500; - } - - &__mark { - color: var(--color-text-success); - } - } - - dl:last-child { - border-bottom: 0; - } -} - .directory__tag .trends__item__current { width: auto; } diff --git a/app/javascript/flavours/glitch/styles/mastodon/admin.scss b/app/javascript/flavours/glitch/styles/mastodon/admin.scss index 65622a27d4..680ab7b17d 100644 --- a/app/javascript/flavours/glitch/styles/mastodon/admin.scss +++ b/app/javascript/flavours/glitch/styles/mastodon/admin.scss @@ -1050,35 +1050,121 @@ a.name-tag, max-width: 100%; } - .account__header__fields, - .account__header__content { + &__fields, + &__content { background: var(--color-bg-primary); border: 1px solid var(--color-border-primary); border-radius: 4px; height: 100%; } - .account__header__fields { - margin: 0; + &__fields { border: 1px solid var(--color-border-primary); + font-size: 14px; + line-height: 20px; + display: grid; + grid-template-columns: 120px auto; + grid-auto-flow: row; + + dl { + display: flex; + } + + dt, + dd { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 14px; + text-align: center; + border-bottom: 1px solid var(--color-border-primary); + + &:last-of-type:not(.verified) { + border-bottom: none; + } + } + + dt { + font-weight: 500; + width: 120px; + flex: 0 0 auto; + color: var(--color-text-primary); + background: var(--color-bg-secondary); + } + + dd { + flex: 1 1 auto; + color: var(--color-text-secondary); + + &:first-of-type.verified { + border-top-right-radius: 4px; + } + + &:last-of-type.verified { + border-bottom-right-radius: 4px; + } + } a { color: var(--color-text-brand); + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } } - dl:first-child .verified { - border-radius: 0 4px 0 0; - } + .verified { + border: 1px solid var(--color-border-success-soft); + background: var(--color-bg-success-softest); - .verified a { - color: var(--color-text-success); + a { + color: var(--color-text-success); + font-weight: 500; + } + + &__mark { + color: var(--color-text-success); + + > svg { + vertical-align: middle; + } + } } } - .account__header__content { + &__content { box-sizing: border-box; padding: 20px; color: var(--color-text-primary); + font-size: 14px; + font-weight: 400; + overflow: hidden; + word-break: normal; + overflow-wrap: break-word; + + p { + margin-bottom: 20px; + unicode-bidi: plaintext; + + &:last-child { + margin-bottom: 0; + } + } + + a { + color: var(--color-text-brand); + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } } } diff --git a/app/javascript/flavours/glitch/styles/mastodon/components.scss b/app/javascript/flavours/glitch/styles/mastodon/components.scss index b65289ede7..e9a0194b24 100644 --- a/app/javascript/flavours/glitch/styles/mastodon/components.scss +++ b/app/javascript/flavours/glitch/styles/mastodon/components.scss @@ -8654,372 +8654,6 @@ noscript { } } -.account__header__content { - color: var(--color-text-secondary); - font-size: 14px; - font-weight: 400; - overflow: hidden; - word-break: normal; - overflow-wrap: break-word; - - p { - margin-bottom: 20px; - unicode-bidi: plaintext; - - &:last-child { - margin-bottom: 0; - } - } - - a { - color: inherit; - text-decoration: underline; - - &:hover { - text-decoration: none; - } - } -} - -.account__header { - container: account-header / inline-size; - - &.inactive { - opacity: 0.5; - - .account__header__image, - .account__avatar { - filter: grayscale(100%); - } - } - - &__info { - position: absolute; - top: 20px; - inset-inline-end: 20px; - display: flex; - flex-wrap: wrap; - gap: 2px; - } - - &__image { - overflow: hidden; - height: 145px; - position: relative; - background: var(--color-bg-tertiary); - border-bottom: 1px solid var(--color-border-primary); - - img { - object-fit: cover; - display: block; - width: 100%; - height: 100%; - margin: 0; - } - } - - &__bar { - position: relative; - padding: 0 20px; - border-bottom: 1px solid var(--color-border-primary); - - .avatar { - display: block; - flex: 0 0 auto; - - .account__avatar { - background: var(--color-bg-primary); - border: 1px solid var(--color-border-primary); - border-radius: var(--avatar-border-radius); - } - } - } - - &__tabs { - display: flex; - align-items: flex-start; - justify-content: space-between; - margin-top: -55px; - padding-top: 10px; - gap: 8px; - overflow: hidden; - margin-inline-start: -2px; // aligns the pfp with content below - - &__name { - margin-top: 16px; - margin-bottom: 16px; - - .emojione { - width: 22px; - height: 22px; - } - - h1 { - font-size: 17px; - line-height: 22px; - color: var(--color-text-primary); - font-weight: 600; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - - small { - display: flex; - align-items: center; - gap: 4px; - font-size: 14px; - line-height: 20px; - color: var(--color-text-secondary); - font-weight: 400; - overflow: hidden; - text-overflow: ellipsis; - - span { - overflow: hidden; - text-overflow: ellipsis; - user-select: all; - } - - .icon-lock { - height: 18px; - width: 18px; - } - } - } - } - - .spacer { - flex: 1 1 auto; - } - } - - &__follow-button { - flex-grow: 1; - } - - &__buttons { - display: flex; - align-items: center; - gap: 8px; - - $button-breakpoint: 420px; - $button-fallback-breakpoint: $button-breakpoint + 55px; - - &--desktop { - margin-top: 55px; - - @container (width < #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (max-width: #{$button-fallback-breakpoint}) { - display: none; - } - } - } - - &--mobile { - margin-block: 16px; - - @container (width >= #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (min-width: ($button-fallback-breakpoint + 1px)) { - display: none; - } - } - } - - .button { - flex-shrink: 1; - white-space: nowrap; - min-width: 80px; - } - - .icon-button { - border: 1px solid var(--color-border-primary); - border-radius: 4px; - box-sizing: content-box; - padding: 5px; - - .icon { - width: 24px; - height: 24px; - } - - &.copied { - border-color: var(--color-text-success); - } - } - } - - &__bio { - .account__header__content { - color: var(--color-text-primary); - } - - .account__header__fields { - margin: 0; - margin-top: 16px; - border-radius: 4px; - border: 1px solid var(--color-border-primary); - - dl { - display: block; - padding: 8px 16px; // glitch-soc: padding purposefuly reduced - border-bottom-color: var(--color-border-primary); - } - - dd, - dt { - font-size: 13px; - line-height: 18px; - padding: 0; - text-align: initial; - } - - dt { - width: auto; - background: transparent; - text-transform: uppercase; - color: var(--color-text-tertiary); - } - - dd { - color: var(--color-text-secondary); - } - - a { - color: var(--color-text-brand); - } - - .icon { - width: 18px; - height: 18px; - } - - .verified { - border: 1px solid var(--color-text-success); - margin-top: -1px; - margin-inline: -1px; - - &:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - } - - &:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - margin-bottom: -1px; - } - - dt, - dd { - color: var(--color-text-success); - } - - dd { - display: flex; - align-items: center; - gap: 4px; - - span { - display: flex; - } - } - - a { - color: var(--color-text-success); - } - } - } - } - - &__extra { - margin-top: 16px; - - &__links { - font-size: 14px; - color: var(--color-text-secondary); - margin: 0 -10px; - padding-top: 16px; - padding-bottom: 10px; - - a { - display: inline-block; - color: var(--color-text-secondary); - text-decoration: none; - padding: 5px 10px; - font-weight: 500; - - strong { - font-weight: 700; - color: var(--color-text-primary); - } - } - } - } - - &__account-note { - color: var(--color-text-primary); - font-size: 14px; - font-weight: 400; - margin-bottom: 10px; - - &__loading-indicator-wrapper { - position: relative; - height: 37px; - - .loading-indicator { - left: 10px; - } - - .circular-progress { - width: 14px; - height: 14px; - } - } - - label { - display: block; - font-size: 12px; - font-weight: 500; - color: var(--color-text-secondary); - text-transform: uppercase; - margin-bottom: 5px; - } - - textarea { - display: block; - box-sizing: border-box; - width: calc(100% + 20px); - color: var(--color-text-primary); - background: transparent; - padding: 10px; - margin: 0 -10px; - font-family: inherit; - font-size: 14px; - resize: none; - border: 0; - outline: 0; - border-radius: 4px; - - &::placeholder { - color: var(--color-text-tertiary); - opacity: 1; - } - - &:focus { - background: var(--color-bg-brand-softest); - } - } - } -} - .account__contents { overflow: hidden; } diff --git a/app/javascript/mastodon/components/account_header/buttons.tsx b/app/javascript/mastodon/components/account_header/buttons.tsx index 737a3b9ca5..7a5ca4332c 100644 --- a/app/javascript/mastodon/components/account_header/buttons.tsx +++ b/app/javascript/mastodon/components/account_header/buttons.tsx @@ -3,8 +3,6 @@ import type { FC } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import classNames from 'classnames'; - import { followAccount } from '@/mastodon/actions/accounts'; import { useAccount } from '@/mastodon/hooks/useAccount'; import { getAccountHidden } from '@/mastodon/selectors/accounts'; @@ -18,6 +16,7 @@ import { FollowButton } from '../follow_button'; import { IconButton } from '../icon_button'; import { AccountMenu } from './menu'; +import classes from './styles.module.scss'; const messages = defineMessages({ enableNotifications: { @@ -49,7 +48,7 @@ export const AccountButtons: FC = ({ const me = useAppSelector((state) => state.meta.get('me') as string); return ( -
+
{!hidden && ( )} @@ -94,7 +93,7 @@ const AccountButtonsOther: FC< {!isMovedAndUnfollowedAccount && ( )} diff --git a/app/javascript/mastodon/components/account_header/fields.tsx b/app/javascript/mastodon/components/account_header/fields.tsx index ce2fe9d322..5e052f5bfe 100644 --- a/app/javascript/mastodon/components/account_header/fields.tsx +++ b/app/javascript/mastodon/components/account_header/fields.tsx @@ -108,11 +108,9 @@ const FieldCard: FC<{ }> = ({ htmlHandlers, field }) => { const intl = useIntl(); const { - name, name_emojified, nameHasEmojis, value_emojified, - value_plain, valueHasEmojis, verified_at, } = field; @@ -138,8 +136,7 @@ const FieldCard: FC<{ )} label={ void; @@ -183,9 +178,7 @@ type FieldHTMLProps = { const FieldHTML: FC = ({ className, - extraEmojis, text, - textEmojified, textHasCustomEmoji, isOverflowing, onOverflowClick, @@ -198,7 +191,7 @@ const FieldHTML: FC = ({ const html = ( +
{!hidden && account.memorial && } {!hidden && account.moved && ( )} {!suspendedOrHidden && !account.moved && relationship?.requested_by && ( )} -
+
{!suspendedOrHidden && ( -
-
+
+ -
+
-
- {me && account.id !== me && ( - - )} +
+ {me && account.id !== me && } - + - -
+ {!me && account.email_subscriptions && ( diff --git a/app/javascript/mastodon/components/account_header/styles.module.scss b/app/javascript/mastodon/components/account_header/styles.module.scss index 2953fd0ec2..65775147cd 100644 --- a/app/javascript/mastodon/components/account_header/styles.module.scss +++ b/app/javascript/mastodon/components/account_header/styles.module.scss @@ -1,26 +1,79 @@ +.moved { + opacity: 0.5; +} + +// Account header .header { height: 120px; + overflow: hidden; background: var(--color-bg-secondary); + border-bottom: 1px solid var(--color-border-primary); + + img { + object-fit: cover; + display: block; + width: 100%; + height: 100%; + margin: 0; + } @container (width >= 500px) { height: 160px; } + + :global(.inactive) & { + filter: grayscale(100%); + } } +// Wraps everything except the header image. .barWrapper { - border-bottom: none; padding-inline: 16px; } +// Avatar .avatarWrapper { margin-top: -64px; padding-top: 0; + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 8px; + overflow: hidden; + margin-inline-start: -2px; // aligns the pfp with content below +} + +.avatar { + background: var(--color-bg-primary); + border: 1px solid var(--color-border-primary); + border-radius: var(--avatar-border-radius); + + .moved & { + filter: grayscale(100%); + } } .displayNameWrapper { display: flex; align-items: start; gap: 16px; + margin-top: 16px; + margin-bottom: 16px; + + h1 { + font-size: 17px; + line-height: 22px; + color: var(--color-text-primary); + font-weight: 600; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + :global(.emojione) { + width: 22px; + height: 22px; + } } .nameWrapper { @@ -112,21 +165,6 @@ } } -$button-breakpoint: 420px; -$button-fallback-breakpoint: $button-breakpoint + 55px; - -.buttonsDesktop { - @container (width < #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (max-width: #{$button-fallback-breakpoint}) { - display: none; - } - } -} - .handleCopy { border: 1px solid var(--color-border-primary); border-radius: 8px; @@ -147,6 +185,45 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; } } +$button-breakpoint: 420px; +$button-fallback-breakpoint: $button-breakpoint + 55px; + +.buttonsDesktop, +.buttonsMobile { + display: flex; + align-items: center; + gap: 8px; + + :global(.button) { + flex-shrink: 1; + white-space: nowrap; + min-width: 80px; + } + + :global(.icon-button) { + border: 1px solid var(--color-border-primary); + border-radius: 4px; + box-sizing: content-box; + padding: 5px; + + &:global(.copied) { + border-color: var(--color-text-success); + } + } +} + +.buttonsDesktop { + @container (width < #{$button-breakpoint}) { + display: none; + } + + @supports (not (container-type: inline-size)) { + @media (max-width: #{$button-fallback-breakpoint}) { + display: none; + } + } +} + .buttonsMobile { position: sticky; bottom: var(--mobile-bottom-nav-height); @@ -188,6 +265,7 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; .bio { font-size: 15px; + color: var(--color-text-primary); } .familiarFollowers { @@ -420,3 +498,13 @@ $button-fallback-breakpoint: $button-breakpoint + 55px; background: var(--color-bg-primary); } } + +// Buttons + +.followButton { + flex-grow: 1; +} + +.bioButtonsWrapper { + margin-top: 16px; +} diff --git a/app/javascript/mastodon/components/error_boundary.jsx b/app/javascript/mastodon/components/error_boundary.jsx index ca2f017f3b..54424d283b 100644 --- a/app/javascript/mastodon/components/error_boundary.jsx +++ b/app/javascript/mastodon/components/error_boundary.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import StackTrace from 'stacktrace-js'; diff --git a/app/javascript/mastodon/components/hover_card_account.tsx b/app/javascript/mastodon/components/hover_card_account.tsx index 1c015e4e80..b85536cfdd 100644 --- a/app/javascript/mastodon/components/hover_card_account.tsx +++ b/app/javascript/mastodon/components/hover_card_account.tsx @@ -154,17 +154,19 @@ export const HoverCardAccount = forwardRef< {(isMutual || isFollower) && ( <> · - {isMutual ? ( - - ) : ( - - )} + + {isMutual ? ( + + ) : ( + + )} + )}
diff --git a/app/javascript/mastodon/containers/mastodon.jsx b/app/javascript/mastodon/containers/mastodon.jsx index f697c5a8b0..d6df09db49 100644 --- a/app/javascript/mastodon/containers/mastodon.jsx +++ b/app/javascript/mastodon/containers/mastodon.jsx @@ -1,6 +1,6 @@ import { PureComponent } from 'react'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Route } from 'react-router-dom'; import { Provider as ReduxProvider } from 'react-redux'; diff --git a/app/javascript/mastodon/features/about/index.jsx b/app/javascript/mastodon/features/about/index.jsx index e666e26abc..9814032cac 100644 --- a/app/javascript/mastodon/features/about/index.jsx +++ b/app/javascript/mastodon/features/about/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/account_edit/components/column.tsx b/app/javascript/mastodon/features/account_edit/components/column.tsx index dde7436887..a9b0f8cbd5 100644 --- a/app/javascript/mastodon/features/account_edit/components/column.tsx +++ b/app/javascript/mastodon/features/account_edit/components/column.tsx @@ -2,9 +2,10 @@ import type { FC } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { Column } from '@/mastodon/components/column'; import { ColumnHeader } from '@/mastodon/components/column_header'; import { LoadingIndicator } from '@/mastodon/components/loading_indicator'; diff --git a/app/javascript/mastodon/features/account_featured/index.tsx b/app/javascript/mastodon/features/account_featured/index.tsx index d4b36ae747..3082f19abc 100644 --- a/app/javascript/mastodon/features/account_featured/index.tsx +++ b/app/javascript/mastodon/features/account_featured/index.tsx @@ -24,6 +24,7 @@ import Column from '@/mastodon/features/ui/components/column'; import { useAccount } from '@/mastodon/hooks/useAccount'; import { useAccountId } from '@/mastodon/hooks/useAccountId'; import { useAccountVisibility } from '@/mastodon/hooks/useAccountVisibility'; +import { me } from '@/mastodon/initial_state'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; import AddIcon from '@/material-icons/400-24px/add.svg?react'; @@ -173,12 +174,14 @@ const AccountFeatured: React.FC<{ multiColumn: boolean }> = ({ defaultMessage='Collections' /> - - - + {accountId === me && ( + + + + )} {hasCollections ? ( diff --git a/app/javascript/mastodon/features/bookmarked_statuses/index.tsx b/app/javascript/mastodon/features/bookmarked_statuses/index.tsx index 5d4574b05b..b8fc9e2448 100644 --- a/app/javascript/mastodon/features/bookmarked_statuses/index.tsx +++ b/app/javascript/mastodon/features/bookmarked_statuses/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; import { diff --git a/app/javascript/mastodon/features/collections/components/collection_menu.tsx b/app/javascript/mastodon/features/collections/components/collection_menu.tsx index f5cc518fb8..f9d7e18157 100644 --- a/app/javascript/mastodon/features/collections/components/collection_menu.tsx +++ b/app/javascript/mastodon/features/collections/components/collection_menu.tsx @@ -131,7 +131,7 @@ export const CollectionMenu: React.FC<{ { text: intl.formatMessage(messages.copyLink), action: () => { - void navigator.clipboard.writeText(getCollectionPath(id)); + void navigator.clipboard.writeText(collection.url); dispatch(showAlert({ message: messages.copyLinkConfirmation })); }, }, @@ -196,13 +196,14 @@ export const CollectionMenu: React.FC<{ id, openShareModal, isOwnCollection, + collection.url, dispatch, openDeleteConfirmation, context, currentAccountInCollection, openReportModal, - openBlockModal, openRevokeConfirmation, + openBlockModal, ]); return ( diff --git a/app/javascript/mastodon/features/collections/components/share_modal.tsx b/app/javascript/mastodon/features/collections/components/share_modal.tsx index 0e2a412594..85440438a4 100644 --- a/app/javascript/mastodon/features/collections/components/share_modal.tsx +++ b/app/javascript/mastodon/features/collections/components/share_modal.tsx @@ -42,7 +42,7 @@ export const CollectionShareModal: React.FC<{ const isNew = !!location.state?.newCollection; const isOwnCollection = collection.account_id === me; - const collectionLink = `${window.location.origin}/collections/${collection.id}`; + const collectionLink = collection.url; const handleShareOnDevice = useCallback(() => { void navigator.share({ diff --git a/app/javascript/mastodon/features/collections/detail/accounts_list.tsx b/app/javascript/mastodon/features/collections/detail/accounts_list.tsx index 01718381c9..441b8345fb 100644 --- a/app/javascript/mastodon/features/collections/detail/accounts_list.tsx +++ b/app/javascript/mastodon/features/collections/detail/accounts_list.tsx @@ -138,12 +138,16 @@ export const CollectionAccountsList: React.FC<{ const renderAccountItemButton = useCallback( ({ relationship, accountId }: RenderButtonOptions) => { + if (!me || !relationship) { + // Show follow button when logged out (it will trigger the remote interaction modal) + return ; + } + // When viewing your own collection, only show the Follow button // for accounts you're not following anymore. const withoutButton = - !relationship || - (collectionOwnerId === me && - (relationship.following || relationship.requested)); + collectionOwnerId === me && + (relationship.following || relationship.requested); if (withoutButton) return null; diff --git a/app/javascript/mastodon/features/collections/detail/index.tsx b/app/javascript/mastodon/features/collections/detail/index.tsx index 12701d1fd4..fd8e68c772 100644 --- a/app/javascript/mastodon/features/collections/detail/index.tsx +++ b/app/javascript/mastodon/features/collections/detail/index.tsx @@ -2,10 +2,11 @@ import { useCallback, useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useHistory, useLocation, useParams } from 'react-router'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import HelpIcon from '@/material-icons/400-24px/help.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import ShareIcon from '@/material-icons/400-24px/share.svg?react'; diff --git a/app/javascript/mastodon/features/collections/editor/index.tsx b/app/javascript/mastodon/features/collections/editor/index.tsx index beb4719a3e..935e230e4a 100644 --- a/app/javascript/mastodon/features/collections/editor/index.tsx +++ b/app/javascript/mastodon/features/collections/editor/index.tsx @@ -2,7 +2,6 @@ import { useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Switch, Route, @@ -12,6 +11,8 @@ import { useLocation, } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { Callout } from '@/mastodon/components/callout'; import { useCurrentAccountId } from '@/mastodon/hooks/useAccountId'; import { initialState } from '@/mastodon/initial_state'; diff --git a/app/javascript/mastodon/features/collections/index.tsx b/app/javascript/mastodon/features/collections/index.tsx index 0b1e6445f8..11494dcd1d 100644 --- a/app/javascript/mastodon/features/collections/index.tsx +++ b/app/javascript/mastodon/features/collections/index.tsx @@ -1,8 +1,9 @@ import { defineMessages, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Route, Switch, useRouteMatch } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { TabLink, TabList } from '@/mastodon/components/tab_list'; import { Column } from 'mastodon/components/column'; import { ColumnHeader } from 'mastodon/components/column_header'; diff --git a/app/javascript/mastodon/features/community_timeline/index.jsx b/app/javascript/mastodon/features/community_timeline/index.jsx index 0cb8d9a4b7..3487e4958c 100644 --- a/app/javascript/mastodon/features/community_timeline/index.jsx +++ b/app/javascript/mastodon/features/community_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/compose/index.tsx b/app/javascript/mastodon/features/compose/index.tsx index 527e541e84..0439606ac2 100644 --- a/app/javascript/mastodon/features/compose/index.tsx +++ b/app/javascript/mastodon/features/compose/index.tsx @@ -2,11 +2,12 @@ import { useEffect, useCallback } from 'react'; import { useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; import type { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import elephantUIPlane from '@/images/elephant_ui_plane.svg'; import EditIcon from '@/material-icons/400-24px/edit_square.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; diff --git a/app/javascript/mastodon/features/direct_timeline/index.jsx b/app/javascript/mastodon/features/direct_timeline/index.jsx index 7aee83ec10..36b5efc088 100644 --- a/app/javascript/mastodon/features/direct_timeline/index.jsx +++ b/app/javascript/mastodon/features/direct_timeline/index.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useDispatch } from 'react-redux'; diff --git a/app/javascript/mastodon/features/directory/index.tsx b/app/javascript/mastodon/features/directory/index.tsx index 54317a6c76..83cf021966 100644 --- a/app/javascript/mastodon/features/directory/index.tsx +++ b/app/javascript/mastodon/features/directory/index.tsx @@ -3,10 +3,10 @@ import { useCallback, useEffect, useRef } from 'react'; import { defineMessages, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; import { addColumn, diff --git a/app/javascript/mastodon/features/domain_blocks/index.tsx b/app/javascript/mastodon/features/domain_blocks/index.tsx index 26a31c8870..74439ade71 100644 --- a/app/javascript/mastodon/features/domain_blocks/index.tsx +++ b/app/javascript/mastodon/features/domain_blocks/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react'; import { apiGetDomainBlocks } from 'mastodon/api/domain_blocks'; diff --git a/app/javascript/mastodon/features/explore/index.tsx b/app/javascript/mastodon/features/explore/index.tsx index e886627048..ed9f566c2d 100644 --- a/app/javascript/mastodon/features/explore/index.tsx +++ b/app/javascript/mastodon/features/explore/index.tsx @@ -2,9 +2,10 @@ import { useCallback, useRef } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { NavLink, Switch, Route } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import TrendingUpIcon from '@/material-icons/400-24px/trending_up.svg?react'; import { Column } from 'mastodon/components/column'; import type { ColumnRef } from 'mastodon/components/column'; diff --git a/app/javascript/mastodon/features/favourited_statuses/index.tsx b/app/javascript/mastodon/features/favourited_statuses/index.tsx index 908a8ae4a1..ccc787d6f2 100644 --- a/app/javascript/mastodon/features/favourited_statuses/index.tsx +++ b/app/javascript/mastodon/features/favourited_statuses/index.tsx @@ -2,7 +2,7 @@ import { useEffect, useRef, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns'; diff --git a/app/javascript/mastodon/features/favourites/index.jsx b/app/javascript/mastodon/features/favourites/index.jsx index 3296ec2eb9..56af510504 100644 --- a/app/javascript/mastodon/features/favourites/index.jsx +++ b/app/javascript/mastodon/features/favourites/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/firehose/index.jsx b/app/javascript/mastodon/features/firehose/index.jsx index ca3dd7ce38..645051d5f2 100644 --- a/app/javascript/mastodon/features/firehose/index.jsx +++ b/app/javascript/mastodon/features/firehose/index.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { NavLink } from 'react-router-dom'; import { useIdentity } from '@/mastodon/identity_context'; diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx index 6aff30bd47..847a088e51 100644 --- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx +++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.jsx @@ -10,11 +10,11 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { AccountBio } from '@/mastodon/components/account_bio'; import { Avatar } from '@/mastodon/components/avatar'; import { DisplayName } from '@/mastodon/components/display_name'; import { IconButton } from '@/mastodon/components/icon_button'; import { injectIntl } from '@/mastodon/components/intl'; -import { EmojiHTML } from '@/mastodon/components/emoji/html'; const messages = defineMessages({ authorize: { id: 'follow_request.authorize', defaultMessage: 'Authorize' }, @@ -41,11 +41,7 @@ class AccountAuthorize extends ImmutablePureComponent { - +
diff --git a/app/javascript/mastodon/features/follow_requests/index.jsx b/app/javascript/mastodon/features/follow_requests/index.jsx index ba632b8ea3..940279feea 100644 --- a/app/javascript/mastodon/features/follow_requests/index.jsx +++ b/app/javascript/mastodon/features/follow_requests/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/followed_tags/index.tsx b/app/javascript/mastodon/features/followed_tags/index.tsx index 4c5c0581f8..546109acb1 100644 --- a/app/javascript/mastodon/features/followed_tags/index.tsx +++ b/app/javascript/mastodon/features/followed_tags/index.tsx @@ -2,10 +2,10 @@ import { useEffect, useCallback, useRef } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { isFulfilled } from '@reduxjs/toolkit'; +import { Helmet } from '@unhead/react/helmet'; + import TagIcon from '@/material-icons/400-24px/tag.svg?react'; import { fetchFollowedHashtags, diff --git a/app/javascript/mastodon/features/followers/components/list.tsx b/app/javascript/mastodon/features/followers/components/list.tsx index 734409ee55..6c600d570f 100644 --- a/app/javascript/mastodon/features/followers/components/list.tsx +++ b/app/javascript/mastodon/features/followers/components/list.tsx @@ -28,6 +28,7 @@ interface AccountListProps { list?: AccountList | null; loadMore: () => void; prependAccountId?: string | null; + withoutFollowsYouBadge?: boolean; scrollKey: string; } @@ -40,6 +41,7 @@ export const AccountList: FC = ({ list, loadMore, prependAccountId, + withoutFollowsYouBadge, scrollKey, }) => { const account = useAccount(accountId); @@ -57,6 +59,7 @@ export const AccountList: FC = ({ key={followerId} accountId={followerId} withBio={false} + badge={withoutFollowsYouBadge ? false : null} /> )) ?? []; @@ -66,11 +69,12 @@ export const AccountList: FC = ({ key={prependAccountId} accountId={prependAccountId} withBio={false} + badge={withoutFollowsYouBadge ? false : null} />, ); } return children; - }, [prependAccountId, list, forceEmptyState]); + }, [prependAccountId, list, forceEmptyState, withoutFollowsYouBadge]); const { multiColumn } = useLayout(); diff --git a/app/javascript/mastodon/features/followers/index.tsx b/app/javascript/mastodon/features/followers/index.tsx index 219462ef6f..61345cbc97 100644 --- a/app/javascript/mastodon/features/followers/index.tsx +++ b/app/javascript/mastodon/features/followers/index.tsx @@ -9,6 +9,7 @@ import { expandFollowers, fetchFollowers } from '@/mastodon/actions/accounts'; import { useAccount } from '@/mastodon/hooks/useAccount'; import { useAccountId } from '@/mastodon/hooks/useAccountId'; import { useRelationship } from '@/mastodon/hooks/useRelationship'; +import { me } from '@/mastodon/initial_state'; import { selectUserListWithoutMe } from '@/mastodon/selectors/user_lists'; import { useAppDispatch, useAppSelector } from '@/mastodon/store'; @@ -85,6 +86,7 @@ const Followers: FC = () => { list={followerList} loadMore={loadMore} prependAccountId={followerId} + withoutFollowsYouBadge={accountId === me} scrollKey='followers' /> ); diff --git a/app/javascript/mastodon/features/getting_started/index.tsx b/app/javascript/mastodon/features/getting_started/index.tsx index 9212ddad76..f4f66f1404 100644 --- a/app/javascript/mastodon/features/getting_started/index.tsx +++ b/app/javascript/mastodon/features/getting_started/index.tsx @@ -1,6 +1,6 @@ import { useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Column } from 'mastodon/components/column'; diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.jsx b/app/javascript/mastodon/features/hashtag_timeline/index.jsx index 36049d4331..f8e04ea08d 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.jsx +++ b/app/javascript/mastodon/features/hashtag_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index e135fe0cd9..0b0d3cc805 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -4,7 +4,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/interaction_modal/index.tsx b/app/javascript/mastodon/features/interaction_modal/index.tsx index 624ecd5613..a4ba40c069 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.tsx +++ b/app/javascript/mastodon/features/interaction_modal/index.tsx @@ -483,11 +483,19 @@ const InteractionModal: React.FC<{ />

- + {intent === 'follow' ? ( + + ) : ( + + )}

diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx index 3322dc13a2..dc0e8cb4f8 100644 --- a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx +++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/link_timeline/index.tsx b/app/javascript/mastodon/features/link_timeline/index.tsx index fd9e157773..b096519606 100644 --- a/app/javascript/mastodon/features/link_timeline/index.tsx +++ b/app/javascript/mastodon/features/link_timeline/index.tsx @@ -1,8 +1,9 @@ import { useRef, useEffect, useCallback } from 'react'; -import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import TrendingUpIcon from '@/material-icons/400-24px/trending_up.svg?react'; import { expandLinkTimeline } from 'mastodon/actions/timelines'; import { Column } from 'mastodon/components/column'; diff --git a/app/javascript/mastodon/features/list_timeline/index.jsx b/app/javascript/mastodon/features/list_timeline/index.jsx index cc4533ea99..7f9d45d3b1 100644 --- a/app/javascript/mastodon/features/list_timeline/index.jsx +++ b/app/javascript/mastodon/features/list_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Link, withRouter } from 'react-router-dom'; import ImmutablePropTypes from 'react-immutable-proptypes'; diff --git a/app/javascript/mastodon/features/lists/index.tsx b/app/javascript/mastodon/features/lists/index.tsx index 65fb11d0be..6aa27d5c57 100644 --- a/app/javascript/mastodon/features/lists/index.tsx +++ b/app/javascript/mastodon/features/lists/index.tsx @@ -2,9 +2,10 @@ import { useEffect, useMemo, useCallback } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import AddIcon from '@/material-icons/400-24px/add.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; diff --git a/app/javascript/mastodon/features/lists/members.tsx b/app/javascript/mastodon/features/lists/members.tsx index c4bd99d9b4..66ea1bb127 100644 --- a/app/javascript/mastodon/features/lists/members.tsx +++ b/app/javascript/mastodon/features/lists/members.tsx @@ -2,9 +2,10 @@ import { useCallback, useState, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useParams, Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import SquigglyArrow from '@/svg-icons/squiggly_arrow.svg?react'; import { fetchRelationships } from 'mastodon/actions/accounts'; diff --git a/app/javascript/mastodon/features/lists/new.tsx b/app/javascript/mastodon/features/lists/new.tsx index 67a79fae4a..b2f916b738 100644 --- a/app/javascript/mastodon/features/lists/new.tsx +++ b/app/javascript/mastodon/features/lists/new.tsx @@ -2,11 +2,12 @@ import { useCallback, useState, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { useParams, useHistory, Link } from 'react-router-dom'; import { isFulfilled } from '@reduxjs/toolkit'; +import { Helmet } from '@unhead/react/helmet'; + import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import { fetchList } from 'mastodon/actions/lists'; diff --git a/app/javascript/mastodon/features/mutes/index.jsx b/app/javascript/mastodon/features/mutes/index.jsx index 8dd230e4ad..357bfa3e3b 100644 --- a/app/javascript/mastodon/features/mutes/index.jsx +++ b/app/javascript/mastodon/features/mutes/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/notifications/request.jsx b/app/javascript/mastodon/features/notifications/request.jsx index bf0ccc5409..d7303e7f27 100644 --- a/app/javascript/mastodon/features/notifications/request.jsx +++ b/app/javascript/mastodon/features/notifications/request.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useSelector, useDispatch } from 'react-redux'; diff --git a/app/javascript/mastodon/features/notifications/requests.jsx b/app/javascript/mastodon/features/notifications/requests.jsx index b2bdd0ec77..ef8f58d6a4 100644 --- a/app/javascript/mastodon/features/notifications/requests.jsx +++ b/app/javascript/mastodon/features/notifications/requests.jsx @@ -3,7 +3,7 @@ import { useRef, useCallback, useEffect, useState } from 'react'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { useSelector, useDispatch } from 'react-redux'; diff --git a/app/javascript/mastodon/features/notifications_v2/index.tsx b/app/javascript/mastodon/features/notifications_v2/index.tsx index 3fca9eb44e..74fa914b27 100644 --- a/app/javascript/mastodon/features/notifications_v2/index.tsx +++ b/app/javascript/mastodon/features/notifications_v2/index.tsx @@ -2,8 +2,7 @@ import { useCallback, useEffect, useMemo, useRef } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - +import { Helmet } from '@unhead/react/helmet'; import { isEqual } from 'lodash'; import { useDebouncedCallback } from 'use-debounce'; diff --git a/app/javascript/mastodon/features/onboarding/follows.tsx b/app/javascript/mastodon/features/onboarding/follows.tsx index d53f1ea50d..910d105183 100644 --- a/app/javascript/mastodon/features/onboarding/follows.tsx +++ b/app/javascript/mastodon/features/onboarding/follows.tsx @@ -2,9 +2,9 @@ import { useEffect, useState, useCallback, useRef } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; import { useDebouncedCallback } from 'use-debounce'; import PersonIcon from '@/material-icons/400-24px/person.svg?react'; diff --git a/app/javascript/mastodon/features/onboarding/profile.tsx b/app/javascript/mastodon/features/onboarding/profile.tsx index 961c5f9872..b4bde4dba5 100644 --- a/app/javascript/mastodon/features/onboarding/profile.tsx +++ b/app/javascript/mastodon/features/onboarding/profile.tsx @@ -3,9 +3,10 @@ import { useState, useMemo, useCallback, createRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; import { useHistory } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import AddPhotoAlternateIcon from '@/material-icons/400-24px/add_photo_alternate.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import PersonIcon from '@/material-icons/400-24px/person.svg?react'; diff --git a/app/javascript/mastodon/features/pinned_statuses/index.jsx b/app/javascript/mastodon/features/pinned_statuses/index.jsx index 438921a4e3..2af1af0303 100644 --- a/app/javascript/mastodon/features/pinned_statuses/index.jsx +++ b/app/javascript/mastodon/features/pinned_statuses/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/privacy_policy/index.tsx b/app/javascript/mastodon/features/privacy_policy/index.tsx index cd6f9f3b2b..d47d8db296 100644 --- a/app/javascript/mastodon/features/privacy_policy/index.tsx +++ b/app/javascript/mastodon/features/privacy_policy/index.tsx @@ -2,7 +2,7 @@ import { useState, useEffect } from 'react'; import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { apiGetPrivacyPolicy } from 'mastodon/api/instance'; import type { ApiPrivacyPolicyJSON } from 'mastodon/api_types/instance'; diff --git a/app/javascript/mastodon/features/public_timeline/index.jsx b/app/javascript/mastodon/features/public_timeline/index.jsx index e11b361545..0d04e4d4f7 100644 --- a/app/javascript/mastodon/features/public_timeline/index.jsx +++ b/app/javascript/mastodon/features/public_timeline/index.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { connect } from 'react-redux'; diff --git a/app/javascript/mastodon/features/quotes/index.tsx b/app/javascript/mastodon/features/quotes/index.tsx index 56cf2f71f1..76b4fb892c 100644 --- a/app/javascript/mastodon/features/quotes/index.tsx +++ b/app/javascript/mastodon/features/quotes/index.tsx @@ -2,10 +2,10 @@ import { useCallback, useEffect } from 'react'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; -import { Helmet } from 'react-helmet'; - import { List as ImmutableList } from 'immutable'; +import { Helmet } from '@unhead/react/helmet'; + import RefreshIcon from '@/material-icons/400-24px/refresh.svg?react'; import { fetchQuotes } from 'mastodon/actions/interactions_typed'; import { ColumnHeader } from 'mastodon/components/column_header'; diff --git a/app/javascript/mastodon/features/reblogs/index.jsx b/app/javascript/mastodon/features/reblogs/index.jsx index b0ee5029f5..06fee81e9f 100644 --- a/app/javascript/mastodon/features/reblogs/index.jsx +++ b/app/javascript/mastodon/features/reblogs/index.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; diff --git a/app/javascript/mastodon/features/search/index.tsx b/app/javascript/mastodon/features/search/index.tsx index 5b4ed807fa..0424ed30c3 100644 --- a/app/javascript/mastodon/features/search/index.tsx +++ b/app/javascript/mastodon/features/search/index.tsx @@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef } from 'react'; import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index cc9bf693ea..db18964a3b 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { defineMessages } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { withRouter } from 'react-router-dom'; import { difference } from 'lodash'; diff --git a/app/javascript/mastodon/features/terms_of_service/index.tsx b/app/javascript/mastodon/features/terms_of_service/index.tsx index 8ef64fc515..669fb18b92 100644 --- a/app/javascript/mastodon/features/terms_of_service/index.tsx +++ b/app/javascript/mastodon/features/terms_of_service/index.tsx @@ -7,9 +7,10 @@ import { defineMessages, } from 'react-intl'; -import { Helmet } from 'react-helmet'; import { Link, useParams } from 'react-router-dom'; +import { Helmet } from '@unhead/react/helmet'; + import { apiGetTermsOfService } from 'mastodon/api/instance'; import type { ApiTermsOfServiceJSON } from 'mastodon/api_types/instance'; import { Column } from 'mastodon/components/column'; diff --git a/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx index da98c5632f..81fb8f48c7 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx +++ b/app/javascript/mastodon/features/ui/components/bundle_column_error.jsx @@ -4,7 +4,7 @@ import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import { Link } from 'react-router-dom'; import { Button } from 'mastodon/components/button'; diff --git a/app/javascript/mastodon/features/ui/components/modal_root.jsx b/app/javascript/mastodon/features/ui/components/modal_root.jsx index 8938223c53..ff67e1b8f2 100644 --- a/app/javascript/mastodon/features/ui/components/modal_root.jsx +++ b/app/javascript/mastodon/features/ui/components/modal_root.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { Helmet } from 'react-helmet'; +import { Helmet } from '@unhead/react/helmet'; import Base from 'mastodon/components/modal_root'; import { AltTextModal } from 'mastodon/features/alt_text_modal'; diff --git a/app/javascript/mastodon/features/ui/util/intersection_observer_wrapper.js b/app/javascript/mastodon/features/ui/util/intersection_observer_wrapper.js index 2b24c65831..456bde11b5 100644 --- a/app/javascript/mastodon/features/ui/util/intersection_observer_wrapper.js +++ b/app/javascript/mastodon/features/ui/util/intersection_observer_wrapper.js @@ -25,7 +25,7 @@ class IntersectionObserverWrapper { this.observerBacklog.forEach(([ id, node, callback ]) => { this.observe(id, node, callback); }); - this.observerBacklog = null; + this.observerBacklog = []; } observe (id, node, callback) { diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index c0ce1821c0..63e215c81c 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -136,10 +136,10 @@ "account.share": "Κοινοποίηση του προφίλ @{name}", "account.show_reblogs": "Εμφάνιση ενισχύσεων από @{name}", "account.statuses_counter": "{count, plural, one {{counter} ανάρτηση} other {{counter} αναρτήσεις}}", - "account.timeline.pinned": "Καρφιτσωμένα", + "account.timeline.pinned": "Καρφιτσωμένη", "account.timeline.pinned.view_all": "Προβολή όλων των καρφιτσωμένων αναρτήσεων", "account.unblock": "Άρση αποκλεισμού @{name}", - "account.unblock_domain": "Άρση αποκλεισμού του τομέα {domain}", + "account.unblock_domain": "Άρση αποκλεισμού τομέα {domain}", "account.unblock_domain_short": "Άρση αποκλ.", "account.unblock_short": "Άρση αποκλεισμού", "account.unendorse": "Να μην αναδεικνύεται στο προφίλ", @@ -162,7 +162,7 @@ "account_edit.custom_fields.edit_label": "Επεξεργασία πεδίου", "account_edit.custom_fields.placeholder": "Προσθέστε τις αντωνυμίες σας, εξωτερικούς συνδέσμους ή οτιδήποτε άλλο θέλετε να μοιραστείτε.", "account_edit.custom_fields.reorder_button": "Αναδιάταξη πεδίων", - "account_edit.custom_fields.tip_content": "Μπορείς εύκολα να προσθέσεις αξιοπιστία στον Mastodon λογαριασμό σου επαληθεύοντας συνδέσμους σε οποιεσδήποτε ιστοσελίδες κατέχεις.", + "account_edit.custom_fields.tip_content": "Μπορείς εύκολα να προσθέσεις αξιοπιστία στον Mastodon λογαριασμό σου επαληθεύοντας συνδέσμους προς οποιεσδήποτε ιστοσελίδες κατέχεις.", "account_edit.custom_fields.tip_title": "Συμβουλή: Προσθήκη επαληθευμένων συνδέσμων", "account_edit.custom_fields.title": "Προσαρμοσμένα πεδία", "account_edit.custom_fields.verified_hint": "Πώς προσθέτω έναν επαληθευμένο σύνδεσμο;", @@ -241,7 +241,7 @@ "account_edit.upload_modal.title_add.header": "Προσθήκη εικόνας εξωφύλλου", "account_edit.upload_modal.title_replace.avatar": "Αντικατάσταση εικόνας προφίλ", "account_edit.upload_modal.title_replace.header": "Αντικατάσταση εικόνας εξωφύλλου", - "account_edit.verified_modal.details": "Πρόσθεσε αξιοπιστία στο Mastodon προφίλ σας επαληθεύοντας συνδέσμους σε προσωπικές ιστοσελίδες. Ορίστε πως δουλεύει:", + "account_edit.verified_modal.details": "Πρόσθεσε αξιοπιστία στο Mastodon προφίλ σου επαληθεύοντας συνδέσμους προς προσωπικές ιστοσελίδες. Ορίστε πως δουλεύει:", "account_edit.verified_modal.invisible_link.details": "Πρόσθεσε τον σύνδεσμο στην κεφαλίδα σου. Το σημαντικό μέρος είναι το rel=\"me\" που αποτρέπει την μίμηση σε ιστοσελίδες με περιεχόμενο παραγόμενο από χρήστες. Μπορείς ακόμα να χρησιμοποιήσεις μια ετικέτα link στην κεφαλίδα της σελίδας αντί για {tag}, αλλά η HTML πρέπει να είναι προσβάσιμη χωρίς την εκτέλεση JavaScript.", "account_edit.verified_modal.invisible_link.summary": "Πώς κάνω αυτόν τον σύνδεσμο αόρατο;", "account_edit.verified_modal.step1.header": "Αντίγραψε τον παρακάτω κώδικα HTML και επικόλλησε τον στην κεφαλίδα της ιστοσελίδας σου", @@ -250,7 +250,7 @@ "account_edit.verified_modal.title": "Πώς να προσθέσεις έναν επαληθευμένο σύνδεσμο", "account_edit_tags.add_tag": "Προσθήκη #{tagName}", "account_edit_tags.column_title": "Επεξεργασία Ετικετών", - "account_edit_tags.help_text": "Οι αναδεδειγμένες ετικέτες βοηθούν τους χρήστες να ανακαλύψουν και να αλληλεπιδράσουν με το προφίλ σας. Εμφανίζονται ως φίλτρα στην προβολή Δραστηριότητας της σελίδας προφίλ σας.", + "account_edit_tags.help_text": "Οι αναδεδειγμένες ετικέτες βοηθούν τους χρήστες να ανακαλύψουν και να αλληλεπιδράσουν με το προφίλ σας. Εμφανίζονται ως φίλτρα στην καρτέλα Δραστηριότητα της σελίδας προφίλ σας.", "account_edit_tags.max_tags_reached": "Έχετε φτάσει τον μέγιστο αριθμό των προτεινόμενων ετικετών.", "account_edit_tags.search_placeholder": "Εισάγετε μια ετικέτα…", "account_edit_tags.suggestions": "Προτάσεις:", @@ -866,7 +866,7 @@ "lists.done": "Έγινε", "lists.edit": "Επεξεργασία λίστας", "lists.exclusive": "Απόκρυψη μελών από την Αρχική", - "lists.exclusive_hint": "Αν κάποιος είναι σε αυτή τη λίστα, απόκρυψέ τον από την Αρχική σου για να αποφύγεις να βλέπεις τις αναρτήσεις του δύο φορές.", + "lists.exclusive_hint": "Αν κάποιος είναι σε αυτή τη λίστα, απόκρυψέ τον από την Αρχική ροή σου για να αποφύγεις να βλέπεις τις αναρτήσεις του δύο φορές.", "lists.find_users_to_add": "Εύρεση χρηστών για προσθήκη", "lists.list_members_count": "{count, plural, one {# μέλος} other {# μέλη}}", "lists.list_name": "Όνομα λίστας", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index b306d90bd3..1253660898 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -796,6 +796,7 @@ "info_button.label": "Help", "info_button.what_is_alt_text": "

What is alt text?

Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.

You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.

  • Capture important elements
  • Summarize text in images
  • Use regular sentence structure
  • Avoid redundant information
  • Focus on trends and key findings in complex visuals (like diagrams or maps)
", "interaction_modal.action": "To interact with {name}'s post, you need to sign into your account on whatever Mastodon server you use.", + "interaction_modal.action_follow": "To follow {name}, you need to sign into your account on whatever Mastodon server you use.", "interaction_modal.go": "Go", "interaction_modal.no_account_yet": "Don't have an account yet?", "interaction_modal.on_another_server": "On a different server", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index d99a25c6be..ae3b58d737 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -1043,9 +1043,9 @@ "notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas", "notifications.policy.filter_not_following_hint": "Jusqu'à ce que vous les validiez manuellement", "notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas", - "notifications.policy.filter_private_mentions_hint": "Filtrées sauf si c'est en réponse à l'une de vos mentions ou si vous suivez l'expéditeur·ice", + "notifications.policy.filter_private_mentions_hint": "Filtrées sauf si c'est en réponse à l'une de vos mentions ou si vous suivez la personne", "notifications.policy.filter_private_mentions_title": "Mentions privées non sollicitées", - "notifications.policy.title": "Gestion des notifications des …", + "notifications.policy.title": "Gestion des notifications des…", "notifications_permission_banner.enable": "Activer les notifications de bureau", "notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon n’est pas ouvert, activez les notifications de bureau. Vous pouvez contrôler précisément quels types d’interactions génèrent des notifications de bureau via le bouton {icon} ci-dessus une fois qu’elles sont activées.", "notifications_permission_banner.title": "Ne rien rater", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index c76754c1e5..678c0f5906 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -1027,7 +1027,7 @@ "notifications.group": "{count} notifications", "notifications.mark_as_read": "Marquer toutes les notifications comme lues", "notifications.permission_denied": "Impossible d’activer les notifications de bureau car l’autorisation a été refusée.", - "notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas être activées, car l’autorisation du navigateur a été refusée avant", + "notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas être activées, car l’autorisation du navigateur a été refusée auparavant", "notifications.permission_required": "Les notifications de bureau ne sont pas disponibles car l’autorisation requise n’a pas été accordée.", "notifications.policy.accept": "Accepter", "notifications.policy.accept_hint": "Afficher dans les notifications", @@ -1043,9 +1043,9 @@ "notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas", "notifications.policy.filter_not_following_hint": "Jusqu'à ce que vous les validiez manuellement", "notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas", - "notifications.policy.filter_private_mentions_hint": "Filtrées sauf si c'est en réponse à l'une de vos mentions ou si vous suivez l'expéditeur·ice", + "notifications.policy.filter_private_mentions_hint": "Filtrées sauf si c'est en réponse à l'une de vos mentions ou si vous suivez la personne", "notifications.policy.filter_private_mentions_title": "Mentions privées non sollicitées", - "notifications.policy.title": "Gestion des notifications des …", + "notifications.policy.title": "Gestion des notifications des…", "notifications_permission_banner.enable": "Activer les notifications de bureau", "notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon n’est pas ouvert, activez les notifications du bureau. Vous pouvez contrôler précisément quels types d’interactions génèrent des notifications de bureau via le bouton {icon} ci-dessus une fois qu’elles sont activées.", "notifications_permission_banner.title": "Toujours au courant", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 96da1b8d85..41fdb1ec39 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -328,11 +328,15 @@ "annual_report.summary.share_on_mastodon": "Comhroinn ar Mastodon", "attachments_list.unprocessed": "(neamhphróiseáilte)", "audio.hide": "Cuir fuaim i bhfolach", + "block_modal.no_collections": "Ní féidir le ceachtar agaibh a chéile a chur le bailiúcháin. Bainfear sibh go huathoibríoch ó bhailiúcháin atá agaibh cheana féin, más infheidhme.", "block_modal.remote_users_caveat": "Iarrfaimid ar an bhfreastalaí {domain} meas a bheith agat ar do chinneadh. Mar sin féin, ní ráthaítear comhlíonadh toisc go bhféadfadh roinnt freastalaithe bloic a láimhseáil ar bhealach difriúil. Seans go mbeidh postálacha poiblí fós le feiceáil ag úsáideoirí nach bhfuil logáilte isteach.", "block_modal.show_less": "Taispeáin níos lú", "block_modal.show_more": "Taispeáin níos mó", + "block_modal.they_cant_mention": "Ní féidir libh a chéile a lua, a leanúint ná a chéile a lua.", + "block_modal.they_cant_see_posts": "Ní féidir leo d’ábhar a fheiceáil agus ní fheicfidh tú a gcuid ábhair.", "block_modal.they_will_know": "Is féidir leo a fheiceáil go bhfuil bac orthu.", "block_modal.title": "Úsáideoir a bhlocáil?", + "block_modal.you_wont_see_mentions": "Ní fheicfidh tú poist ó dhaoine eile a luann iad.", "boost_modal.combo": "Is féidir leat {combo} a bhrú chun é seo a scipeáil an chéad uair eile", "boost_modal.reblog": "An post a threisiú?", "boost_modal.undo_reblog": "An deireadh a chur le postáil?", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 291829bfa9..dffd687feb 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -224,6 +224,7 @@ "account_edit.profile_tab.show_media.title": "„Média” lap megjelenítése", "account_edit.profile_tab.show_media_replies.description": "Ha engedélyezve van, akkor a Média lap megjeleníti a bejegyzéseidet és a mások bejegyzéseihez írt válaszaidat.", "account_edit.profile_tab.show_media_replies.title": "Válaszok megjelenítése a „Média” lapon", + "account_edit.profile_tab.show_relations.description": "A profilodban megjeleníti azokat a fiókokat, melyeket követsz, valamint a többi felhasználó követőit. Mások továbbra is látni fogják, hogy követed-e őket.", "account_edit.profile_tab.show_relations.title": "„Követők” és „Követettek” megjelenítése", "account_edit.profile_tab.subtitle": "A profil megjelenítésének testreszabása.", "account_edit.profile_tab.title": "Profil megjelenítési beállításai", @@ -327,6 +328,7 @@ "annual_report.summary.share_on_mastodon": "Megosztás a Mastodonon", "attachments_list.unprocessed": "(feldolgozatlan)", "audio.hide": "Hang elrejtése", + "block_modal.no_collections": "Egyikőtök sem adhatja hozzá a másikat gyűjteményekhez. Automatikusan el is lesztek távolítva az egymás gyűjteményéből.", "block_modal.remote_users_caveat": "Arra kérjük a {domain} kiszolgálót, hogy tartsa tiszteletben a döntésedet. Ugyanakkor az együttműködés nem garantált, mivel néhány kiszolgáló másképp kezelheti a letiltásokat. A nyilvános bejegyzések a be nem jelentkezett felhasználók számára továbbra is látszódhatnak.", "block_modal.show_less": "Kevesebb mutatása", "block_modal.show_more": "Több mutatása", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index 080e2d1813..37ddb9d07b 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -36,6 +36,7 @@ "account.familiar_followers_many": "Yeṭṭafaṛ-it {name1} d {name2}, akked {othersCount, plural, one {yiwen nniḍen i tessneḍ} other {# nniḍen i tessneḍ}}", "account.familiar_followers_one": "Yeṭṭafar-it {name1}", "account.familiar_followers_two": "Yeṭṭafar-it {name1} akked {name2}", + "account.featured": "Ufrinen", "account.featured.accounts": "Imeɣna", "account.featured.collections": "Tilkensa", "account.featured.new_collection": "Talkensit tamaynut", @@ -68,6 +69,8 @@ "account.join_modal.me_today": "Ass-a, d ass-ik⋅im amezwaru deg {server}!", "account.join_modal.other": "{name} yerna-d ɣer {server} ass n", "account.join_modal.other_today": "D ass amezwaru n {name} ɣef {server}!", + "account.join_modal.share.intro": "Bḍu izen anida deg-s ad temmeslayeḍ fell-ak⋅am", + "account.join_modal.years": "{number, plural, one {n useggas} other {n iseggasen}}", "account.joined_short": "Izeddi da seg ass n", "account.languages": "Beddel tutlayin yettwajerden", "account.last_active": "Armud aneggaru", @@ -87,6 +90,7 @@ "account.menu.remove_follower": "Kkes aneḍfar", "account.menu.report": "Cetki ɣef umiḍan-a", "account.menu.share": "Zuzer…", + "account.menu.unblock": "Kkes asewḥel i umiḍan", "account.moved_to": "{name} yenna-d dakken amiḍan-is amaynut yuɣal :", "account.mute": "Sgugem @{name}", "account.mute_notifications_short": "Susem ilɣa", @@ -141,6 +145,7 @@ "account_edit.display_name.edit_label": "Ẓreg isem ara d-yettwaskanen", "account_edit.display_name.title": "Isem ara d-yettwaskanen", "account_edit.featured_hashtags.edit_label": "Rnu ihacṭagen", + "account_edit.featured_hashtags.title": "Ihacṭagen ufrinen", "account_edit.field_actions.delete": "Kkes urti", "account_edit.field_actions.edit": "Ẓreg urti", "account_edit.field_delete_modal.delete_button": "Kkes", @@ -167,6 +172,7 @@ "account_edit.name_modal.add_title": "Rnu isem ara d-yettwaskanen", "account_edit.name_modal.edit_title": "Ẓreg isem ara d-yettwaskanen", "account_edit.profile_tab.button_label": "Sagen", + "account_edit.profile_tab.show_featured.title": "Sken-d accer n \"Ufrinen\"", "account_edit.save": "Sekles", "account_edit.upload_modal.back": "Uɣal", "account_edit.upload_modal.done": "Dayen", @@ -179,12 +185,16 @@ "account_edit.upload_modal.title_add.header": "Rnu tawlaft n tduli", "account_edit.upload_modal.title_replace.avatar": "Semselsi tawlaft n umaɣnu", "account_edit.upload_modal.title_replace.header": "Semselsi tawlaft n tduli", + "account_edit.verified_modal.invisible_link.summary": "Amek ara rreɣ aseɣwen-nni ur yettban ara?", + "account_edit.verified_modal.title": "Amek ara ternuḍ aseɣwen yettuselknen", "account_edit_tags.add_tag": "Rnu #{tagName}", "account_edit_tags.column_title": "Asiẓreg n yihacṭagen", "account_edit_tags.search_placeholder": "Sekcem-d ahacṭag…", "account_edit_tags.suggestions": "Isumren:", "account_edit_tags.tag_status_count": "{count, plural, one {# n yizen} other {# n yiznan}}", + "account_list.total": "{total, plural, one {# n umiḍan} other {# n imiḍanen}}", "account_note.placeholder": "Ulac iwenniten", + "admin.dashboard.retention.cohort": "Ajerred deg ayyur", "admin.dashboard.retention.cohort_size": "Iseqdacen imaynuten", "alert.rate_limited.message": "Ma ulac aɣilif ɛreḍ tikelt-nniḍen akka {retry_time, time, medium}.", "alert.rate_limited.title": "Aktum s talast", @@ -223,6 +233,7 @@ "block_modal.title": "Sewḥel aseqdac ?", "boost_modal.combo": "Tzemreḍ ad tsiteḍ ɣef {combo} akken ad tzegleḍ aya tikelt i d-iteddun", "boost_modal.reblog": "Zuzer tasuffeɣt?", + "boost_modal.undo_reblog": "Semmet azuzer n yizen-a?", "bundle_column_error.copy_stacktrace": "Nɣel tuccḍa n uneqqis", "bundle_column_error.error.title": "Uh, ala !", "bundle_column_error.network.body": "Teḍra-d tuccḍa deg usali n usebter-a. Aya yezmer ad yili d ugur akudan deg tuqqna-inek·inem ɣer internet neɣ deg uqeddac-a.", @@ -234,6 +245,7 @@ "bundle_modal_error.close": "Mdel", "bundle_modal_error.retry": "Ɛreḍ tikelt-nniḍen", "callout.dismiss": "Zgel-it", + "character_counter.required": "{currentLength}/{maxLength} n yisekkilen", "closed_registrations_modal.description": "Asnulfu n umiḍan deg {domain} mačči d ayen izemren ad yili, maca ttxil-k·m, err deg lbal-ik·im belli ur teḥwaǧeḍ ara amiḍan s wudem ibanen ɣef {domain} akken ad tesqedceḍ Mastodon.", "closed_registrations_modal.find_another_server": "Aff-d aqeddac nniḍen", "closed_registrations_modal.title": "Ajerred deg Masṭudun", @@ -243,6 +255,8 @@ "collection.share_modal.title": "Bḍu talkensit", "collection.share_modal.title_new": "Zuzer talkensit-ik·im tamaynut!", "collections.account_count": "{count, plural, one {# n umiḍan} other {# n imiḍanen}}", + "collections.accounts.empty_description": "Rnu alamma d {count} n imiḍanen", + "collections.accounts.empty_editor_title": "Ulac ula yiwen ɛad deg telkensit-a", "collections.accounts.empty_title": "Talkensit-a d tilemt", "collections.block_collection_owner": "Sewḥel amiḍan", "collections.by_account": "sɣur {account_handle}", @@ -262,12 +276,14 @@ "collections.detail.revoke_inclusion": "Kkes-iyi", "collections.detail.sensitive_content": "Agbur amḥulfu", "collections.detail.share": "Zuzer talkensit-a", + "collections.detail.you_are_in_this_collection": "Aql-ik⋅em ɣer sdat deg telsenkit-a", "collections.edit_details": "Ẓreg talqayt", "collections.hidden_accounts_link": "{count, plural, one {# n umiḍan uffir} other {# n imiḍanen yettwaffaren}}", "collections.hints.accounts_counter": "{count}/{max} n imiḍanen", "collections.last_updated_at": "Taẓrigt taneggarut: {date}", "collections.list.created_by_author": "D-yesnulfa {name}", "collections.list.created_by_you": "D-tesnulfaḍ", + "collections.list.featuring_you": "Yid-k⋅m", "collections.manage_accounts": "Sefrek imiḍanen", "collections.name_length_hint": "talast n 40 n yisekkilen", "collections.new_collection": "Talkensit tamaynut", @@ -276,6 +292,7 @@ "collections.revoke_collection_inclusion": "Kkes-iyi seg telkensit-a", "collections.search_accounts_label": "Nadi ɣef umiḍan ara ternuḍ", "collections.share_short": "Bḍu", + "collections.suggestions.can_not_add": "Ur tezmireḍ ara ad t-ternuḍt", "collections.view_collection": "Wali talkensit", "collections.visibility_public": "Azayaz", "collections.visibility_title": "Abani", @@ -290,6 +307,7 @@ "column.edit_list": "Ẓreg tabdart", "column.favourites": "Imenyafen", "column.firehose": "Isuddam usriden", + "column.firehose_singular": "Asuddem usrid", "column.follow_requests": "Isuturen n teḍfeṛt", "column.home": "Agejdan", "column.list_members": "Sefrek iεeggalen n tebdart", @@ -299,6 +317,7 @@ "column.other_collections": "Tilkensa sɣur {name}", "column.pins": "Tisuffaɣ yettwasenṭḍen", "column.public": "Tasuddemt tamatut", + "column.your_collections": "Tilkensa-k·m", "column_back_button.label": "Tuɣalin", "column_header.hide_settings": "Ffer iɣewwaṛen", "column_header.moveLeft_settings": "Err ajgu ɣer tama tazelmaḍt", @@ -355,6 +374,7 @@ "confirmations.follow_to_list.confirm": "Ḍfeṛ-it sakin rnu-t ɣer tebdart", "confirmations.follow_to_list.title": "Ḍfer aseqdac?", "confirmations.hide_featured_tab.confirm": "Ffer accer", + "confirmations.hide_featured_tab.title": "Ffer accer n \"Ufrinen\"?", "confirmations.logout.confirm": "Ffeɣ", "confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?", "confirmations.logout.title": "Tebɣiḍ ad teffɣeḍ ssya?", @@ -432,11 +452,13 @@ "emoji_button.symbols": "Izamulen", "emoji_button.travel": "Imeḍqan d Yinigen", "empty_column.account_featured_self.no_collections_button": "Snulfu-d talkensit", + "empty_column.account_featured_self.no_collections_hide_tab": "Ɣumm accer-a", "empty_column.account_suspended": "Amiḍan yettwaḥbas", "empty_column.account_timeline": "Ulac tisuffaɣ da !", "empty_column.account_unavailable": "Ur nufi ara amaɣnu-ayi", "empty_column.blocks": "Ur tesḥebseḍ ula yiwen n umseqdac ar tura.", "empty_column.bookmarked_statuses": "Ulac kra n tsuffeɣt i terniḍ ɣer yismenyifen-ik·im ar tura. Ticki terniḍ yiwet, ad d-tettwasken da.", + "empty_column.collections.featured_in": "Ur-k yerni ḥedd ɛad ɣer kra n telkensit.", "empty_column.community": "Tasuddemt tazayezt tadigant n yisallen d tilemt. Aru ihi kra akken ad tt-teččareḍ!", "empty_column.domain_blocks": "Ulac kra n taɣult yettwaffren ar tura.", "empty_column.explore_statuses": "Ulac ayen yellan d anezzuɣ akka tura. Uɣal-d ticki!", @@ -458,6 +480,7 @@ "explore.trending_tags": "Ihacṭagen", "featured_carousel.current": "Izen wis {current, number} / {max, number}", "featured_carousel.header": "{count, plural, one {n tsuffeɣt tunṭiḍt} other {n tsuffaɣ tunṭiḍin}}", + "featured_carousel.slide": "Iznen {current, number} ɣef {max, number}", "featured_tags.more_items": "+{count}", "featured_tags.suggestions.add": "Rnu", "featured_tags.suggestions.dismiss": "Uhu, tanemmirt", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 5067e505a4..9daf7c29c9 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -43,6 +43,7 @@ "account.featured": "Utvald", "account.featured.accounts": "Profilar", "account.featured.collections": "Samlingar", + "account.featured.new_collection": "Ny samling", "account.field_overflow": "Vis heile innhaldet", "account.filters.all": "All aktivitet", "account.filters.boosts_toggle": "Vis framhevingar", @@ -68,6 +69,16 @@ "account.go_to_profile": "Gå til profil", "account.hide_reblogs": "Gøym framhevingar frå @{name}", "account.in_memoriam": "Til minne om.", + "account.join_modal.day": "Dag", + "account.join_modal.me": "Du vart medlem av {server} den", + "account.join_modal.me_anniversary": "God allheimsbursdag! Du vart medlem av {server} den", + "account.join_modal.me_today": "Det er fyrste dagen din på {server}!", + "account.join_modal.other": "{name} vart medlem av {server} den", + "account.join_modal.other_today": "{name} har sin fyrste dag på {server}!", + "account.join_modal.share.celebrate": "Skriv eit jubileumsinnlegg", + "account.join_modal.share.intro": "Skriv eit introduksjonsinnlegg", + "account.join_modal.share.welcome": "Skriv eit velkomstinnlegg", + "account.join_modal.years": "{number, plural, one {år} other {år}}", "account.joined_short": "Vart med", "account.languages": "Endre språktingingar", "account.last_active": "Sist aktiv", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index cc993ce578..4c952ba57d 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -324,11 +324,15 @@ "annual_report.summary.share_on_mastodon": "Ndajeni në Mastodon me të tjerë", "attachments_list.unprocessed": "(e papërpunuar)", "audio.hide": "Fshihe audion", + "block_modal.no_collections": "Asnjë prej jush s’mund shtojë tjetrin te koleksione. Do të hiqeni automatikisht nga koleksionne ekzistuese të njëri-tjetrit, nëse ka vend.", "block_modal.remote_users_caveat": "Do t’i kërkojmë shërbyesit {domain} të respektojë vendimin tuaj. Por, pajtimi s’është i garantuar, ngaqë disa shërbyes mund t’i trajtojnë ndryshe bllokimet. Psotimet publike mundet të jenë ende të dukshme për përdorues pa bërë hyrje në llogari.", "block_modal.show_less": "Shfaq më pak", "block_modal.show_more": "Shfaq më tepër", + "block_modal.they_cant_mention": "S’mund të përmendni, ndiqni, ose citoni njëri-tjetrin.", + "block_modal.they_cant_see_posts": "S’mund të shohin lëndën tuaj dhe ju s’do të shihni të tyren.", "block_modal.they_will_know": "Mund të shohin se janë bllokuar.", "block_modal.title": "Të bllokohet përdoruesi?", + "block_modal.you_wont_see_mentions": "S’do të shihni postime nga të tjerë që i përmendin ata.", "boost_modal.combo": "Që kjo të anashkalohet herës tjetër, mund të shtypni {combo}", "boost_modal.reblog": "Përforcim postimi?", "boost_modal.undo_reblog": "Të hiqet përforcim për postimin?", diff --git a/app/javascript/mastodon/main.tsx b/app/javascript/mastodon/main.tsx index 965645f9e6..ccefd7f366 100644 --- a/app/javascript/mastodon/main.tsx +++ b/app/javascript/mastodon/main.tsx @@ -1,3 +1,4 @@ +import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import { Globals } from '@react-spring/web'; @@ -33,7 +34,11 @@ function main() { await initializeEmoji(); const root = createRoot(mountNode); - root.render(); + root.render( + + + , + ); store.dispatch(setupBrowserNotifications()); if (isProduction() && me && 'serviceWorker' in navigator) { diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss index 924b12434b..d4eb434a2b 100644 --- a/app/javascript/styles/mastodon/accounts.scss +++ b/app/javascript/styles/mastodon/accounts.scss @@ -231,75 +231,6 @@ border-color: var(--color-border-error-soft); } -.account__header__fields { - max-width: 100vw; - padding: 0; - margin: 15px -15px -15px; - border: 0 none; - border-top: 1px solid var(--color-border-primary); - border-bottom: 1px solid var(--color-border-primary); - font-size: 14px; - line-height: 20px; - - dl { - display: flex; - border-bottom: 1px solid var(--color-border-primary); - } - - dt, - dd { - box-sizing: border-box; - padding: 14px; - text-align: center; - max-height: 48px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - } - - dt { - font-weight: 500; - width: 120px; - flex: 0 0 auto; - color: var(--color-text-primary); - background: var(--color-bg-secondary); - } - - dd { - flex: 1 1 auto; - color: var(--color-text-secondary); - } - - a { - color: var(--color-text-brand); - text-decoration: none; - - &:hover, - &:focus, - &:active { - text-decoration: underline; - } - } - - .verified { - border: 1px solid var(--color-border-success-soft); - background: var(--color-bg-success-softest); - - a { - color: var(--color-text-success); - font-weight: 500; - } - - &__mark { - color: var(--color-text-success); - } - } - - dl:last-child { - border-bottom: 0; - } -} - .directory__tag .trends__item__current { width: auto; } diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 9921370f09..fc730d0c22 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1051,35 +1051,121 @@ a.name-tag, max-width: 100%; } - .account__header__fields, - .account__header__content { + &__fields, + &__content { background: var(--color-bg-primary); border: 1px solid var(--color-border-primary); border-radius: 4px; height: 100%; } - .account__header__fields { - margin: 0; + &__fields { border: 1px solid var(--color-border-primary); + font-size: 14px; + line-height: 20px; + display: grid; + grid-template-columns: 120px auto; + grid-auto-flow: row; + + dl { + display: flex; + } + + dt, + dd { + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + padding: 14px; + text-align: center; + border-bottom: 1px solid var(--color-border-primary); + + &:last-of-type:not(.verified) { + border-bottom: none; + } + } + + dt { + font-weight: 500; + width: 120px; + flex: 0 0 auto; + color: var(--color-text-primary); + background: var(--color-bg-secondary); + } + + dd { + flex: 1 1 auto; + color: var(--color-text-secondary); + + &:first-of-type.verified { + border-top-right-radius: 4px; + } + + &:last-of-type.verified { + border-bottom-right-radius: 4px; + } + } a { color: var(--color-text-brand); + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } } - dl:first-child .verified { - border-radius: 0 4px 0 0; - } + .verified { + border: 1px solid var(--color-border-success-soft); + background: var(--color-bg-success-softest); - .verified a { - color: var(--color-text-success); + a { + color: var(--color-text-success); + font-weight: 500; + } + + &__mark { + color: var(--color-text-success); + + > svg { + vertical-align: middle; + } + } } } - .account__header__content { + &__content { box-sizing: border-box; padding: 20px; color: var(--color-text-primary); + font-size: 14px; + font-weight: 400; + overflow: hidden; + word-break: normal; + overflow-wrap: break-word; + + p { + margin-bottom: 20px; + unicode-bidi: plaintext; + + &:last-child { + margin-bottom: 0; + } + } + + a { + color: var(--color-text-brand); + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } } } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index eb0869d04f..b931d46d11 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -8320,372 +8320,6 @@ noscript { } } -.account__header__content { - color: var(--color-text-secondary); - font-size: 14px; - font-weight: 400; - overflow: hidden; - word-break: normal; - overflow-wrap: break-word; - - p { - margin-bottom: 20px; - unicode-bidi: plaintext; - - &:last-child { - margin-bottom: 0; - } - } - - a { - color: inherit; - text-decoration: underline; - - &:hover { - text-decoration: none; - } - } -} - -.account__header { - container: account-header / inline-size; - - &.inactive { - opacity: 0.5; - - .account__header__image, - .account__avatar { - filter: grayscale(100%); - } - } - - &__info { - position: absolute; - top: 20px; - inset-inline-end: 20px; - display: flex; - flex-wrap: wrap; - gap: 2px; - } - - &__image { - overflow: hidden; - height: 145px; - position: relative; - background: var(--color-bg-tertiary); - border-bottom: 1px solid var(--color-border-primary); - - img { - object-fit: cover; - display: block; - width: 100%; - height: 100%; - margin: 0; - } - } - - &__bar { - position: relative; - padding: 0 20px; - border-bottom: 1px solid var(--color-border-primary); - - .avatar { - display: block; - flex: 0 0 auto; - - .account__avatar { - background: var(--color-bg-primary); - border: 1px solid var(--color-border-primary); - border-radius: var(--avatar-border-radius); - } - } - } - - &__tabs { - display: flex; - align-items: flex-start; - justify-content: space-between; - margin-top: -55px; - padding-top: 10px; - gap: 8px; - overflow: hidden; - margin-inline-start: -2px; // aligns the pfp with content below - - &__name { - margin-top: 16px; - margin-bottom: 16px; - - .emojione { - width: 22px; - height: 22px; - } - - h1 { - font-size: 17px; - line-height: 22px; - color: var(--color-text-primary); - font-weight: 600; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - - small { - display: flex; - align-items: center; - gap: 4px; - font-size: 14px; - line-height: 20px; - color: var(--color-text-secondary); - font-weight: 400; - overflow: hidden; - text-overflow: ellipsis; - - span { - overflow: hidden; - text-overflow: ellipsis; - user-select: all; - } - - .icon-lock { - height: 18px; - width: 18px; - } - } - } - } - - .spacer { - flex: 1 1 auto; - } - } - - &__follow-button { - flex-grow: 1; - } - - &__buttons { - display: flex; - align-items: center; - gap: 8px; - - $button-breakpoint: 420px; - $button-fallback-breakpoint: $button-breakpoint + 55px; - - &--desktop { - margin-top: 55px; - - @container (width < #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (max-width: #{$button-fallback-breakpoint}) { - display: none; - } - } - } - - &--mobile { - margin-block: 16px; - - @container (width >= #{$button-breakpoint}) { - display: none; - } - - @supports (not (container-type: inline-size)) { - @media (min-width: ($button-fallback-breakpoint + 1px)) { - display: none; - } - } - } - - .button { - flex-shrink: 1; - white-space: nowrap; - min-width: 80px; - } - - .icon-button { - border: 1px solid var(--color-border-primary); - border-radius: 4px; - box-sizing: content-box; - padding: 5px; - - .icon { - width: 24px; - height: 24px; - } - - &.copied { - border-color: var(--color-text-success); - } - } - } - - &__bio { - .account__header__content { - color: var(--color-text-primary); - } - - .account__header__fields { - margin: 0; - margin-top: 16px; - border-radius: 4px; - border: 1px solid var(--color-border-primary); - - dl { - display: block; - padding: 11px 16px; - border-bottom-color: var(--color-border-primary); - } - - dd, - dt { - font-size: 13px; - line-height: 18px; - padding: 0; - text-align: initial; - } - - dt { - width: auto; - background: transparent; - text-transform: uppercase; - color: var(--color-text-tertiary); - } - - dd { - color: var(--color-text-secondary); - } - - a { - color: var(--color-text-brand); - } - - .icon { - width: 18px; - height: 18px; - } - - .verified { - border: 1px solid var(--color-text-success); - margin-top: -1px; - margin-inline: -1px; - - &:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - } - - &:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - margin-bottom: -1px; - } - - dt, - dd { - color: var(--color-text-success); - } - - dd { - display: flex; - align-items: center; - gap: 4px; - - span { - display: flex; - } - } - - a { - color: var(--color-text-success); - } - } - } - } - - &__extra { - margin-top: 16px; - - &__links { - font-size: 14px; - color: var(--color-text-secondary); - margin: 0 -10px; - padding-top: 16px; - padding-bottom: 10px; - - a { - display: inline-block; - color: var(--color-text-secondary); - text-decoration: none; - padding: 5px 10px; - font-weight: 500; - - strong { - font-weight: 700; - color: var(--color-text-primary); - } - } - } - } - - &__account-note { - color: var(--color-text-primary); - font-size: 14px; - font-weight: 400; - margin-bottom: 10px; - - &__loading-indicator-wrapper { - position: relative; - height: 37px; - - .loading-indicator { - left: 10px; - } - - .circular-progress { - width: 14px; - height: 14px; - } - } - - label { - display: block; - font-size: 12px; - font-weight: 500; - color: var(--color-text-secondary); - text-transform: uppercase; - margin-bottom: 5px; - } - - textarea { - display: block; - box-sizing: border-box; - width: calc(100% + 20px); - color: var(--color-text-primary); - background: transparent; - padding: 10px; - margin: 0 -10px; - font-family: inherit; - font-size: 14px; - resize: none; - border: 0; - outline: 0; - border-radius: 4px; - - &::placeholder { - color: var(--color-text-tertiary); - opacity: 1; - } - - &:focus { - background: var(--color-bg-brand-softest); - } - } - } -} - .account__contents { overflow: hidden; } diff --git a/app/lib/permalink_redirector.rb b/app/lib/permalink_redirector.rb index 19fb3f401c..6cf071a098 100644 --- a/app/lib/permalink_redirector.rb +++ b/app/lib/permalink_redirector.rb @@ -21,6 +21,9 @@ class PermalinkRedirector elsif accounts_request? && record_integer_id_request? account = Account.find_by(id: second_segment) account if !account&.local? && !account&.suspended? + elsif collections_request? && record_integer_id_request? + collection = Collection.find_by(id: second_segment) + collection if !collection&.local? && !collection&.account&.suspended? end end end @@ -43,6 +46,8 @@ class PermalinkRedirector redirect_account_path(object.id) when 'Status' redirect_status_path(object.id) + when 'Collection' + redirect_collection_path(object.id) else @path.delete_prefix('/deck') if @path.start_with?('/deck') end @@ -70,6 +75,10 @@ class PermalinkRedirector first_segment == 'accounts' end + def collections_request? + first_segment == 'collections' + end + def record_integer_id_request? second_segment =~ /\d/ end diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb index b7b82a29c4..7ecb28ddb8 100644 --- a/app/models/collection_item.rb +++ b/app/models/collection_item.rb @@ -30,7 +30,7 @@ class CollectionItem < ApplicationRecord delegate :local?, :remote?, to: :collection - validates :account_id, uniqueness: { scope: :collection_id } + validates :account_id, uniqueness: { scope: :collection_id, allow_nil: true } validates :position, numericality: { only_integer: true, greater_than: 0 } validates :activity_uri, presence: true, if: :local_item_with_remote_account? validates :approval_uri, presence: true, unless: -> { local? || account&.local? || !accepted? } diff --git a/app/views/admin/accounts/_field.html.haml b/app/views/admin/accounts/_field.html.haml index ce8d80785e..fa68d08d37 100644 --- a/app/views/admin/accounts/_field.html.haml +++ b/app/views/admin/accounts/_field.html.haml @@ -1,9 +1,8 @@ -# locals: (field:, account:) -%dl - %dt.emojify{ title: field.name } - = prerender_custom_emojis(h(field.name), account.emojis) - %dd{ title: field.value, class: field_verified_class(field.verified?) } - - if field.verified? - %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } - = material_symbol 'check' - = prerender_custom_emojis(account_field_value_format(field, with_rel_me: false), account.emojis) +%dt.emojify{ title: field.name } + = prerender_custom_emojis(h(field.name), account.emojis) +%dd{ title: field.value, class: field_verified_class(field.verified?) } + - if field.verified? + %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } + = material_symbol 'check' + = prerender_custom_emojis(account_field_value_format(field, with_rel_me: false), account.emojis) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 977967c58f..d3a8a1f6fb 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -11,12 +11,12 @@ .admin-account-bio - if @account.fields? %div - .account__header__fields + %dl.admin-account-bio__fields = render partial: 'field', collection: @account.fields, locals: { account: @account } - if @account.note? %div - .account__header__content.emojify + .admin-account-bio__content.emojify = prerender_custom_emojis(account_bio_format(@account), @account.emojis) = render 'admin/accounts/counters', account: @account diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 0dc1d894ec..6695160f58 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -61,14 +61,11 @@ wrapper: :with_block_label - if approved_registrations? && @invite.blank? - %p.lead= t('auth.sign_up.manual_review', domain: site_hostname) - .fields-group = f.simple_fields_for :invite_request, resource.invite_request || resource.build_invite_request do |invite_request_fields| = invite_request_fields.input :text, as: :text, - hint: false, - label: false, + hint: t('auth.sign_up.manual_review', domain: site_hostname), input_html: { maxlength: UserInviteRequest::TEXT_SIZE_LIMIT }, required: Setting.require_invite_text, wrapper: :with_block_label diff --git a/bin/setup b/bin/setup index 4ccf4594b4..b3dbece5e6 100755 --- a/bin/setup +++ b/bin/setup @@ -18,7 +18,7 @@ FileUtils.chdir APP_ROOT do system('bundle check') || system!('bundle install') puts "\n== Installing JS dependencies ==" - system! 'corepack enable' + system! 'npm i -g corepack' system! 'bin/yarn install --immutable' puts "\n== Preparing database ==" diff --git a/config/locales/da.yml b/config/locales/da.yml index 1f8795c7fc..08697d48bd 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -484,8 +484,10 @@ da: title: Blokér nyt e-maildomæne no_email_domain_block_selected: Ingen e-maildomæneblokeringer ændret (ingen var valgt) not_permitted: Ikke tilladt + reset: Nulstil resolved_dns_records_hint_html: Domænenavnet opløses til flg. MX-domæner, som i sidste ende er ansvarlige for e-mailmodtagelse. Blokering af et MX-domæne blokerer også tilmeldinger fra enhver e-mailadresse på det pågældende MX-domæne, selv hvis det synlige domænenavn er et andet. Pas på ikke at blokere større e-mailudbydere. resolved_through_html: Opløst via %{domain} + search: Søg title: Blokerede e-maildomæner email_subscriptions: accounts: diff --git a/config/locales/de.yml b/config/locales/de.yml index 1521df439a..e6ebce926b 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -484,8 +484,10 @@ de: title: Neue E-Mail-Domain sperren no_email_domain_block_selected: Es wurden keine E-Mail-Domain-Sperren geändert, da keine ausgewählt wurden not_permitted: Nicht erlaubt + reset: Zurücksetzen resolved_dns_records_hint_html: Die Domain wird zu den folgenden MX-Domains aufgelöst, die für die Annahme von E-Mails zuständig sind. Das Sperren einer MX-Domain sperrt Anmeldungen aller E-Mail-Adressen, die dieselbe MX-Domain verwenden, auch wenn die sichtbare Domain anders lautet. Achte daher darauf, keine großen E-Mail-Anbieter versehentlich zu sperren. resolved_through_html: Durch %{domain} aufgelöst + search: Suchen title: Gesperrte E-Mail-Domains email_subscriptions: accounts: @@ -495,26 +497,39 @@ de: hint: Bisher wurden keine Konten abonniert. no_lists_yet: Noch keine Listen vorhanden inactive: Deaktiviert + last_email: Letzte E-Mail lead: Konten, die die Funktion aktiviert haben und abonniert wurden, werden unten angezeigt. status: Status subscribers: Abonnent*innen title: Mailingliste + additional_footer_texts: + show: + title: Fußzeile compliance_settings: additional_footer_text: action: Verwalten + hint: Der Text erscheint ausschließlich in der Fußzeile von E-Mails + title: Fußzeile + lead: E-Mail-Newsletter können abhängig vom geltenden Recht als Marketing-E-Mails betrachtet werden. privacy_policy: action: Verwalten + hint: Die Datenschutzerklärung wird in der Fußzeile jeder E-Mail beigefügt title: Datenschutzerklärung + title: Einstellungen zur Einhaltung von Vorschriften danger_zone: disable_feature: action: Deaktivieren + hint: Funktion für alle Konten deaktivieren title: Funktion deaktivieren erase_all_data: action: Daten löschen + hint: Löscht dauerhaft alle E-Mails aus allen Mailinglisten title: Alle Daten löschen title: Gefahrenzone + disabled_msg: E-Mail-Abonnements wurden erfolgreich deaktiviert. index: disabled: + description: Diese Funktion ermöglicht bestimmten Konten, ein Widget zu ihrem Profil hinzuzufügen, damit Gäste ohne Mastodon-Konto deren Beiträge per E-Mail erhalten können. get_started: Loslegen lead: Ermögliche Gästen, Beiträge von ausgewählten Konten dieses Servers per E-Mail zu abonnieren. title: E-Mail-Newsletter @@ -533,6 +548,11 @@ de: show: enable_feature: Funktionen aktivieren important_information: Wichtige Informationen + list: + 1_permission_explanation: Wenn die Funktion aktiviert ist, können alle berechtigten Konten ein E-Mail-Formular zu ihrem Profil hinzufügen. + 2_feature_explanation: Sobald Gäste ein Profil abonnieren und das Abonnement bestätigen, werden sie E-Mails über neue öffentliche Beiträge des betreffenden Profils erhalten. + 3_privacy_policy_warning: Server-Admins werden Zugriff auf persönlich identifizierbare Informationen (E-Mail-Adressen) haben. Daher müssen die Datenschutzerklärung und Nutzungsbedingungen im Vorfeld aktualisiert werden, bevor diese Funktion verwendet werden kann. + 4_cost_warning: Abhängig vom Hosting-Provider können Gebühren für den E-Mail-Versand anfallen. Kläre für deinen Server vorher alle Details, da diese Funktion die Anzahl versendeter E-Mails drastisch erhöhen kann. export_domain_allows: new: title: Erlaubte Domains importieren @@ -838,6 +858,7 @@ de: manage_custom_emojis: Emojis manage_custom_emojis_description: Spezielle Emojis dieses Servers verwalten manage_email_subscriptions: E-Mail-Abonnements + manage_email_subscriptions_description: Konten mit dieser Berechtigung dürfen die Funktion für E-Mail-Newsletter verwenden manage_federation: Föderation manage_federation_description: Domains anderer Mastodon-Server sperren/zulassen – und Zustellbarkeit kontrollieren manage_invites: Einladungen diff --git a/config/locales/el.yml b/config/locales/el.yml index 3ed839cd0d..7a7bdb5496 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -484,8 +484,10 @@ el: title: Αποκλεισμός νέου τομέα email no_email_domain_block_selected: Δεν άλλαξαν οι αποκλεισμοί τομέα email καθώς δεν επιλέχθηκε κανένας not_permitted: Δεν επιτρέπεται + reset: Επαναφορά resolved_dns_records_hint_html: Το όνομα τομέα επιλύεται στους ακόλουθους τομείς MX, οι οποίοι είναι τελικά υπεύθυνοι για την αποδοχή των email. Αποκλείοντας έναν τομέα MX θα αποκλείει τις εγγραφές από οποιαδήποτε διεύθυνση email που χρησιμοποιεί τον ίδιο τομέα MX, ακόμη και αν το ορατό όνομα τομέα είναι διαφορετικό. Προσέξτε να μην αποκλείσετε τους μεγάλους παρόχους ηλεκτρονικού ταχυδρομείου. resolved_through_html: Επιλύθηκε μέσω %{domain} + search: Αναζήτηση title: Αποκλεισμένοι τομείς email email_subscriptions: accounts: diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index b4ed310577..8ea041ed6d 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -484,8 +484,10 @@ es-AR: title: Bloquear nuevo dominio de correo electrónico no_email_domain_block_selected: No se cambiaron bloqueos de dominio de correo electrónico, ya que no se seleccionó ninguno not_permitted: No permitidos + reset: Restablecer resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Tené cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} + search: Buscar title: Dominios bloqueados de correo electrónico email_subscriptions: accounts: diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index 8a3e953d30..632bdca3e3 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -484,8 +484,10 @@ es-MX: title: Bloquear nuevo dominio de correo no_email_domain_block_selected: No se han cambiado bloqueos de dominio de correo, ya que ninguno ha sido seleccionado not_permitted: No permitido + reset: Restablecer resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Ten cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} + search: Buscar title: Dominios de correo bloqueados email_subscriptions: accounts: @@ -496,7 +498,7 @@ es-MX: no_lists_yet: No hay listas todavía inactive: Inactiva last_email: Último correo electrónico - lead: Las cuentas que han habilitado la función y tienen suscriptores se mostrarán a continuación. + lead: A continuación se mostrarán las cuentas que hayan activado la función y tengan suscriptores. status: Estado subscribers: Suscriptores title: Listas de correo @@ -506,33 +508,33 @@ es-MX: compliance_settings: additional_footer_text: action: Administrar - hint: Texto opcional que aparece únicamente en el pie de los correos electrónicos del boletín de noticias + hint: Texto opcional que aparece únicamente en el pie de página de los correos electrónicos del boletín informativo title: Texto de pie de página adicional - lead: Los boletines de correo electrónico pueden considerarse correos electrónicos de marketing, dependiendo de las jurisdicciones en las que operas. + lead: Los boletines informativos por correo electrónico pueden considerarse correos electrónicos de marketing, dependiendo de las jurisdicciones en las que operes. privacy_policy: action: Administrar - hint: Esta política está enlazada en el pie de cada correo electrónico + hint: Esta política aparece en el pie de página de cada correo electrónico title: Política de privacidad title: Ajustes de cumplimiento normativo danger_zone: disable_feature: action: Desactivar - hint: Desactivar función para todas las cuentas + hint: Desactivar la función para todas las cuentas title: Desactivar función erase_all_data: - action: Borrar datos - hint: Borra permanentemente todos los correos electrónicos de todas las listas de correo - title: Borrar todos los datos + action: Eliminar datos + hint: Elimina de forma permanente todos los correos electrónicos de todas las listas de correo + title: Eliminar todos los datos title: Zona peligrosa - disabled_msg: Las suscripciones de correo electrónico se han desactivado correctamente. + disabled_msg: Las suscripciones por correo electrónico se han desactivado correctamente. index: disabled: cannot_be_enabled: Tu proveedor técnico no ha habilitado esta función para tu servidor. - description: Esta función permite a las cuentas especificadas añadir un widget a sus perfiles, permitiendo a los visitantes sin una cuenta de Mastodon recibir sus publicaciones por correo electrónico. + description: Esta función permite a las cuentas especificadas añadir un widget a sus perfiles, lo que permite a los visitantes que no tienen una cuenta de Mastodon recibir sus publicaciones por correo electrónico. get_started: Primeros pasos - lead: Permitir a los visitantes recibir publicaciones por correo electrónico de cuentas dedicadas en este servidor. - title: Boletines de correo electrónico - purged_msg: Todos los datos de las suscripciones de correo electrónico están siendo borrados. + lead: Permitir que los visitantes reciban publicaciones por correo electrónico desde cuentas específicas de este servidor. + title: Boletines informativos por correo electrónico + purged_msg: Se están borrando todos los datos de las suscripciones por correo electrónico. roles: accounts: Cuentas edit_role: Editar rol @@ -545,13 +547,13 @@ es-MX: title: Roles setups: show: - enable_feature: Activar función + enable_feature: Habilitar función important_information: Información importante list: - 1_permission_explanation: Cuando esta función está activada, las cuentas con los permisos designados pueden añadir un formulario de recopilación de correo electrónico a sus perfiles. - 2_feature_explanation: Cuando los visitantes se registran en la página de perfil de una cuenta y confirman su suscripción, comenzarán a recibir actualizaciones por correo electrónico cuando la cuenta cree nuevas publicaciones públicas. - 3_privacy_policy_warning: Los administradores del servidor tendrán acceso a información de identificación personal (direcciones de correo electrónico). Por lo tanto, la política de privacidad y los Términos del Servicio del servidor deben actualizarse antes de usar esta función. - 4_cost_warning: Los correos electrónicos pueden incurrir en un cargo dependiendo de la configuración del alojamiento. Habla con tu proveedor de alojamiento antes de activarlo, ya que esta característica podría aumentar drásticamente la cantidad de correos electrónicos enviados desde tu servidor. + 1_permission_explanation: Cuando esta función está habilitada, las cuentas con los permisos correspondientes pueden añadir un formulario de recopilación de correos electrónicos a sus perfiles. + 2_feature_explanation: Cuando los visitantes se suscriban en la página de perfil de una cuenta y confirmen su suscripción, empezarán a recibir notificaciones por correo electrónico cada vez que la cuenta publique nuevas entradas públicas. + 3_privacy_policy_warning: Los administradores del servidor tendrán acceso a la información de identificación personal (direcciones de correo electrónico) recopilada. Por lo tanto, es necesario actualizar la política de privacidad y los Términos de servicio del servidor antes de utilizar esta función. + 4_cost_warning: El envío de correos electrónicos puede conllevar un cargo adicional dependiendo de la configuración del alojamiento web. Consúltalo con tu proveedor de alojamiento antes de habilitar esta función, ya que podría aumentar considerablemente el volumen de correos electrónicos enviados desde tu servidor. export_domain_allows: new: title: Importar dominios permitidos @@ -857,7 +859,7 @@ es-MX: manage_custom_emojis: Administrar Emojis Personalizados manage_custom_emojis_description: Permite a los usuarios gestionar emojis personalizados en el servidor manage_email_subscriptions: Gestionar suscripciones por correo electrónico - manage_email_subscriptions_description: Permite a los usuarios con este permiso habilitar la función del boletín de noticias por correo electrónico para su cuenta + manage_email_subscriptions_description: Permitir a los usuarios con este permiso activar la función de boletín informativo por correo electrónico en su cuenta manage_federation: Administrar Federación manage_federation_description: Permite a los usuarios bloquear o permitir la federación con otros dominios, y controlar la entregabilidad manage_invites: Administrar Invitaciones diff --git a/config/locales/es.yml b/config/locales/es.yml index 4c81cacafe..7b81ea0ed4 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -484,8 +484,10 @@ es: title: Bloquear nuevo dominio de correo no_email_domain_block_selected: No se han cambiado bloqueos de dominio de correo, ya que ninguno ha sido seleccionado not_permitted: No permitido + reset: Restablecer resolved_dns_records_hint_html: El nombre de dominio resuelve los siguientes dominios MX, los cuales son responsables en última instancia de aceptar el correo electrónico. Bloquear un dominio MX bloqueará los registros de cualquier dirección de correo electrónico que utilice el mismo dominio MX, incluso si el nombre de dominio visible es diferente. Ten cuidado de no bloquear los principales proveedores de correo electrónico. resolved_through_html: Resuelto a través de %{domain} + search: Buscar title: Dominios de correo bloqueados email_subscriptions: accounts: diff --git a/config/locales/et.yml b/config/locales/et.yml index bedf62ade4..4dcf00d2c0 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -539,6 +539,19 @@ et: empty: hint: Kellelgi pole õigust seda oskust kasutada. no_roles_added: Rolle pole lisatud + lead: Järgmiste rollidega kontod saavad selle oskuse oma profiilis sisse lülitada. + manage_roles: Halda rolle + role_name: Rolli nimi + title: Rollid + setups: + show: + enable_feature: Luba oskus + important_information: Oluline info + list: + 1_permission_explanation: Kui see funktsioon on sisse lülitatud, saavad vastavate õigustega kontod lisada oma profiilidesse e-posti kogumise vormi. + 2_feature_explanation: Kui külastajad registreeruvad konto profiililehel ja kinnitavad tellimuse, hakkavad nad saama e-kirju, kui konto avaldab uusi avalikke postitusi. + 3_privacy_policy_warning: Serveri administraatoritel on juurdepääs kogutud isikuandmetele (e-posti aadressidele). Seetõttu tuleb enne selle funktsiooni kasutamist ajakohastada serveri privaatsuspoliitika ja kasutustingimused. + 4_cost_warning: Sõltuvalt veebimajutuse seadistustest võib e-kirjade saatmine kaasa tuua lisatasu. Enne selle funktsiooni aktiveerimist konsulteeri oma veebimajutuse pakkujaga, kuna sinu serverist saadetavate e-kirjade arv võib oluliselt suureneda. export_domain_allows: new: title: Lubatud domeenide import @@ -844,6 +857,7 @@ et: manage_custom_emojis: Halda isetehtud emotikone manage_custom_emojis_description: Lubab kasutajatel hallata serveris isetehtud emotikone manage_email_subscriptions: Halda e-posti tellimusi + manage_email_subscriptions_description: Luba selle õigusega kasutajatel oma kontol e-posti uudiskirja funktsioon sisse lülitada manage_federation: Halda födereerumist manage_federation_description: Lubab kasutajail keelata või lubada föderatsioone teiste domeenidega ja hallata ühenduvust manage_invites: Halda kutseid diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 46096a3c48..ba2df40527 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -517,6 +517,71 @@ ga: resolved_dns_records_hint_html: Réitíonn an t-ainm fearainn chuig na fearainn MX seo a leanas, atá freagrach sa deireadh as glacadh le ríomhphost. Má dhéantar fearann ​​MX a bhlocáil, cuirfear bac ar chlárúcháin ó aon seoladh ríomhphoist a úsáideann an fearann ​​MX céanna, fiú má tá an t-ainm fearainn infheicthe difriúil. Bí cúramach gan bac a chur ar phríomhsholáthraithe ríomhphoist. resolved_through_html: Réitithe trí %{domain} title: Fearainn ríomhphoist bactha + email_subscriptions: + accounts: + account: Cuntas + active: Gníomhach + empty: + hint: Níl aon síntiúsóirí ag aon chuntas go fóill. + no_lists_yet: Gan aon liostaí fós + inactive: Neamhghníomhach + last_email: Ríomhphost deireanach + lead: Taispeánfar thíos cuntais a bhfuil an ghné cumasaithe acu agus a bhfuil síntiúsóirí acu. + status: Stádas + subscribers: Síntiúsóirí + title: Liostaí poist + additional_footer_texts: + show: + title: Téacs breise sa bhuntásc + compliance_settings: + additional_footer_text: + action: Bainistigh + hint: Téacs roghnach a thaispeántar i mbunús ríomhphoist nuachtlitir amháin + title: Téacs breise sa bhuntásc + lead: Féadfar nuachtlitreacha ríomhphoist a mheas mar ríomhphoist mhargaíochta, ag brath ar na dlínsí ina bhfeidhmíonn tú. + privacy_policy: + action: Bainistigh + hint: Tá nasc chuig an mbeartas seo i mbun gach ríomhphoist + title: Polasaí príobháideachta + title: Socruithe comhlíontachta + danger_zone: + disable_feature: + action: Díchumasaigh + hint: Múch an ghné do gach cuntas + title: Díchumasaigh gné + erase_all_data: + action: Scrios sonraí + hint: Scriosann sé gach ríomhphost i ngach liosta seoltaí go buan + title: Scrios na sonraí go léir + title: Crios contúirte + disabled_msg: Tá síntiúis ríomhphoist díchumasaithe go rathúil. + index: + disabled: + cannot_be_enabled: Níl an ghné seo cumasaithe ag do sholáthraí teicniúil do do fhreastalaí. + description: Leis an ngné seo, is féidir le cuntais shonraithe giuirléid a chur lena bpróifílí, rud a chuireann ar chumas cuairteoirí gan cuntas Mastodon a gcuid post a fháil trí ríomhphost. + get_started: Tosaigh + lead: Lig do chuairteoirí poist a fháil trí ríomhphost ó chuntais tiomnaithe ar an bhfreastalaí seo. + title: Nuachtlitreacha ríomhphoist + purged_msg: Tá gach sonraí síntiúis ríomhphoist á scriosadh. + roles: + accounts: Cuntais + edit_role: Cuir ról in eagar + empty: + hint: Níl cead ag aon duine an ghné seo a úsáid. + no_roles_added: Níor cuireadh aon róil leis + lead: Is féidir le cuntais leis na róil seo a leanas an ghné seo a chumasú ar a bpróifílí. + manage_roles: Bainistigh róil + role_name: Ainm an róil + title: Róil + setups: + show: + enable_feature: Cumasaigh gné + important_information: Faisnéis thábhachtach + list: + 1_permission_explanation: Nuair a bhíonn an ghné seo cumasaithe, is féidir le cuntais a bhfuil na ceadanna ainmnithe acu foirm bhailiúcháin ríomhphoist a chur lena bpróifílí. + 2_feature_explanation: Nuair a chláraíonn cuairteoirí ar leathanach próifíle cuntais agus a dheimhníonn siad a síntiús, tosóidh siad ag fáil nuashonruithe ríomhphoist nuair a chruthaíonn an cuntas poist phoiblí nua. + 3_privacy_policy_warning: Beidh rochtain ag riarthóirí freastalaí ar PII (seoltaí ríomhphoist) a bhailítear. Dá bhrí sin, ní mór an polasaí príobháideachta agus na Téarmaí Seirbhíse don fhreastalaí a nuashonrú sula n-úsáidtear an ghné seo. + 4_cost_warning: D’fhéadfadh táille a bheith i gceist le ríomhphoist ag brath ar shocrú an óstála. Pléigh le do sholáthraí óstála sula gcumasaíonn tú é, mar d’fhéadfadh an ghné seo líon na ríomhphoist a sheoltar ó do fhreastalaí a mhéadú go mór. export_domain_allows: new: title: Ceadaíonn fearann ​​​​iomportála @@ -840,6 +905,7 @@ ga: manage_custom_emojis: Bainistigh Emojis Saincheaptha manage_custom_emojis_description: Ligeann sé d'úsáideoirí emojis saincheaptha a bhainistiú ar an bhfreastalaí manage_email_subscriptions: Bainistigh Síntiúis Ríomhphoist + manage_email_subscriptions_description: Lig d’úsáideoirí a bhfuil an cead seo acu gné an nuachtlitir ríomhphoist a chumasú dá gcuntas manage_federation: Cónaidhm a bhainistiú manage_federation_description: Ligeann sé d’úsáideoirí cónaidhm a bhlocáil nó a cheadú le fearainn eile, agus inseachadacht a rialú manage_invites: Bainistigh Cuirí diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 41e85c8e65..ff4c36c0e2 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -484,8 +484,10 @@ gl: title: Bloquear novo dominio de correo no_email_domain_block_selected: Non se cambiou ningún bloqueo de dominio porque non había ningún seleccionado not_permitted: Non permitido + reset: Restabelecer resolved_dns_records_hint_html: O nome de dominio corresponde cos seguintes dominios MX, que son os responsables últimos de aceptar o correo. Ao bloquear un dominio MX bloquerás a creación de contas para todo enderezo de correo que use o mesmo dominio MX, incluso se o nome de dominio visible é diferente. Ten coidado xa que podes bloquear os principais provedores de correo. resolved_through_html: Resolto a través de %{domain} + search: Buscar title: Dominios de correo bloqueados email_subscriptions: accounts: @@ -551,6 +553,7 @@ gl: 1_permission_explanation: Cando se activa esta ferramenta as contas cos permisos concedidos poden engadir un formulario no seu perfil para recoller correos. 2_feature_explanation: Cando unha persoa visita se apunta na páxina do perfil e confirma a súa subscrición, comezará a recibir actualizacións por correo cando a conta publique novas publicacións públicas. 3_privacy_policy_warning: A administración do servidor vai ter acceso aos PII (enderezos de correo) recollidos. Así, a directiva de privacidade e os termos do servizo do servidor deben actualizarse antes de activar esta ferramenta. + 4_cost_warning: Os correos poderían supoñer costes adicionais do servidor. Consulta co teu provedor de hospedaxe antes de activalos, xa que esta ferramenta podería facer aumentar drásticamente o número de correos que envía o teu servidor. export_domain_allows: new: title: Importar dominios permitidos @@ -856,6 +859,7 @@ gl: manage_custom_emojis: Xestionar Emojis personalizados manage_custom_emojis_description: Permite xestionar os emojis personalizados do servidor manage_email_subscriptions: Xestionar subscripcións por correo + manage_email_subscriptions_description: Permitir ás usuarias con este permiso activar para a súa conta a ferramenta do boletín por correo manage_federation: Xestionar a federación manage_federation_description: Permite bloquear ou permitir a federación con outros dominios, e controlar as entregas manage_invites: Xestionar Convites diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 62250a9bfb..d2a1303522 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -496,6 +496,7 @@ hu: no_lists_yet: Még nincsenek listák inactive: Inaktív last_email: Legutóbbi e-mail + lead: A fiókok, melyek bekapcsolták a funkciót, és vannak feliratkozóik, itt fognak megjelenni alább. status: Állapot subscribers: Feliratkozók title: Levelezőlisták @@ -527,6 +528,7 @@ hu: index: disabled: cannot_be_enabled: A műszaki szolgáltató nem kapcsolta be ezt a funkciót a kiszolgálód számára. + description: A funkció lehetővé teszi, hogy a megadott fiókok hozzáadjanak egy kisalkalmazást a profiljukhoz, mellyel a Mastodon-fiók nélküli látogatók e-mailben megkaphatják a bejegyzéseiket. get_started: Első lépések title: E-mailes hírlevelek purged_msg: Az összes e-mail-feliratkozási adat törlése folyamatban van. diff --git a/config/locales/is.yml b/config/locales/is.yml index 97c09f7988..cb46774390 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -484,8 +484,10 @@ is: title: Útiloka nýtt tölvupóstlén no_email_domain_block_selected: Engum útilokunum tölvupóstléna var breytt þar sem ekkert var valið not_permitted: Ekki leyft + reset: Endurstilla resolved_dns_records_hint_html: Heiti lénsins vísar til eftirfarandi MX-léna, sem bera endanlega ábyrgð á að tölvupóstur skili sér. Útilokun á MX-léni mun koma í veg fyrir nýskráningar með hverju því tölvupóstfangi sem notar sama MX-lén, jafnvel þótt sýnilega lénsheitið sé frábrugðið. Farðu varlega svo þú útilokir ekki algengar tölvupóstþjónustur. resolved_through_html: Leyst í gegnum %{domain} + search: Leita title: Útilokuð tölvupóstlén email_subscriptions: accounts: diff --git a/config/locales/it.yml b/config/locales/it.yml index 72260e1a40..4112e5e9db 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -486,6 +486,7 @@ it: not_permitted: Non consentito resolved_dns_records_hint_html: Il nome di dominio si risolve nei seguenti domini MX, che sono in ultima analisi responsabili dell'accettazione delle e-mail. Il blocco di un dominio MX bloccherà le registrazioni da qualsiasi indirizzo e-mail che utilizzi lo stesso dominio MX, anche se il nome di dominio visibile è diverso. Fai attenzione a non bloccare i principali provider di posta elettronica. resolved_through_html: Risolto attraverso %{domain} + search: Cerca title: Domini e-mail bloccati email_subscriptions: accounts: @@ -521,6 +522,7 @@ it: title: Disabilita la funzionalità erase_all_data: action: Cancella i dati + hint: Elimina in modo permanente tutti gli indirizzi email in tutte le mailing list title: Cancella tutti i dati title: Zona pericolosa disabled_msg: Le iscrizioni via email sono state disabilitate con successo. diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 662b3be45f..7b5765436e 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -1005,6 +1005,7 @@ kab: development: Taneflit edit_profile: Ẓreg amaɣnu export: Sifeḍ + featured_tags: Ihacṭagen ufrinen import: Kter import_and_export: Taktert d usifeḍ migrate: Tunigin n umiḍan diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index 60d98c40b6..fb562719f1 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -92,6 +92,7 @@ de: closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Davon sind auch Beiträge betroffen, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Diese Option richtet sich ausschließlich an Server mit speziellen Zwecken und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist. custom_css: Du kannst eigene Stylesheets für das Webinterface von Mastodon verwenden. + email_footer_text: Der Text erscheint ausschließlich in der Fußzeile von E-Mails. favicon: WebP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Favicon. landing_page: Legt fest, welchen Bereich (nicht angemeldete) Besucher*innen sehen, wenn sie deinen Server besuchen. Für „Trends“ müssen die Trends in den Entdecken-Einstellungen aktiviert sein. Für „Lokaler Feed“ muss „Zugriff auf Live-Feeds, die lokale Beiträge beinhalten“ in den Entdecken-Einstellungen auf „Alle“ gesetzt werden. mascot: Überschreibt die Abbildung im erweiterten Webinterface. @@ -294,6 +295,7 @@ de: closed_registrations_message: Nachricht, falls Registrierungen deaktiviert sind content_cache_retention_period: Aufbewahrungsfrist für externe Inhalte custom_css: Eigenes CSS + email_footer_text: Fußzeile favicon: Favicon landing_page: Landingpage für Gäste local_live_feed_access: Zugriff auf Live-Feeds, die lokale Beiträge beinhalten @@ -322,6 +324,9 @@ de: trendable_by_default: Trends ohne vorherige Überprüfung erlauben trends: Trends aktivieren wrapstodon: Wrapstodon aktivieren + form_email_subscriptions_confirmation: + agreement_email_volume: Ich verstehe, dass das Aktivieren dieser Funktion die Anzahl versendeter E-Mails drastisch erhöhen kann. Ich übernehme die Verantwortung für mögliche Zusatzkosten. + agreement_privacy_and_terms: Datenschutzerklärung und Nutzungsbedingungen wurden im Vorfeld aktualisiert. interactions: must_be_follower: Benachrichtigungen von Profilen, die mir nicht folgen, ausblenden must_be_following: Benachrichtigungen von Profilen, denen ich nicht folge, ausblenden diff --git a/config/locales/simple_form.el.yml b/config/locales/simple_form.el.yml index 26f62f2737..5d4cb3f332 100644 --- a/config/locales/simple_form.el.yml +++ b/config/locales/simple_form.el.yml @@ -156,7 +156,7 @@ el: jurisdiction: Ανέφερε τη χώρα όπου ζει αυτός που πληρώνει τους λογαριασμούς. Εάν πρόκειται για εταιρεία ή άλλη οντότητα, ανέφερε τη χώρα όπου υφίσταται, και την πόλη, περιοχή, έδαφος ή πολιτεία ανάλογα με την περίπτωση. min_age: Δεν πρέπει να είναι κάτω από την ελάχιστη ηλικία που απαιτείται από τους νόμους της δικαιοδοσίας σας. user: - chosen_languages: Όταν ενεργοποιηθεί, μόνο αναρτήσεις σε επιλεγμένες γλώσσες θα εμφανίζονται στις δημόσιες ροές. Αυτή η ρύθμιση δεν επηρεάζει την Αρχική ροή και τις λίστες σας. + chosen_languages: Όταν επιλέξετε, στις δημόσιες ροές θα εμφανίζονται αναρτήσεις μόνο από τις επιλεγμένες γλώσσες. Αυτή η ρύθμιση δεν επηρεάζει την Αρχική ροή και τις λίστες σας. date_of_birth: one: Πρέπει να βεβαιωθούμε ότι είσαι τουλάχιστον %{count} για να χρησιμοποιήσεις το %{domain}. Δε θα το αποθηκεύσουμε. other: Πρέπει να βεβαιωθούμε ότι είσαι τουλάχιστον %{count} για να χρησιμοποιήσεις το %{domain}. Δε θα το αποθηκεύσουμε. diff --git a/config/locales/simple_form.es-MX.yml b/config/locales/simple_form.es-MX.yml index 9eb9d85446..631dbb4f01 100644 --- a/config/locales/simple_form.es-MX.yml +++ b/config/locales/simple_form.es-MX.yml @@ -92,7 +92,7 @@ es-MX: closed_registrations_message: Mostrado cuando los registros están cerrados content_cache_retention_period: Todas las publicaciones de otros servidores (incluyendo impuestos y respuestas) serán borrados después del número de días especificado, sin tener en cuenta cualquier interacción del usuario local con esas publicaciones. Esto incluye los mensajes que un usuario local haya marcado como favoritos. Las menciones privadas entre usuarios de diferentes instancias también se perderán y será imposible restaurarlas. El uso de esta configuración está pensado para instancias de propósito especial y rompe muchas expectativas de los usuarios cuando se implementa para uso general. custom_css: Puedes aplicar estilos personalizados a la versión web de Mastodon. - email_footer_text: Texto opcional que aparece únicamente en el pie de los correos electrónicos del boletín de correo electrónico. + email_footer_text: Texto opcional que aparece únicamente en el pie de página de los correos electrónicos del boletín informativo. favicon: WEBP, PNG, GIF o JPG. Reemplaza el icono predeterminado de Mastodon con un icono personalizado. landing_page: Selecciona qué página ven los nuevos visitantes cuando llegan por primera vez a tu servidor. Si seleccionas "Tendencias", entonces las tendencias deben estar habilitadas en la Configuración de Descubrimiento. Si selecciona "Cronología local", entonces "Acceso a las cronologías que destacan publicaciones locales" debe configurarse a "Todos" en la Configuración de Descubrimiento. mascot: Reemplaza la ilustración en la interfaz web avanzada. @@ -325,8 +325,8 @@ es-MX: trends: Habilitar tendencias wrapstodon: Habilitar Wrapstodon form_email_subscriptions_confirmation: - agreement_email_volume: Entiendo que activar esta característica puede aumentar significativamente el volumen de correos electrónicos enviados desde el servidor, y que soy el único responsable de cualquier coste incurrido. - agreement_privacy_and_terms: He actualizado la Política de Privacidad y los Términos del Servicio. + agreement_email_volume: Entiendo que al habilitar esta función puede aumentar considerablemente el volumen de correos electrónicos enviados desde el servidor y que soy el único responsable de los gastos en que se incurra. + agreement_privacy_and_terms: He actualizado la Política de privacidad y los Términos de servicio. interactions: must_be_follower: Bloquear notificaciones de personas que no te siguen must_be_following: Bloquear notificaciones de personas que no sigues diff --git a/config/locales/simple_form.et.yml b/config/locales/simple_form.et.yml index 7ea286ab4f..9866920cc1 100644 --- a/config/locales/simple_form.et.yml +++ b/config/locales/simple_form.et.yml @@ -92,6 +92,7 @@ et: closed_registrations_message: Kuvatakse, kui liitumised pole võimalikud content_cache_retention_period: Kõik teiste serverite postitused (sealhulgas jagamised ja vastused) kustutatakse pärast määratud arvu päevade möödumist, sõltumata, kuidas kohalik kasutaja on nende postitustega interakteerunud. Hõlmatud on ka postitused, mille kohalik kasutaja on märkinud järjehoidjaks või lemmikuks. Ka eri instantside kasutajate vahelised privaatsed mainimised kaovad ja neid on võimatu taastada. See seadistus on mõeldud eriotstarbeliste instantside jaoks ja rikub paljude kasutajate ootusi, kui seda rakendatakse üldotstarbelise kasutuse puhul. custom_css: Mastodoni veebiliideses on võimalik kasutada kohandatud stiile. + email_footer_text: Valikuline tekst, mida kuvatakse ainult uudis-e-kirjade jaluses. favicon: WEBP, PNG, GIF või JPG. Asendab Mastodoni vaike- favicon ikooni kohandatud ikooniga. landing_page: Sellega valid lehe, mida uued külastajad sinu serverisse tulles näevad. Kui sa valid „Trendid“, siis peavad nad olema lubatud. Kui sa valid „Kohalike postituste voog“, siis seadistuse „Ligipääs kohalike postituste voole“ väärtus peab olema „Kõik“. mascot: Asendab kohandatud veebiliidese illustratsiooni. @@ -294,6 +295,7 @@ et: closed_registrations_message: Kohandatud teade, kui liitumine pole võimalik content_cache_retention_period: Kaugsisu säilitamise aeg custom_css: Kohandatud CSS + email_footer_text: Täiendav jaluse tekst favicon: Favicon landing_page: Avaleht uute külastajate jaoks local_live_feed_access: Ligipääs kohalike postituste voole @@ -322,6 +324,9 @@ et: trendable_by_default: Luba trendid eelneva ülevaatuseta trends: Luba trendid wrapstodon: Luba Wrapstodon + form_email_subscriptions_confirmation: + agreement_email_volume: Ma mõistan, et selle funktsiooni aktiveerimine võib märkimisväärselt suurendada serverist saadetavate e-kirjade mahtu ning et vastutan tekkivate kulude eest täielikult ise. + agreement_privacy_and_terms: Olen uuendanud privaatsuspoliitikat ja kasutustingimusi. interactions: must_be_follower: Keela teavitused mittejälgijatelt must_be_following: Keela teavitused kasutajatelt, keda sa ei jälgi diff --git a/config/locales/simple_form.ga.yml b/config/locales/simple_form.ga.yml index 8ce7bf11ac..a7c94a91a7 100644 --- a/config/locales/simple_form.ga.yml +++ b/config/locales/simple_form.ga.yml @@ -92,6 +92,7 @@ ga: closed_registrations_message: Ar taispeáint nuair a dhúntar clárúcháin content_cache_retention_period: Scriosfar gach postáil ó fhreastalaithe eile (lena n-áirítear treisithe agus freagraí) tar éis an líon sonraithe laethanta, gan aird ar aon idirghníomhaíocht úsáideora áitiúil leis na postálacha sin. Áirítear leis seo postálacha ina bhfuil úsáideoir áitiúil tar éis é a mharcáil mar leabharmharcanna nó mar cheanáin. Caillfear tagairtí príobháideacha idir úsáideoirí ó chásanna éagsúla freisin agus ní féidir iad a athchóiriú. Tá úsáid an tsocraithe seo beartaithe le haghaidh cásanna sainchuspóra agus sáraítear go leor ionchais úsáideoirí nuair a chuirtear i bhfeidhm é le haghaidh úsáid ghinearálta. custom_css: Is féidir leat stíleanna saincheaptha a chur i bhfeidhm ar an leagan gréasáin de Mastodon. + email_footer_text: Téacs roghnach a thaispeántar i mbunús ríomhphoist nuachtlitir amháin. favicon: WEBP, PNG, GIF nó JPG. Sáraíonn sé an favicon Mastodon réamhshocraithe le deilbhín saincheaptha. landing_page: Roghnaíonn sé seo an leathanach a fheiceann cuairteoirí nua nuair a shroicheann siad do fhreastalaí den chéad uair. Má roghnaíonn tú "Treochtaí", ní mór treochtaí a chumasú sna Socruithe Fionnachtana. Má roghnaíonn tú "Fotha Áitiúil", ní mór "Rochtain ar fhothaí beo ina bhfuil poist áitiúla" a shocrú go "Gach Duine" sna Socruithe Fionnachtana. mascot: Sáraíonn sé an léaráid san ardchomhéadan gréasáin. @@ -297,6 +298,7 @@ ga: closed_registrations_message: Teachtaireacht saincheaptha nuair nach bhfuil sínithe suas ar fáil content_cache_retention_period: Tréimhse choinneála inneachair cianda custom_css: CSS saincheaptha + email_footer_text: Téacs breise sa bhuntásc favicon: Favicon landing_page: Leathanach tuirlingthe do chuairteoirí nua local_live_feed_access: Rochtain ar bheatha bheo ina bhfuil poist áitiúla @@ -325,6 +327,9 @@ ga: trendable_by_default: Ceadaigh treochtaí gan athbhreithniú roimh ré trends: Cumasaigh treochtaí wrapstodon: Cumasaigh Wrapstodon + form_email_subscriptions_confirmation: + agreement_email_volume: Tuigim go bhféadfadh an ghné seo a chumasú líon na ríomhphoist a sheoltar ón bhfreastalaí a mhéadú go suntasach agus gurb mise amháin atá freagrach as aon chostais a thabhaítear. + agreement_privacy_and_terms: Tá an Polasaí Príobháideachais agus na Téarmaí Seirbhíse nuashonraithe agam. interactions: must_be_follower: Cuir bac ar fhógraí ó dhaoine nach leantóirí iad must_be_following: Cuir bac ar fhógraí ó dhaoine nach leanann tú diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index 3283190387..85cbacc70a 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -92,6 +92,7 @@ gl: closed_registrations_message: Móstrase cando non se admiten novas usuarias content_cache_retention_period: Todas as publicacións procedentes de outros servidores (incluído promocións e respostas) van ser eliminadas despois do número de días indicado, sen importar as interaccións das usuarias locais con esas publicacións. Esto inclúe publicacións que a usuaria local marcou como favoritas ou incluíu nos marcadores. As mencións privadas entre usuarias de diferentes instancias tamén se eliminarán e non se poderán restablecer. O uso desta ferramenta esta orientado a situacións especiais e estraga moitas das expectativas das usuarias ao implementala cun propósito de uso xeral. custom_css: Podes aplicar deseños personalizados na versión web de Mastodon. + email_footer_text: Texto optativo que só aparece no rodapé dos correos co boletín. favicon: WEBP, PNG, GIF ou JPG. Sobrescribe a icona de favoritos de Mastodon por defecto cunha icona personalizada. landing_page: Elixe a páxina que verán as persoas que se acheguen por primeira vez ao teu servidor. Se elixes «Tendencias» entón debes activar as tendencias nos Axustes de Descubrimento. Se elixes «Cronoloxía local», hai que configurar nos Axustes de Descubrimento a opción «Acceso das cronoloxías en directo ás publicacións locais» como «Calquera». mascot: Sobrescribe a ilustración na interface web avanzada. @@ -294,6 +295,7 @@ gl: closed_registrations_message: Mensaxe personalizada para cando o rexistro está pechado content_cache_retention_period: Período de retención de contido remoto custom_css: CSS personalizado + email_footer_text: Texto adicional no rodapé favicon: Favicon landing_page: Páxina que se mostra ás visitas local_live_feed_access: Acceso a cronoloxías ao vivo que mostran publicacións locais @@ -322,6 +324,9 @@ gl: trendable_by_default: Permitir tendencias sen aprobación previa trends: Activar tendencias wrapstodon: Activar Wrapstodon + form_email_subscriptions_confirmation: + agreement_email_volume: Comprendo que activar esta ferramenta pode aumentar de xeito significativo o volume de correos electrónicos que envía o servidor e que é responsabilidade miña calquera custo que xenere. + agreement_privacy_and_terms: Actualicei a Directiva de Privacidade e os Termos do Servizo. interactions: must_be_follower: Bloquea as notificacións de persoas que non te seguen must_be_following: Bloquea as notificacións de persoas que non segues diff --git a/config/locales/simple_form.sq.yml b/config/locales/simple_form.sq.yml index 24e6f4ffb1..b513e66dee 100644 --- a/config/locales/simple_form.sq.yml +++ b/config/locales/simple_form.sq.yml @@ -91,6 +91,7 @@ sq: closed_registrations_message: Shfaqur kur mbyllen dritare regjistrimesh content_cache_retention_period: Krejt postimet prej shërbyesve të tjerë (përfshi përforcime dhe përgjigje) do të fshihen pas numrit të caktuar të ditëve, pa marrë parasysh çfarëdo ndërveprimi përdoruesi me këto postime. Kjo përfshin postime kur një përdorues vendor u ka vënë shenjë si faqerojtës, ose të parapëlqyer. Do të humbin gjithashtu dhe përmendje private mes përdoruesish nga instanca të ndryshme dhe s’do të jetë e mundshme të rikthehen. Përdorimi i këtij rregullimi është menduar për instanca me qëllim të caktuar dhe ndërhyn në çka presin mjaft përdorues, kur sendërtohet për përdorim të përgjithshëm. custom_css: Stile vetjakë mund të aplikoni në versionin web të Mastodon-it. + email_footer_text: Tekst opsional që shfaqet vetëm te fundfaqja e email-eve të buletinit. favicon: WEBP, PNG, GIF, ose JPG. Anashkalon favikonën parazgjedhje Mastodon me një ikonë vetjake. landing_page: Përzgjedh cilën faqe shohin vizitorët e rinj, kur vijnë për herë të parë në shërbyesin tuaj. Nëse përzgjidhni “Në modë”, atëherë “në modë” duhet aktivizuar te Rregullime për Zbulime. Nëse përzgjidhni “Prurje vendore”, atëherë “Hyrje te prurje vendore që përmbajnë postime vendore” duhet vënë si “Gjithkush”, te Rregullime për Zbulime. mascot: Anashkalon ilustrimin te ndërfaqja web e thelluar. @@ -322,6 +323,9 @@ sq: trendable_by_default: Lejoni gjëra në modë pa shqyrtim paraprak trends: Aktivizo gjëra në modë wrapstodon: Aktivizo Përmbledhjedon-in + form_email_subscriptions_confirmation: + agreement_email_volume: E kuptoj se aktivizimi i kësaj veçorie mund të rrisë në mënyrë domethënëse vëllimin e email-eve nga shërbyesi dhe se jam i vetmi që mban përgjegjësi për çfarëdo kostos që rrjedhin prej kësaj. + agreement_privacy_and_terms: Kam përditësuar Rregulla Privatësie dhe Kushte Shërbimi. interactions: must_be_follower: Blloko njoftime nga jo-ndjekës must_be_following: Blloko njoftime nga persona që s’i ndiqni diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 99e238af90..d065158e6d 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -484,8 +484,10 @@ sq: title: Blloko përkatësi të re email no_email_domain_block_selected: S’u ndryshuan bllokime përkatësish email, ngaqë s’qe përzgjedhur ndonjë not_permitted: Jo i lejuar + reset: Riktheje te parazgjedhjet resolved_dns_records_hint_html: Emri i përkatësisë u përket përkatësive vijuese MX, që janë përgjegjëset përfundimtare për pranim email-esh. Bllokimi i një përkatësie MX do të bllokojë regjistrime nga çfarëdo adrese email që përdor të njëjtën përkatësi MX, edhe nëse emri i dukshëm i përkatësisë është i ndryshëm. Hapni sytë të mos bllokoni shërbime të njohur email-esh. resolved_through_html: Zgjidhur përmes %{domain} + search: Kërko title: Përkatësi email të bllokuara email_subscriptions: accounts: @@ -508,21 +510,38 @@ sq: action: Administrojini hint: Tekst opsional që shfaqet vetëm te fundfaqja e email-eve të buletinit title: Tekst fundfaqeje shtesë + lead: Në varësi të juridiksionit në të cilin veproni, buletinet me email mund të konsiderohen email-e marketingu. privacy_policy: action: Administrojini + hint: Për këto rregulla ka një lidhje te fundfaqja e çdo email-i title: Rregulla privatësie title: Rregullime përputhjeje me rregullore dhe ligje danger_zone: disable_feature: action: Çaktivizoje + hint: Çaktivizoje këtë veçori për krejt llogaritë title: Çaktivizoje veçorinë erase_all_data: action: Fshiji të dhënat + hint: Fshin në mënyrë të pakthyeshme krejt email-et në krejt listat e postimeve title: Fshiji krejt të dhënat title: Zonë rreziku + disabled_msg: Pajtimet email janë çaktivizuar me sukses. index: + disabled: + cannot_be_enabled: Shërbimi juaj teknik s’e ka aktivizuar këtë veçori për shërbyesin tuaj. + description: Kjo veçori lejon llogari të caktuara të shtojnë një “widget” te profilet e tyre, duke u bërë të mundur vizitorëve pa një llogari Mastodon të marrin postimet përmes email-i. + get_started: Fillojani + lead: Lejojuni vizitorëve të marrin postime përmes email-i, që nga llogari enkas për këtë në këtë shërbyes. title: Dërgoni buletine me email + purged_msg: Po fshihen krejt të dhënat e lidhura me pajtime me email. roles: + accounts: Llogari + edit_role: Përpunoni rolin + empty: + hint: Askush s’ka leje të përdorë këtë veçori. + no_roles_added: S’u shtuan role + lead: Llogaritë me rolet vijuese mund ta aktivizojnë këtë veçori në profilet e tyre. manage_roles: Administroni role role_name: Emër roli title: Role @@ -530,6 +549,8 @@ sq: show: enable_feature: Aktivizoje veçorinë important_information: Informacion i rëndësishëm + list: + 1_permission_explanation: Kur aktivizohet kjo veçroi, llogaritë me lejet e caktuara mund të shtojnë te profilet e tyre një formular koleksionesh email. export_domain_allows: new: title: Importoni lejime përkatësish @@ -830,6 +851,7 @@ sq: manage_custom_emojis: Të Administrojë Emoxhi Vetjake manage_custom_emojis_description: U lejon përdoruesve të administrojnë te shërbyesi emoxhi vetjake manage_email_subscriptions: Administroni Pajtime Me Email + manage_email_subscriptions_description: Lejoji përdoruesit me këtë leje të aktivizojnë veçorinë për buletine me email për llogaritë e tyre manage_federation: Të Administrojë Federim manage_federation_description: U lejon përdoruesve të bllokojnë ose lejojnë federim me përkatësi të tjera dhe të kontrollojnë shpërndarjen manage_invites: Të Administrojë Ftesa diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 3d00d95195..8771a4921b 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -484,8 +484,10 @@ sv: title: Blockera ny e-postdomän no_email_domain_block_selected: Inga blockeringar av e-postdomäner ändrades eftersom inga valdes not_permitted: Ej tillåtet + reset: Återställ resolved_dns_records_hint_html: Domännamnet ger uppslag till följande MX-domäner, vilka är ytterst ansvariga för att e-post tas emot. Att blockera en MX-domän blockerar även registreringar från alla e-postadresser som använder samma MX-domän, även om det synliga domännamnet är annorlunda. Var noga med att inte blockera stora e-postleverantörer. resolved_through_html: Uppslagen genom %{domain} + search: Sök title: Blockerade e-postdomäner export_domain_allows: new: diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 7f5e2cb159..8f7ee329f8 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -474,8 +474,10 @@ vi: title: Chặn tên miền email mới no_email_domain_block_selected: Không có thay đổi vì không có mục nào được chọn not_permitted: Không cho phép + reset: Đặt lại resolved_dns_records_hint_html: Tên miền phân giải thành các tên miền MX sau, các tên miền này chịu trách nhiệm cuối cùng trong việc chấp nhận email. Chặn tên miền MX sẽ chặn đăng ký từ bất kỳ địa chỉ email nào sử dụng cùng một tên miền MX, ngay cả khi tên miền hiển thị là khác. Cẩn thận đừng chặn những dịch vụ email lớn. resolved_through_html: Đã xử lý thông qua %{domain} + search: Tìm kiếm title: Tên miền email đã chặn email_subscriptions: accounts: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 7c02995de8..b7dd7b9be2 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -474,8 +474,10 @@ zh-CN: title: 封禁新的邮箱域名 no_email_domain_block_selected: 没有任何项目被选中,因此未更改邮箱域名屏蔽列表 not_permitted: 未允许 + reset: 重置 resolved_dns_records_hint_html: 该域名解析的 MX 记录所指向的域名如下,这些域名被用于接收电子邮件。 即使电子邮件地址域名与 MX 域名不同,屏蔽一个 MX 域名意味着阻止任何使用相同 MX 域名的邮箱地址注册本站账号。 请谨慎操作,不要误屏蔽主要的邮箱提供商。 resolved_through_html: 通过 %{domain} 解析 + search: 搜索 title: 被封禁的邮箱域名 email_subscriptions: accounts: diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index d2ff545b17..56636fd80f 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -474,8 +474,10 @@ zh-TW: title: 新增電子郵件網域封鎖 no_email_domain_block_selected: 因未選取任何電子郵件網域,所以什麼事都沒發生 not_permitted: 無權限 + reset: 重設 resolved_dns_records_hint_html: 網域名稱解析為以下 MX 網域,這些網域最終負責接收電子郵件。封鎖 MX 網域將會封鎖任何來自使用相同 MX 網域的電子郵件註冊,即便可見的域名是不同的也一樣。請注意,不要封鎖主要的電子郵件服務提供商。 resolved_through_html: 透過 %{domain} 解析 + search: 搜尋 title: 已封鎖電子郵件網域 email_subscriptions: accounts: diff --git a/config/routes.rb b/config/routes.rb index 772ca28f1c..8538635124 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -189,6 +189,7 @@ Rails.application.routes.draw do namespace :redirect do resources :accounts, only: :show resources :statuses, only: :show + resources :collections, only: :show end namespace :email_subscriptions do diff --git a/package.json b/package.json index 7fdd3fa6a9..64adf78346 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@react-spring/web": "^9.7.5", "@reduxjs/toolkit": "^2.0.1", "@rolldown/plugin-babel": "^0.2.2", + "@unhead/react": "^3.1.0", "@use-gesture/react": "^10.3.1", "@vitejs/plugin-legacy": "^8.0.0", "@vitejs/plugin-react": "^6.0.0", @@ -95,7 +96,6 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-easy-crop": "^5.5.6", - "react-helmet": "^6.1.0", "react-immutable-proptypes": "^2.2.0", "react-immutable-pure-component": "^2.2.2", "react-intl": "^10.0.0", @@ -153,7 +153,6 @@ "@types/punycode": "^2.1.0", "@types/react": "^18.2.7", "@types/react-dom": "^18.2.4", - "@types/react-helmet": "^6.1.6", "@types/react-immutable-proptypes": "^2.1.0", "@types/react-router": "^5.1.20", "@types/react-router-dom": "^5.3.3", diff --git a/spec/lib/permalink_redirector_spec.rb b/spec/lib/permalink_redirector_spec.rb index 81fa05449e..2f3a10b9dc 100644 --- a/spec/lib/permalink_redirector_spec.rb +++ b/spec/lib/permalink_redirector_spec.rb @@ -45,6 +45,12 @@ RSpec.describe PermalinkRedirector do redirector = described_class.new('@alice/123?foo=bar') expect(redirector.redirect_path).to eq 'https://example.com/status-123' end + + it 'returns path for collections link' do + collection = Fabricate(:remote_collection, account: remote_account) + redirector = described_class.new("collections/#{collection.id}") + expect(redirector.redirect_path).to eq(ActivityPub::TagManager.instance.url_for(collection) || ActivityPub::TagManager.instance.uri_for(collection)) + end end context 'when account is suspended' do @@ -81,6 +87,12 @@ RSpec.describe PermalinkRedirector do redirector = described_class.new('@alice/123?foo=bar') expect(redirector.redirect_path).to be_nil end + + it 'returns nil for collections link' do + collection = Fabricate(:remote_collection, account: remote_account) + redirector = described_class.new("collections/#{collection.id}") + expect(redirector.redirect_path).to be_nil + end end end end diff --git a/spec/models/collection_item_spec.rb b/spec/models/collection_item_spec.rb index 89ef2bc534..0c927e368f 100644 --- a/spec/models/collection_item_spec.rb +++ b/spec/models/collection_item_spec.rb @@ -41,6 +41,19 @@ RSpec.describe CollectionItem do subject { Fabricate.build(:unverified_remote_collection_item) } it { is_expected.to validate_presence_of(:object_uri) } + + context 'when another item without account exists' do + subject { Fabricate.build(:unverified_remote_collection_item, collection:) } + + let(:collection) { Fabricate(:remote_collection) } + + before do + Fabricate(:unverified_remote_collection_item, collection:) + collection.reload + end + + it { is_expected.to be_valid } + end end end diff --git a/streaming/Dockerfile b/streaming/Dockerfile index 74c0c42aae..e8697213be 100644 --- a/streaming/Dockerfile +++ b/streaming/Dockerfile @@ -95,7 +95,7 @@ RUN \ --mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \ # Configure Corepack rm /usr/local/bin/yarn*; \ - corepack enable; \ + npm i -g corepack; \ corepack prepare --activate; RUN \ diff --git a/yarn.lock b/yarn.lock index 347061b3ae..56ee2341f1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1943,6 +1943,16 @@ __metadata: languageName: node linkType: hard +"@emnapi/core@npm:1.9.2": + version: 1.9.2 + resolution: "@emnapi/core@npm:1.9.2" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.1" + tslib: "npm:^2.4.0" + checksum: 10c0/5500393f953951bad0768fafaa9191f2d938956b20c6d6a79e5ab696a613a25ce6ad23422bc18e86e6ce8deb147619d8d0d7d413a69f84adc01a6633cc353cd9 + languageName: node + linkType: hard + "@emnapi/runtime@npm:1.10.0, @emnapi/runtime@npm:^1.4.3": version: 1.10.0 resolution: "@emnapi/runtime@npm:1.10.0" @@ -1952,6 +1962,15 @@ __metadata: languageName: node linkType: hard +"@emnapi/runtime@npm:1.9.2": + version: 1.9.2 + resolution: "@emnapi/runtime@npm:1.9.2" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/61c3a59e0c36784558b8d58eb02bd04815aa5fb0dbfbaf84d1b3050a78aa0cc63ea129ae806bd1e48062bfeb7fc36eb0e5431740d62f64ea51bdf426404b8caa + languageName: node + linkType: hard + "@emnapi/wasi-threads@npm:1.2.1": version: 1.2.1 resolution: "@emnapi/wasi-threads@npm:1.2.1" @@ -2885,7 +2904,6 @@ __metadata: "@types/punycode": "npm:^2.1.0" "@types/react": "npm:^18.2.7" "@types/react-dom": "npm:^18.2.4" - "@types/react-helmet": "npm:^6.1.6" "@types/react-immutable-proptypes": "npm:^2.1.0" "@types/react-router": "npm:^5.1.20" "@types/react-router-dom": "npm:^5.3.3" @@ -2893,6 +2911,7 @@ __metadata: "@types/react-test-renderer": "npm:^18.0.0" "@types/redux-immutable": "npm:^4.0.3" "@types/requestidlecallback": "npm:^0.3.5" + "@unhead/react": "npm:^3.1.0" "@use-gesture/react": "npm:^10.3.1" "@vitejs/plugin-legacy": "npm:^8.0.0" "@vitejs/plugin-react": "npm:^6.0.0" @@ -2958,7 +2977,6 @@ __metadata: react: "npm:^18.2.0" react-dom: "npm:^18.2.0" react-easy-crop: "npm:^5.5.6" - react-helmet: "npm:^6.1.0" react-immutable-proptypes: "npm:^2.2.0" react-immutable-pure-component: "npm:^2.2.2" react-intl: "npm:^10.0.0" @@ -3197,6 +3215,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-android-arm-eabi@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-android-arm-eabi@npm:0.126.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@oxc-parser/binding-android-arm-eabi@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-android-arm-eabi@npm:0.127.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@oxc-parser/binding-android-arm-eabi@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-android-arm-eabi@npm:0.128.0" @@ -3204,6 +3236,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-android-arm64@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-android-arm64@npm:0.126.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-parser/binding-android-arm64@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-android-arm64@npm:0.127.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@oxc-parser/binding-android-arm64@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-android-arm64@npm:0.128.0" @@ -3211,6 +3257,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-darwin-arm64@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-darwin-arm64@npm:0.126.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-parser/binding-darwin-arm64@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-darwin-arm64@npm:0.127.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@oxc-parser/binding-darwin-arm64@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-darwin-arm64@npm:0.128.0" @@ -3218,6 +3278,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-darwin-x64@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-darwin-x64@npm:0.126.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@oxc-parser/binding-darwin-x64@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-darwin-x64@npm:0.127.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@oxc-parser/binding-darwin-x64@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-darwin-x64@npm:0.128.0" @@ -3225,6 +3299,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-freebsd-x64@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-freebsd-x64@npm:0.126.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@oxc-parser/binding-freebsd-x64@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-freebsd-x64@npm:0.127.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@oxc-parser/binding-freebsd-x64@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-freebsd-x64@npm:0.128.0" @@ -3232,6 +3320,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-arm-gnueabihf@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-arm-gnueabihf@npm:0.126.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-arm-gnueabihf@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-arm-gnueabihf@npm:0.127.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@oxc-parser/binding-linux-arm-gnueabihf@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-arm-gnueabihf@npm:0.128.0" @@ -3239,6 +3341,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-arm-musleabihf@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-arm-musleabihf@npm:0.126.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-arm-musleabihf@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-arm-musleabihf@npm:0.127.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@oxc-parser/binding-linux-arm-musleabihf@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-arm-musleabihf@npm:0.128.0" @@ -3246,6 +3362,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-arm64-gnu@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-arm64-gnu@npm:0.126.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-arm64-gnu@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-arm64-gnu@npm:0.127.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + "@oxc-parser/binding-linux-arm64-gnu@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-arm64-gnu@npm:0.128.0" @@ -3253,6 +3383,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-arm64-musl@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-arm64-musl@npm:0.126.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-arm64-musl@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-arm64-musl@npm:0.127.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + "@oxc-parser/binding-linux-arm64-musl@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-arm64-musl@npm:0.128.0" @@ -3260,6 +3404,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-ppc64-gnu@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-ppc64-gnu@npm:0.126.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-ppc64-gnu@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-ppc64-gnu@npm:0.127.0" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + "@oxc-parser/binding-linux-ppc64-gnu@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-ppc64-gnu@npm:0.128.0" @@ -3267,6 +3425,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-riscv64-gnu@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-riscv64-gnu@npm:0.126.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-riscv64-gnu@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-riscv64-gnu@npm:0.127.0" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + "@oxc-parser/binding-linux-riscv64-gnu@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-riscv64-gnu@npm:0.128.0" @@ -3274,6 +3446,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-riscv64-musl@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-riscv64-musl@npm:0.126.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-riscv64-musl@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-riscv64-musl@npm:0.127.0" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + "@oxc-parser/binding-linux-riscv64-musl@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-riscv64-musl@npm:0.128.0" @@ -3281,6 +3467,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-s390x-gnu@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-s390x-gnu@npm:0.126.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-s390x-gnu@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-s390x-gnu@npm:0.127.0" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + "@oxc-parser/binding-linux-s390x-gnu@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-s390x-gnu@npm:0.128.0" @@ -3288,6 +3488,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-x64-gnu@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-x64-gnu@npm:0.126.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-x64-gnu@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-x64-gnu@npm:0.127.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + "@oxc-parser/binding-linux-x64-gnu@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-x64-gnu@npm:0.128.0" @@ -3295,6 +3509,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-linux-x64-musl@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-linux-x64-musl@npm:0.126.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@oxc-parser/binding-linux-x64-musl@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-linux-x64-musl@npm:0.127.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + "@oxc-parser/binding-linux-x64-musl@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-linux-x64-musl@npm:0.128.0" @@ -3302,6 +3530,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-openharmony-arm64@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-openharmony-arm64@npm:0.126.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-parser/binding-openharmony-arm64@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-openharmony-arm64@npm:0.127.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + "@oxc-parser/binding-openharmony-arm64@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-openharmony-arm64@npm:0.128.0" @@ -3309,6 +3551,28 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-wasm32-wasi@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-wasm32-wasi@npm:0.126.0" + dependencies: + "@emnapi/core": "npm:1.9.2" + "@emnapi/runtime": "npm:1.9.2" + "@napi-rs/wasm-runtime": "npm:^1.1.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@oxc-parser/binding-wasm32-wasi@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-wasm32-wasi@npm:0.127.0" + dependencies: + "@emnapi/core": "npm:1.9.2" + "@emnapi/runtime": "npm:1.9.2" + "@napi-rs/wasm-runtime": "npm:^1.1.4" + conditions: cpu=wasm32 + languageName: node + linkType: hard + "@oxc-parser/binding-wasm32-wasi@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-wasm32-wasi@npm:0.128.0" @@ -3320,6 +3584,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-win32-arm64-msvc@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-win32-arm64-msvc@npm:0.126.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@oxc-parser/binding-win32-arm64-msvc@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-win32-arm64-msvc@npm:0.127.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@oxc-parser/binding-win32-arm64-msvc@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-win32-arm64-msvc@npm:0.128.0" @@ -3327,6 +3605,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-win32-ia32-msvc@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-win32-ia32-msvc@npm:0.126.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@oxc-parser/binding-win32-ia32-msvc@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-win32-ia32-msvc@npm:0.127.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@oxc-parser/binding-win32-ia32-msvc@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-win32-ia32-msvc@npm:0.128.0" @@ -3334,6 +3626,20 @@ __metadata: languageName: node linkType: hard +"@oxc-parser/binding-win32-x64-msvc@npm:0.126.0": + version: 0.126.0 + resolution: "@oxc-parser/binding-win32-x64-msvc@npm:0.126.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@oxc-parser/binding-win32-x64-msvc@npm:0.127.0": + version: 0.127.0 + resolution: "@oxc-parser/binding-win32-x64-msvc@npm:0.127.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@oxc-parser/binding-win32-x64-msvc@npm:0.128.0": version: 0.128.0 resolution: "@oxc-parser/binding-win32-x64-msvc@npm:0.128.0" @@ -3341,13 +3647,20 @@ __metadata: languageName: node linkType: hard -"@oxc-project/types@npm:=0.127.0": +"@oxc-project/types@npm:=0.127.0, @oxc-project/types@npm:^0.127.0": version: 0.127.0 resolution: "@oxc-project/types@npm:0.127.0" checksum: 10c0/52c0947ac64a9ca119fe971f947e784a35ecd14a072fa3f542a58a5f6c42010b53f2bf92731e39b9899b83c990a9517bbd29d1e5a5b7b489e52616685c6a9278 languageName: node linkType: hard +"@oxc-project/types@npm:^0.126.0": + version: 0.126.0 + resolution: "@oxc-project/types@npm:0.126.0" + checksum: 10c0/ad0bb774d63b6529bfbe7cc0808c9368c5de6038938256eabc868cf7f812b8d304a7a57800b1cfc09bf02566c396be8148d3153fb2c5fee273ccd8f0a9fd8751 + languageName: node + linkType: hard + "@oxc-project/types@npm:^0.128.0": version: 0.128.0 resolution: "@oxc-project/types@npm:0.128.0" @@ -4906,15 +5219,6 @@ __metadata: languageName: node linkType: hard -"@types/react-helmet@npm:^6.1.6": - version: 6.1.11 - resolution: "@types/react-helmet@npm:6.1.11" - dependencies: - "@types/react": "npm:*" - checksum: 10c0/f7b3bb2151d992a108ae46fed876fb9c8119108397d9a01d150c5642782997542c8b3c52e742b56e8689b7dbfa62ca9cfc76aa7e05dec4e60c652f7ef53fa783 - languageName: node - linkType: hard - "@types/react-immutable-proptypes@npm:^2.1.0": version: 2.1.3 resolution: "@types/react-immutable-proptypes@npm:2.1.3" @@ -5213,6 +5517,63 @@ __metadata: languageName: node linkType: hard +"@unhead/bundler@npm:3.1.0": + version: 3.1.0 + resolution: "@unhead/bundler@npm:3.1.0" + dependencies: + "@vitejs/devtools-kit": "npm:^0.1.15" + magic-string: "npm:^0.30.21" + oxc-parser: "npm:^0.127.0" + oxc-walker: "npm:^0.7.0" + ufo: "npm:^1.6.3" + unplugin: "npm:^3.0.0" + peerDependencies: + "@unhead/cli": ^3.1.0 + esbuild: ">=0.17.0" + lightningcss: ">=1.20.0" + rolldown: ">=1.0.0-beta.0" + unhead: ^3.1.0 + vite: ">=6.4.2" + webpack: ">=5.0.0" + peerDependenciesMeta: + "@unhead/cli": + optional: true + esbuild: + optional: true + lightningcss: + optional: true + rolldown: + optional: true + vite: + optional: true + webpack: + optional: true + checksum: 10c0/5acef500584502a4106977c01d0fc131dd13edfc821b66bbdbe7a9d9205a082d8a8c37c230bb5b65d7ce13aa6a7262881ce51c1a3ed24be103ce2a9f9104adc7 + languageName: node + linkType: hard + +"@unhead/react@npm:^3.1.0": + version: 3.1.0 + resolution: "@unhead/react@npm:3.1.0" + dependencies: + "@unhead/bundler": "npm:3.1.0" + magic-string: "npm:^0.30.21" + oxc-walker: "npm:^0.7.0" + unhead: "npm:3.1.0" + unplugin: "npm:^3.0.0" + peerDependencies: + react: ">=19.2.4" + vite: ">=6.4.2" + webpack: ">=5.0.0" + peerDependenciesMeta: + vite: + optional: true + webpack: + optional: true + checksum: 10c0/e810fbde5eed07986785deadbd23a446c5a6ec6323068eb51b1e285f141df35ffec4f954c5f07b35ad664ecd5827709c140894b99c3fbbeee4779c9db6d8c933 + languageName: node + linkType: hard + "@unicode/unicode-17.0.0@npm:^1.6.16": version: 1.6.16 resolution: "@unicode/unicode-17.0.0@npm:1.6.16" @@ -5373,6 +5734,29 @@ __metadata: languageName: node linkType: hard +"@valibot/to-json-schema@npm:^1.6.0": + version: 1.6.0 + resolution: "@valibot/to-json-schema@npm:1.6.0" + peerDependencies: + valibot: ^1.3.0 + checksum: 10c0/3dabbb9ed0f135c436a9f4a22ff1ad3df500e0bdff1b771eb9a03f4ba7a412bb1873a9cc1ff32c09ff47d10be8d1834a540705229380b9fc46fb65a9b41dbae2 + languageName: node + linkType: hard + +"@vitejs/devtools-kit@npm:^0.1.15": + version: 0.1.18 + resolution: "@vitejs/devtools-kit@npm:0.1.18" + dependencies: + birpc: "npm:^4.0.0" + devframe: "npm:0.1.18" + ohash: "npm:^2.0.11" + sirv: "npm:^3.0.2" + peerDependencies: + vite: "*" + checksum: 10c0/4cfad9f8b24089c115c36be531636eeb1bf31f47a823ed0a3159e3bd483daaf7f0c9254359acde3a7a2e68931c49176d0269ddae40fcaa5a097452470c8bfb13 + languageName: node + linkType: hard + "@vitejs/plugin-legacy@npm:^8.0.0": version: 8.0.1 resolution: "@vitejs/plugin-legacy@npm:8.0.1" @@ -5735,6 +6119,13 @@ __metadata: languageName: node linkType: hard +"ansis@npm:^4.2.0": + version: 4.2.0 + resolution: "ansis@npm:4.2.0" + checksum: 10c0/cd6a7a681ecd36e72e0d79c1e34f1f3bcb1b15bcbb6f0f8969b4228062d3bfebbef468e09771b00d93b2294370b34f707599d4a113542a876de26823b795b5d2 + languageName: node + linkType: hard + "are-docs-informative@npm:^0.0.2": version: 0.0.2 resolution: "are-docs-informative@npm:0.0.2" @@ -6108,6 +6499,13 @@ __metadata: languageName: node linkType: hard +"birpc@npm:^4.0.0": + version: 4.0.0 + resolution: "birpc@npm:4.0.0" + checksum: 10c0/61f4e893ff4c5948b2c587c971c04883af0d8b2658d4632c8e77073db9f9e8b040402f985d56308021890b2ad32ef8392e36a8335cab1e3771d99e1b025d1af6 + languageName: node + linkType: hard + "blurhash@npm:^2.0.5": version: 2.0.5 resolution: "blurhash@npm:2.0.5" @@ -6237,6 +6635,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^7.0.0": + version: 7.0.0 + resolution: "cac@npm:7.0.0" + checksum: 10c0/e9da33cb9f0425546ae92a450d479276f9969a050fe64f5d6fedf058bdd87f22a370797fe1c158e07655fa9fc183749df7cb2037431e3772faa7bee9919fb763 + languageName: node + linkType: hard + "cacache@npm:^19.0.1": version: 19.0.1 resolution: "cacache@npm:19.0.1" @@ -6552,6 +6957,13 @@ __metadata: languageName: node linkType: hard +"confbox@npm:^0.1.8": + version: 0.1.8 + resolution: "confbox@npm:0.1.8" + checksum: 10c0/fc2c68d97cb54d885b10b63e45bd8da83a8a71459d3ecf1825143dd4c7f9f1b696b3283e07d9d12a144c1301c2ebc7842380bdf0014e55acc4ae1c9550102418 + languageName: node + linkType: hard + "content-disposition@npm:^1.0.0": version: 1.0.0 resolution: "content-disposition@npm:1.0.0" @@ -6582,6 +6994,13 @@ __metadata: languageName: node linkType: hard +"cookie-es@npm:^1.2.3": + version: 1.2.3 + resolution: "cookie-es@npm:1.2.3" + checksum: 10c0/429eae6f5130a7380ea024d787d7e1ecc644ca84f9c43dfb70f18761a831d2ba591d28f837ce350892cfff0857d711f3a4ad93a082637bceb478823c339c1a97 + languageName: node + linkType: hard + "cookie-signature@npm:^1.2.1": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" @@ -6716,6 +7135,15 @@ __metadata: languageName: node linkType: hard +"crossws@npm:^0.3.5": + version: 0.3.5 + resolution: "crossws@npm:0.3.5" + dependencies: + uncrypto: "npm:^0.1.3" + checksum: 10c0/9e873546f0806606c4f775219f6811768fc3b3b0765ca8230722e849058ad098318af006e1faa39a8008c03009c37c519f6bccad41b0d78586237585c75fb38b + languageName: node + linkType: hard + "crypto-random-string@npm:^2.0.0": version: 2.0.0 resolution: "crypto-random-string@npm:2.0.0" @@ -6955,6 +7383,13 @@ __metadata: languageName: node linkType: hard +"defu@npm:^6.1.6": + version: 6.1.7 + resolution: "defu@npm:6.1.7" + checksum: 10c0/e6635388103c8be3c574ac31302f6930e5e6eeedba32cb1b30cf993c7d9fb571aec2485446dfa23bfa63e55e66156fe109027a9695db82a50f931e91e8d4bedb + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -6992,6 +7427,13 @@ __metadata: languageName: node linkType: hard +"destr@npm:^2.0.5": + version: 2.0.5 + resolution: "destr@npm:2.0.5" + checksum: 10c0/efabffe7312a45ad90d79975376be958c50069f1156b94c181199763a7f971e113bd92227c26b94a169c71ca7dbc13583b7e96e5164743969fc79e1ff153e646 + languageName: node + linkType: hard + "detect-it@npm:^4.0.1": version: 4.0.1 resolution: "detect-it@npm:4.0.1" @@ -7024,6 +7466,37 @@ __metadata: languageName: node linkType: hard +"devframe@npm:0.1.18": + version: 0.1.18 + resolution: "devframe@npm:0.1.18" + dependencies: + "@valibot/to-json-schema": "npm:^1.6.0" + ansis: "npm:^4.2.0" + birpc: "npm:^4.0.0" + cac: "npm:^7.0.0" + h3: "npm:^1.15.11" + logs-sdk: "npm:^0.0.6" + ohash: "npm:^2.0.11" + pathe: "npm:^2.0.3" + sirv: "npm:^3.0.2" + structured-clone-es: "npm:^2.0.0" + valibot: "npm:^1.3.1" + ws: "npm:^8.20.0" + peerDependencies: + "@modelcontextprotocol/sdk": ^1.0.0 + "@nuxt/kit": ^3.0.0 || ^4.0.0 + launch-editor: ^2.0.0 + peerDependenciesMeta: + "@modelcontextprotocol/sdk": + optional: true + "@nuxt/kit": + optional: true + launch-editor: + optional: true + checksum: 10c0/35f0d6a25462dc540bba1eb4269a52dfc98b3a9dc8ac462daaa9dfc2e27060b4764692876ac6aaa7c568e912dcc1b8b2e5bb7b8f6d52ae471e4e297d9b4fe2ef + languageName: node + linkType: hard + "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -8597,6 +9070,23 @@ __metadata: languageName: node linkType: hard +"h3@npm:^1.15.11": + version: 1.15.11 + resolution: "h3@npm:1.15.11" + dependencies: + cookie-es: "npm:^1.2.3" + crossws: "npm:^0.3.5" + defu: "npm:^6.1.6" + destr: "npm:^2.0.5" + iron-webcrypto: "npm:^1.2.1" + node-mock-http: "npm:^1.0.4" + radix3: "npm:^1.1.2" + ufo: "npm:^1.6.3" + uncrypto: "npm:^0.1.3" + checksum: 10c0/6ccb421b9f92e02e6330c2b6697b18ef18e9550e4a1708f224ca517c40ecd201cd00967d0feb26e718595e86e985edec1755933cf8792d34fb8504f1c7cc261d + languageName: node + linkType: hard + "has-bigints@npm:^1.0.2": version: 1.0.2 resolution: "has-bigints@npm:1.0.2" @@ -8723,6 +9213,13 @@ __metadata: languageName: node linkType: hard +"hookable@npm:^6.1.1": + version: 6.1.1 + resolution: "hookable@npm:6.1.1" + checksum: 10c0/bb46cd9ffc0a997af21febd97835da4e59a6989adec73dc3c215fcc44c7ac01de4781f251c3d420bf45862d2592a695f5f0de095b6f5df52db8afb5166938212 + languageName: node + linkType: hard + "hookified@npm:^1.15.0, hookified@npm:^1.15.1": version: 1.15.1 resolution: "hookified@npm:1.15.1" @@ -9045,6 +9542,13 @@ __metadata: languageName: node linkType: hard +"iron-webcrypto@npm:^1.2.1": + version: 1.2.1 + resolution: "iron-webcrypto@npm:1.2.1" + checksum: 10c0/5cf27c6e2bd3ef3b4970e486235fd82491ab8229e2ed0ac23307c28d6c80d721772a86ed4e9fe2a5cabadd710c2f024b706843b40561fb83f15afee58f809f66 + languageName: node + linkType: hard + "is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5": version: 3.0.5 resolution: "is-array-buffer@npm:3.0.5" @@ -10068,6 +10572,17 @@ __metadata: languageName: node linkType: hard +"logs-sdk@npm:^0.0.6": + version: 0.0.6 + resolution: "logs-sdk@npm:0.0.6" + dependencies: + magic-string: "npm:^0.30.21" + oxc-parser: "npm:^0.126.0" + unplugin: "npm:^3.0.0" + checksum: 10c0/d1b5643f5067a89ffde1b9bd936f4d386b9518ae36f41a4e370f5a4174e778dbf6c4fc9b48374f0eee850a508d2cbccfddf2f762308712db316fdaeefc9bc52b + languageName: node + linkType: hard + "loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.2.0, loose-envify@npm:^1.3.1, loose-envify@npm:^1.4.0": version: 1.4.0 resolution: "loose-envify@npm:1.4.0" @@ -10127,7 +10642,22 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.21, magic-string@npm:^0.30.3, magic-string@npm:~0.30.11": +"magic-regexp@npm:^0.10.0": + version: 0.10.0 + resolution: "magic-regexp@npm:0.10.0" + dependencies: + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.12" + mlly: "npm:^1.7.2" + regexp-tree: "npm:^0.1.27" + type-level-regexp: "npm:~0.1.17" + ufo: "npm:^1.5.4" + unplugin: "npm:^2.0.0" + checksum: 10c0/4f183439510984744fcff5af9ef6c2776d886aba832e1390c8d85328e2a4991464e5cb18dc6f491c0184ea1b96508475a5b112295a08fdeae1018193901688f9 + languageName: node + linkType: hard + +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.12, magic-string@npm:^0.30.21, magic-string@npm:^0.30.3, magic-string@npm:~0.30.11": version: 0.30.21 resolution: "magic-string@npm:0.30.21" dependencies: @@ -10448,6 +10978,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.7.2, mlly@npm:^1.7.4": + version: 1.8.2 + resolution: "mlly@npm:1.8.2" + dependencies: + acorn: "npm:^8.16.0" + pathe: "npm:^2.0.3" + pkg-types: "npm:^1.3.1" + ufo: "npm:^1.6.3" + checksum: 10c0/aa826683a6daddf2aef65f9c8142e362731cf8e415a5591faf92fd51040a76697e45ab6dbb7a3b38be74e0f8c464825a7eabe827750455c7472421953f5da733 + languageName: node + linkType: hard + "mrmime@npm:^2.0.0": version: 2.0.1 resolution: "mrmime@npm:2.0.1" @@ -10621,6 +11163,13 @@ __metadata: languageName: node linkType: hard +"node-mock-http@npm:^1.0.4": + version: 1.0.4 + resolution: "node-mock-http@npm:1.0.4" + checksum: 10c0/86e3f7453cf07ad6b8bd17cf89ff91d45f486a861cf6d891618cf29647d559cbcde1d1f90c9cc02e014ff9f7900b2fb21c96b03ea4b4a415dbe2d65badadceba + languageName: node + linkType: hard + "node-releases@npm:^2.0.27": version: 2.0.27 resolution: "node-releases@npm:2.0.27" @@ -10749,6 +11298,13 @@ __metadata: languageName: node linkType: hard +"ohash@npm:^2.0.11": + version: 2.0.11 + resolution: "ohash@npm:2.0.11" + checksum: 10c0/d07c8d79cc26da082c1a7c8d5b56c399dd4ed3b2bd069fcae6bae78c99a9bcc3ad813b1e1f49ca2f335292846d689c6141a762cf078727d2302a33d414e69c79 + languageName: node + linkType: hard + "on-exit-leak-free@npm:^2.1.0": version: 2.1.2 resolution: "on-exit-leak-free@npm:2.1.2" @@ -10850,6 +11406,146 @@ __metadata: languageName: node linkType: hard +"oxc-parser@npm:^0.126.0": + version: 0.126.0 + resolution: "oxc-parser@npm:0.126.0" + dependencies: + "@oxc-parser/binding-android-arm-eabi": "npm:0.126.0" + "@oxc-parser/binding-android-arm64": "npm:0.126.0" + "@oxc-parser/binding-darwin-arm64": "npm:0.126.0" + "@oxc-parser/binding-darwin-x64": "npm:0.126.0" + "@oxc-parser/binding-freebsd-x64": "npm:0.126.0" + "@oxc-parser/binding-linux-arm-gnueabihf": "npm:0.126.0" + "@oxc-parser/binding-linux-arm-musleabihf": "npm:0.126.0" + "@oxc-parser/binding-linux-arm64-gnu": "npm:0.126.0" + "@oxc-parser/binding-linux-arm64-musl": "npm:0.126.0" + "@oxc-parser/binding-linux-ppc64-gnu": "npm:0.126.0" + "@oxc-parser/binding-linux-riscv64-gnu": "npm:0.126.0" + "@oxc-parser/binding-linux-riscv64-musl": "npm:0.126.0" + "@oxc-parser/binding-linux-s390x-gnu": "npm:0.126.0" + "@oxc-parser/binding-linux-x64-gnu": "npm:0.126.0" + "@oxc-parser/binding-linux-x64-musl": "npm:0.126.0" + "@oxc-parser/binding-openharmony-arm64": "npm:0.126.0" + "@oxc-parser/binding-wasm32-wasi": "npm:0.126.0" + "@oxc-parser/binding-win32-arm64-msvc": "npm:0.126.0" + "@oxc-parser/binding-win32-ia32-msvc": "npm:0.126.0" + "@oxc-parser/binding-win32-x64-msvc": "npm:0.126.0" + "@oxc-project/types": "npm:^0.126.0" + dependenciesMeta: + "@oxc-parser/binding-android-arm-eabi": + optional: true + "@oxc-parser/binding-android-arm64": + optional: true + "@oxc-parser/binding-darwin-arm64": + optional: true + "@oxc-parser/binding-darwin-x64": + optional: true + "@oxc-parser/binding-freebsd-x64": + optional: true + "@oxc-parser/binding-linux-arm-gnueabihf": + optional: true + "@oxc-parser/binding-linux-arm-musleabihf": + optional: true + "@oxc-parser/binding-linux-arm64-gnu": + optional: true + "@oxc-parser/binding-linux-arm64-musl": + optional: true + "@oxc-parser/binding-linux-ppc64-gnu": + optional: true + "@oxc-parser/binding-linux-riscv64-gnu": + optional: true + "@oxc-parser/binding-linux-riscv64-musl": + optional: true + "@oxc-parser/binding-linux-s390x-gnu": + optional: true + "@oxc-parser/binding-linux-x64-gnu": + optional: true + "@oxc-parser/binding-linux-x64-musl": + optional: true + "@oxc-parser/binding-openharmony-arm64": + optional: true + "@oxc-parser/binding-wasm32-wasi": + optional: true + "@oxc-parser/binding-win32-arm64-msvc": + optional: true + "@oxc-parser/binding-win32-ia32-msvc": + optional: true + "@oxc-parser/binding-win32-x64-msvc": + optional: true + checksum: 10c0/412b02368711565b4f448c0866fdb37131ac4bc0ccdd0ee97c6b2dadc7bf7d95b3158aff7dc71f2ca2ad789851b99ca81004c348a60f852ac3bf7e9d46cdaecd + languageName: node + linkType: hard + +"oxc-parser@npm:^0.127.0": + version: 0.127.0 + resolution: "oxc-parser@npm:0.127.0" + dependencies: + "@oxc-parser/binding-android-arm-eabi": "npm:0.127.0" + "@oxc-parser/binding-android-arm64": "npm:0.127.0" + "@oxc-parser/binding-darwin-arm64": "npm:0.127.0" + "@oxc-parser/binding-darwin-x64": "npm:0.127.0" + "@oxc-parser/binding-freebsd-x64": "npm:0.127.0" + "@oxc-parser/binding-linux-arm-gnueabihf": "npm:0.127.0" + "@oxc-parser/binding-linux-arm-musleabihf": "npm:0.127.0" + "@oxc-parser/binding-linux-arm64-gnu": "npm:0.127.0" + "@oxc-parser/binding-linux-arm64-musl": "npm:0.127.0" + "@oxc-parser/binding-linux-ppc64-gnu": "npm:0.127.0" + "@oxc-parser/binding-linux-riscv64-gnu": "npm:0.127.0" + "@oxc-parser/binding-linux-riscv64-musl": "npm:0.127.0" + "@oxc-parser/binding-linux-s390x-gnu": "npm:0.127.0" + "@oxc-parser/binding-linux-x64-gnu": "npm:0.127.0" + "@oxc-parser/binding-linux-x64-musl": "npm:0.127.0" + "@oxc-parser/binding-openharmony-arm64": "npm:0.127.0" + "@oxc-parser/binding-wasm32-wasi": "npm:0.127.0" + "@oxc-parser/binding-win32-arm64-msvc": "npm:0.127.0" + "@oxc-parser/binding-win32-ia32-msvc": "npm:0.127.0" + "@oxc-parser/binding-win32-x64-msvc": "npm:0.127.0" + "@oxc-project/types": "npm:^0.127.0" + dependenciesMeta: + "@oxc-parser/binding-android-arm-eabi": + optional: true + "@oxc-parser/binding-android-arm64": + optional: true + "@oxc-parser/binding-darwin-arm64": + optional: true + "@oxc-parser/binding-darwin-x64": + optional: true + "@oxc-parser/binding-freebsd-x64": + optional: true + "@oxc-parser/binding-linux-arm-gnueabihf": + optional: true + "@oxc-parser/binding-linux-arm-musleabihf": + optional: true + "@oxc-parser/binding-linux-arm64-gnu": + optional: true + "@oxc-parser/binding-linux-arm64-musl": + optional: true + "@oxc-parser/binding-linux-ppc64-gnu": + optional: true + "@oxc-parser/binding-linux-riscv64-gnu": + optional: true + "@oxc-parser/binding-linux-riscv64-musl": + optional: true + "@oxc-parser/binding-linux-s390x-gnu": + optional: true + "@oxc-parser/binding-linux-x64-gnu": + optional: true + "@oxc-parser/binding-linux-x64-musl": + optional: true + "@oxc-parser/binding-openharmony-arm64": + optional: true + "@oxc-parser/binding-wasm32-wasi": + optional: true + "@oxc-parser/binding-win32-arm64-msvc": + optional: true + "@oxc-parser/binding-win32-ia32-msvc": + optional: true + "@oxc-parser/binding-win32-x64-msvc": + optional: true + checksum: 10c0/9d109fb3a79c0862a36434cc01c8c0e8f6cf5f1efe9369e02d2183fd518479b10262cf092da2e7f8328befae446afa05ccf742ce12f8346d81429c8f2cdf1651 + languageName: node + linkType: hard + "oxc-parser@npm:^0.128.0": version: 0.128.0 resolution: "oxc-parser@npm:0.128.0" @@ -10920,6 +11616,17 @@ __metadata: languageName: node linkType: hard +"oxc-walker@npm:^0.7.0": + version: 0.7.0 + resolution: "oxc-walker@npm:0.7.0" + dependencies: + magic-regexp: "npm:^0.10.0" + peerDependencies: + oxc-parser: ">=0.98.0" + checksum: 10c0/4238233aaec526a1937b5d173202fbeaa22ff3047fcb5734516d595cf415b0d2b78f9e042aa090d6579574a654224d1d31c2fe6d31ff086c1dd525bbfa9cb354 + languageName: node + linkType: hard + "oxfmt@npm:^0.47.0": version: 0.47.0 resolution: "oxfmt@npm:0.47.0" @@ -11173,7 +11880,7 @@ __metadata: languageName: node linkType: hard -"pathe@npm:^2.0.3": +"pathe@npm:^2.0.1, pathe@npm:^2.0.3": version: 2.0.3 resolution: "pathe@npm:2.0.3" checksum: 10c0/c118dc5a8b5c4166011b2b70608762e260085180bb9e33e80a50dcdb1e78c010b1624f4280c492c92b05fc276715a4c357d1f9edc570f8f1b3d90b6839ebaca1 @@ -11368,6 +12075,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.3.1": + version: 1.3.1 + resolution: "pkg-types@npm:1.3.1" + dependencies: + confbox: "npm:^0.1.8" + mlly: "npm:^1.7.4" + pathe: "npm:^2.0.1" + checksum: 10c0/19e6cb8b66dcc66c89f2344aecfa47f2431c988cfa3366bdfdcfb1dd6695f87dcce37fbd90fe9d1605e2f4440b77f391e83c23255347c35cf84e7fd774d7fcea + languageName: node + linkType: hard + "playwright-core@npm:1.59.1": version: 1.59.1 resolution: "playwright-core@npm:1.59.1" @@ -12084,6 +12802,13 @@ __metadata: languageName: node linkType: hard +"radix3@npm:^1.1.2": + version: 1.1.2 + resolution: "radix3@npm:1.1.2" + checksum: 10c0/d4a295547f71af079868d2c2ed3814a9296ee026c5488212d58c106e6b4797c6eaec1259b46c9728913622f2240c9a944bfc8e2b3b5f6e4a5045338b1609f1e4 + languageName: node + linkType: hard + "range-parser@npm:^1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" @@ -12166,27 +12891,6 @@ __metadata: languageName: node linkType: hard -"react-fast-compare@npm:^3.1.1": - version: 3.2.2 - resolution: "react-fast-compare@npm:3.2.2" - checksum: 10c0/0bbd2f3eb41ab2ff7380daaa55105db698d965c396df73e6874831dbafec8c4b5b08ba36ff09df01526caa3c61595247e3269558c284e37646241cba2b90a367 - languageName: node - linkType: hard - -"react-helmet@npm:^6.1.0": - version: 6.1.0 - resolution: "react-helmet@npm:6.1.0" - dependencies: - object-assign: "npm:^4.1.1" - prop-types: "npm:^15.7.2" - react-fast-compare: "npm:^3.1.1" - react-side-effect: "npm:^2.1.0" - peerDependencies: - react: ">=16.3.0" - checksum: 10c0/1d2831d9c3b4f5c91f020076aeb6502437a4788077d0c438421e466eb9633d5dc2aacedf7b779a970b807d61cf87793c5ff76ee3190a185d71c90b5cfb367e96 - languageName: node - linkType: hard - "react-immutable-proptypes@npm:^2.2.0": version: 2.2.0 resolution: "react-immutable-proptypes@npm:2.2.0" @@ -12372,15 +13076,6 @@ __metadata: languageName: node linkType: hard -"react-side-effect@npm:^2.1.0": - version: 2.1.2 - resolution: "react-side-effect@npm:2.1.2" - peerDependencies: - react: ^16.3.0 || ^17.0.0 || ^18.0.0 - checksum: 10c0/5d934cae438f701ce646f566750ae6a445e99185ce1a026108f9db728147f7962a22ecf8db79ff26089953a3799b3607766904f4f10194ce42bcd5a1aa0215e8 - languageName: node - linkType: hard - "react-sparklines@npm:^1.7.0": version: 1.7.0 resolution: "react-sparklines@npm:1.7.0" @@ -12583,6 +13278,15 @@ __metadata: languageName: node linkType: hard +"regexp-tree@npm:^0.1.27": + version: 0.1.27 + resolution: "regexp-tree@npm:0.1.27" + bin: + regexp-tree: bin/regexp-tree + checksum: 10c0/f636f44b4a0d93d7d6926585ecd81f63e4ce2ac895bc417b2ead0874cd36b337dcc3d0fedc63f69bf5aaeaa4340f36ca7e750c9687cceaf8087374e5284e843c + languageName: node + linkType: hard + "regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" @@ -13833,6 +14537,13 @@ __metadata: languageName: node linkType: hard +"structured-clone-es@npm:^2.0.0": + version: 2.0.0 + resolution: "structured-clone-es@npm:2.0.0" + checksum: 10c0/3fc4ce67a44300170de29af115752a18799def1fdd83cfb9c133b0c963102b8949b06f4e35e8bde3e3de2e02ebbb7730849f75bc6c3d411c22d91c17015affa9 + languageName: node + linkType: hard + "stylelint-config-recommended-scss@npm:^17.0.0": version: 17.0.0 resolution: "stylelint-config-recommended-scss@npm:17.0.0" @@ -14422,6 +15133,13 @@ __metadata: languageName: node linkType: hard +"type-level-regexp@npm:~0.1.17": + version: 0.1.17 + resolution: "type-level-regexp@npm:0.1.17" + checksum: 10c0/54798f83464cb5ce04246c9c4739ec471c526aaa7690679fddbce05b689b99403de709f3fcb494555d4276b46c606435a95855e52535602f63378ab8b38010d5 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -14559,6 +15277,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.5.4, ufo@npm:^1.6.3": + version: 1.6.4 + resolution: "ufo@npm:1.6.4" + checksum: 10c0/3a2b29e7e3d772fbf6893d7d23bf442981457adb2fe122828abdbda89bedcb81aafd0dcc080e41b45f9a877db00cb42cbfee9639753a19d9b9bd39b5627039cf + languageName: node + linkType: hard + "unbox-primitive@npm:^1.1.0": version: 1.1.0 resolution: "unbox-primitive@npm:1.1.0" @@ -14585,6 +15310,13 @@ __metadata: languageName: node linkType: hard +"uncrypto@npm:^0.1.3": + version: 0.1.3 + resolution: "uncrypto@npm:0.1.3" + checksum: 10c0/74a29afefd76d5b77bedc983559ceb33f5bbc8dada84ff33755d1e3355da55a4e03a10e7ce717918c436b4dfafde1782e799ebaf2aadd775612b49f7b5b2998e + languageName: node + linkType: hard + "undici-types@npm:~7.16.0": version: 7.16.0 resolution: "undici-types@npm:7.16.0" @@ -14599,6 +15331,21 @@ __metadata: languageName: node linkType: hard +"unhead@npm:3.1.0": + version: 3.1.0 + resolution: "unhead@npm:3.1.0" + dependencies: + hookable: "npm:^6.1.1" + unplugin: "npm:^3.0.0" + peerDependencies: + vite: ">=6.4.2" + peerDependenciesMeta: + vite: + optional: true + checksum: 10c0/967ab3ee8729398a92d69c372d8815b7a76d55d92fe9b5f628cf88e29b75df061d9eae1f787d14fefb7efab0595492c2fa30f3d89154f17c26297513c9f7f46b + languageName: node + linkType: hard + "unicode-canonical-property-names-ecmascript@npm:^2.0.0": version: 2.0.1 resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" @@ -14678,6 +15425,18 @@ __metadata: languageName: node linkType: hard +"unplugin@npm:^2.0.0": + version: 2.3.11 + resolution: "unplugin@npm:2.3.11" + dependencies: + "@jridgewell/remapping": "npm:^2.3.5" + acorn: "npm:^8.15.0" + picomatch: "npm:^4.0.3" + webpack-virtual-modules: "npm:^0.6.2" + checksum: 10c0/273c1eab0eca4470c7317428689295c31dbe8ab0b306504de9f03cd20c156debb4131bef24b27ac615862958c5dd950a3951d26c0723ea774652ab3624149cff + languageName: node + linkType: hard + "unplugin@npm:^2.3.5": version: 2.3.10 resolution: "unplugin@npm:2.3.10" @@ -14884,6 +15643,18 @@ __metadata: languageName: node linkType: hard +"valibot@npm:^1.3.1": + version: 1.3.1 + resolution: "valibot@npm:1.3.1" + peerDependencies: + typescript: ">=5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/e20a4097fa726f57530da1e64558af47ddd2303129c77978fe93c522c66cf4c79540ea3af864523589283ea25e347c3d65b8044fa4913376208dde576b9f6382 + languageName: node + linkType: hard + "value-equal@npm:^1.0.1": version: 1.0.1 resolution: "value-equal@npm:1.0.1" @@ -15519,7 +16290,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.12.1, ws@npm:^8.18.0, ws@npm:^8.19.0": +"ws@npm:^8.12.1, ws@npm:^8.18.0, ws@npm:^8.19.0, ws@npm:^8.20.0": version: 8.20.0 resolution: "ws@npm:8.20.0" peerDependencies: