diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f7e2e580..889eccdbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Datepicker: correctly default to the current year. - Scheduled posts: fix page crashing on deleting a scheduled post. - Events: don't crash when searching for a location. +- Search: fixes an abort error when using the navbar search component. +- Posts: fix monospace font in Markdown code blocks. +- Modals: fix action buttons overflow +- Editing: don't insert edited posts to the top of the feed. ## [3.0.0] - 2022-12-25 diff --git a/app/soapbox/actions/me.ts b/app/soapbox/actions/me.ts index 7a7cf18d9..a8b275200 100644 --- a/app/soapbox/actions/me.ts +++ b/app/soapbox/actions/me.ts @@ -6,7 +6,7 @@ import api from '../api'; import { loadCredentials } from './auth'; import { importFetchedAccount } from './importer'; -import type { AxiosError, AxiosRequestHeaders } from 'axios'; +import type { AxiosError, RawAxiosRequestHeaders } from 'axios'; import type { AppDispatch, RootState } from 'soapbox/store'; import type { APIEntity } from 'soapbox/types/entities'; @@ -66,7 +66,7 @@ const patchMe = (params: Record, isFormData = false) => (dispatch: AppDispatch, getState: () => RootState) => { dispatch(patchMeRequest()); - const headers: AxiosRequestHeaders = isFormData ? { + const headers: RawAxiosRequestHeaders = isFormData ? { 'Content-Type': 'multipart/form-data', } : {}; diff --git a/app/soapbox/actions/statuses.ts b/app/soapbox/actions/statuses.ts index f9bfca3b0..047d61d71 100644 --- a/app/soapbox/actions/statuses.ts +++ b/app/soapbox/actions/statuses.ts @@ -68,7 +68,7 @@ const createStatus = (params: Record, idempotencyKey: string, statu } dispatch(importFetchedStatus(status, idempotencyKey)); - dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey }); + dispatch({ type: STATUS_CREATE_SUCCESS, status, params, idempotencyKey, editing: !!statusId }); // Poll the backend for the updated card if (status.expectsCard) { diff --git a/app/soapbox/components/autosuggest-account-input.tsx b/app/soapbox/components/autosuggest-account-input.tsx index dc05b8be2..383bf7583 100644 --- a/app/soapbox/components/autosuggest-account-input.tsx +++ b/app/soapbox/components/autosuggest-account-input.tsx @@ -44,7 +44,7 @@ const AutosuggestAccountInput: React.FC = ({ setAccountIds(ImmutableOrderedSet()); }; - const handleAccountSearch = useCallback(throttle(q => { + const handleAccountSearch = useCallback(throttle((q) => { const params = { q, limit, resolve: false }; dispatch(accountSearch(params, controller.current.signal)) @@ -53,7 +53,7 @@ const AutosuggestAccountInput: React.FC = ({ setAccountIds(ImmutableOrderedSet(accountIds)); }) .catch(noOp); - }, 900, { leading: false, trailing: true }), [limit]); + }, 900, { leading: true, trailing: true }), [limit]); const handleChange: React.ChangeEventHandler = e => { refreshCancelToken(); diff --git a/app/soapbox/features/feed-filtering/feed-carousel.tsx b/app/soapbox/features/feed-filtering/feed-carousel.tsx index c16d3bd78..6a4edf2e6 100644 --- a/app/soapbox/features/feed-filtering/feed-carousel.tsx +++ b/app/soapbox/features/feed-filtering/feed-carousel.tsx @@ -98,13 +98,21 @@ const FeedCarousel = () => { const [pinnedAvatar, setPinnedAvatar] = useState(null); const avatarsToList = useMemo(() => { - const list = avatars.filter((avatar) => avatar.account_id !== pinnedAvatar?.account_id); + let list: (Avatar | null)[] = avatars.filter((avatar) => avatar.account_id !== pinnedAvatar?.account_id); + + // If we have an Avatar pinned, let's create a new array with "null" + // in the first position of each page. if (pinnedAvatar) { - return [null, ...list]; + const index = (currentPage - 1) * pageSize; + list = [ + ...list.slice(0, index), + null, + ...list.slice(index), + ]; } return list; - }, [avatars, pinnedAvatar]); + }, [avatars, pinnedAvatar, currentPage, pageSize]); const numberOfPages = Math.ceil(avatars.length / pageSize); const widthPerAvatar = width / (Math.floor(width / 80)); diff --git a/app/soapbox/features/ui/components/modals/birthdays-modal.tsx b/app/soapbox/features/ui/components/modals/birthdays-modal.tsx index 2eb9504ec..fa5fd36de 100644 --- a/app/soapbox/features/ui/components/modals/birthdays-modal.tsx +++ b/app/soapbox/features/ui/components/modals/birthdays-modal.tsx @@ -28,6 +28,7 @@ const BirthdaysModal = ({ onClose }: IBirthdaysModal) => { {accountIds.map(id => diff --git a/app/soapbox/features/ui/components/modals/event-participants-modal.tsx b/app/soapbox/features/ui/components/modals/event-participants-modal.tsx index c975ea22c..1bb6844e6 100644 --- a/app/soapbox/features/ui/components/modals/event-participants-modal.tsx +++ b/app/soapbox/features/ui/components/modals/event-participants-modal.tsx @@ -2,7 +2,8 @@ import React, { useEffect } from 'react'; import { FormattedMessage } from 'react-intl'; import { fetchEventParticipations } from 'soapbox/actions/events'; -import { Modal, Spinner, Stack } from 'soapbox/components/ui'; +import ScrollableList from 'soapbox/components/scrollable-list'; +import { Modal, Spinner } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account-container'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; @@ -33,16 +34,19 @@ const EventParticipantsModal: React.FC = ({ onClose, st if (!accountIds) { body = ; } else { + const emptyMessage = ; + body = ( - - {accountIds.size > 0 ? ( - accountIds.map((id) => - , - ) - ) : ( - + + {accountIds.map(id => + , )} - + ); } diff --git a/app/soapbox/features/ui/components/modals/favourites-modal.tsx b/app/soapbox/features/ui/components/modals/favourites-modal.tsx index 9e2b72a61..e8ec1db39 100644 --- a/app/soapbox/features/ui/components/modals/favourites-modal.tsx +++ b/app/soapbox/features/ui/components/modals/favourites-modal.tsx @@ -2,7 +2,8 @@ import React, { useEffect } from 'react'; import { FormattedMessage } from 'react-intl'; import { fetchFavourites } from 'soapbox/actions/interactions'; -import { Modal, Spinner, Stack } from 'soapbox/components/ui'; +import ScrollableList from 'soapbox/components/scrollable-list'; +import { Modal, Spinner } from 'soapbox/components/ui'; import AccountContainer from 'soapbox/containers/account-container'; import { useAppDispatch, useAppSelector } from 'soapbox/hooks'; @@ -33,16 +34,19 @@ const FavouritesModal: React.FC = ({ onClose, statusId }) => { if (!accountIds) { body = ; } else { + const emptyMessage = ; + body = ( - - {accountIds.size > 0 ? ( - accountIds.map((id) => - , - ) - ) : ( - + + {accountIds.map(id => + , )} - + ); } diff --git a/app/soapbox/features/ui/components/modals/mentions-modal.tsx b/app/soapbox/features/ui/components/modals/mentions-modal.tsx index 1df00fb08..d131687c2 100644 --- a/app/soapbox/features/ui/components/modals/mentions-modal.tsx +++ b/app/soapbox/features/ui/components/modals/mentions-modal.tsx @@ -41,6 +41,7 @@ const MentionsModal: React.FC = ({ onClose, statusId }) => { body = ( {accountIds.map(id => diff --git a/app/soapbox/features/ui/components/modals/reactions-modal.tsx b/app/soapbox/features/ui/components/modals/reactions-modal.tsx index 60c8bd158..7afe96f86 100644 --- a/app/soapbox/features/ui/components/modals/reactions-modal.tsx +++ b/app/soapbox/features/ui/components/modals/reactions-modal.tsx @@ -1,3 +1,4 @@ +import classNames from 'clsx'; import { List as ImmutableList } from 'immutable'; import React, { useEffect, useState } from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; @@ -84,7 +85,9 @@ const ReactionsModal: React.FC = ({ onClose, statusId, reaction 0, + })} itemClassName='pb-3' > {accounts.map((account) => diff --git a/app/soapbox/features/ui/components/modals/reblogs-modal.tsx b/app/soapbox/features/ui/components/modals/reblogs-modal.tsx index 526e7507f..6f5e7d70c 100644 --- a/app/soapbox/features/ui/components/modals/reblogs-modal.tsx +++ b/app/soapbox/features/ui/components/modals/reblogs-modal.tsx @@ -41,6 +41,7 @@ const ReblogsModal: React.FC = ({ onClose, statusId }) => { {accountIds.map((id) => diff --git a/app/soapbox/reducers/timelines.ts b/app/soapbox/reducers/timelines.ts index 8d2b03511..558dae54d 100644 --- a/app/soapbox/reducers/timelines.ts +++ b/app/soapbox/reducers/timelines.ts @@ -314,7 +314,7 @@ export default function timelines(state: State = initialState, action: AnyAction if (action.params.scheduled_at) return state; return importPendingStatus(state, action.params, action.idempotencyKey); case STATUS_CREATE_SUCCESS: - if (action.status.scheduled_at) return state; + if (action.status.scheduled_at || action.editing) return state; return importStatus(state, action.status, action.idempotencyKey); case TIMELINE_EXPAND_REQUEST: return setLoading(state, action.timeline, true); diff --git a/app/styles/application.scss b/app/styles/application.scss index f33e9888e..53a7a8c39 100644 --- a/app/styles/application.scss +++ b/app/styles/application.scss @@ -7,6 +7,7 @@ @import '~@fontsource/inter/600.css'; @import '~@fontsource/inter/700.css'; @import '~@fontsource/inter/900.css'; +@import '~@fontsource/roboto-mono/400.css'; @import 'mixins'; @import 'themes'; @@ -16,7 +17,6 @@ @import 'accounts'; @import 'loading'; @import 'ui'; -// @import 'introduction'; @import 'emoji-picker'; @import 'rtl'; @import 'accessibility'; diff --git a/package.json b/package.json index fd209faa5..c43b2a2f5 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@babel/preset-typescript": "^7.17.12", "@babel/runtime": "^7.18.3", "@fontsource/inter": "^4.5.1", - "@fontsource/roboto": "^4.5.0", + "@fontsource/roboto-mono": "^4.5.8", "@gamestdio/websocket": "^0.3.2", "@jest/globals": "^29.0.0", "@lcdp/offline-plugin": "^5.1.0", @@ -97,7 +97,7 @@ "@types/webpack-deadcode-plugin": "^0.1.2", "array-includes": "^3.1.5", "autoprefixer": "^10.4.2", - "axios": "^1.0.0-alpha.1", + "axios": "^1.2.2", "axios-mock-adapter": "^1.21.1", "babel-loader": "^8.2.5", "babel-plugin-lodash": "^3.3.4", diff --git a/yarn.lock b/yarn.lock index e5d74b9f7..c56c858bf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1404,10 +1404,10 @@ resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.1.tgz#058d8a02354f3c78e369d452c15d33557ec1b705" integrity sha512-mvtOvXNNVLlF1p/UbLgLrmz2RCOl6Ow+TqyiK10SosoLKX7edsXYiHFHb7XIZdjII6F2sJVPPsJXWhBnbXT2DQ== -"@fontsource/roboto@^4.5.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@fontsource/roboto/-/roboto-4.5.0.tgz#d6f925668ba6af46707f1040c43aff498ba204bb" - integrity sha512-ja4XYw/9kNRFM5Ndk9vwzHWsdBMXczyBazFkTXJQ74QQBnT0BbSsHn0pF60AU0Iznig1Wt9x3rADfG8LANvMpw== +"@fontsource/roboto-mono@^4.5.8": + version "4.5.8" + resolved "https://registry.yarnpkg.com/@fontsource/roboto-mono/-/roboto-mono-4.5.8.tgz#f3a48195528b10e154c98365671de14e27605bdb" + integrity sha512-AW44UkbQD0w1CT5mzDbsvhGZ6/bb0YmZzoELj6Sx8vcVEzcbYGUdt2Dtl5zqlOuYMWQFY1mniwWyVv+Bm/lVxw== "@formatjs/ecma402-abstract@1.11.4": version "1.11.4" @@ -3658,10 +3658,10 @@ axios-mock-adapter@^1.21.1: fast-deep-equal "^3.1.3" is-buffer "^2.0.5" -axios@^1.0.0-alpha.1: - version "1.0.0-alpha.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.0.0-alpha.1.tgz#ce69c17ca7605d01787ca754dd906e6fccdf71ee" - integrity sha512-p+meG161943WT+K7sJYquHR46xxi/z0tk7vnSmEf/LrfEAyiP+0uTMMYk1OEo1IRF18oGRhnFxN1y8fLcXaTMw== +axios@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.2.2.tgz#72681724c6e6a43a9fea860fc558127dbe32f9f1" + integrity sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0"