diff --git a/src/components/post-form/__tests__/post-form.test.tsx b/src/components/post-form/__tests__/post-form.test.tsx
index 20586860..e62442b8 100644
--- a/src/components/post-form/__tests__/post-form.test.tsx
+++ b/src/components/post-form/__tests__/post-form.test.tsx
@@ -25,6 +25,7 @@ const testState = vi.hoisted(() => ({
handleUploadMock: vi.fn(),
isOffline: false,
isOnlineStatusLoading: false,
+ isUploading: false,
isResolvingExternalQuotes: false,
navigateMock: vi.fn(),
offlineTitle: 'offline board',
@@ -172,12 +173,16 @@ vi.mock('../../../hooks/use-file-upload', () => ({
testState.uploadComplete = onUploadComplete;
return {
handleUpload: testState.handleUploadMock,
- isUploading: false,
+ isUploading: testState.isUploading,
uploadedFileName: testState.uploadedFileName,
};
},
}));
+vi.mock('../../loading-ellipsis', () => ({
+ default: ({ string }: { string: string }) => createElement('span', { 'data-testid': 'loading-ellipsis' }, string),
+}));
+
vi.mock('../../../lib/utils/media-utils', () => ({
getDisplayMediaInfoType: (type: string, t: (key: string) => string) => t(type),
getLinkMediaInfo: (link: string) => {
@@ -293,6 +298,7 @@ describe('PostForm', () => {
testState.gifFrameStatus = 'idle';
testState.isOffline = false;
testState.isOnlineStatusLoading = false;
+ testState.isUploading = false;
testState.isResolvingExternalQuotes = false;
testState.offlineTitle = 'offline board';
testState.postIndex = undefined;
@@ -433,6 +439,15 @@ describe('PostForm', () => {
expect(table?.textContent).toContain('file name.jpg');
});
+ it('uses the shared loading ellipsis while a post form upload is running', async () => {
+ testState.isUploading = true;
+
+ await renderPostForm('/all');
+ await clickByText(container, 'start_new_thread');
+
+ expect(container.querySelector('[data-testid="loading-ellipsis"]')?.textContent).toBe('uploading');
+ });
+
it('redirects to the pending route when a post publish index is already available on mount', async () => {
testState.postIndex = 7;
testState.resolvedCommunityAddress = 'music-posting.eth';
diff --git a/src/components/post-form/post-form.tsx b/src/components/post-form/post-form.tsx
index 388624d7..3126ec2b 100644
--- a/src/components/post-form/post-form.tsx
+++ b/src/components/post-form/post-form.tsx
@@ -21,6 +21,7 @@ import { getShowUploadControls, isWebRuntime } from '../../lib/media-hosting/sho
import { isCommentArchived } from '../../lib/utils/comment-moderation-utils';
import useMediaHostingStore from '../../stores/use-media-hosting-store';
import BoardOfflineAlert from '../board-offline-alert/board-offline-alert';
+import LoadingEllipsis from '../loading-ellipsis';
import styles from './post-form.module.css';
import capitalize from 'lodash/capitalize';
import debounce from 'lodash/debounce';
@@ -258,7 +259,7 @@ const PostFormFields = ({
isUploading={isUploading}
showUploadControls={showUploadControls}
/>
- {isUploading ? t('uploading') : getPublishURLFilename(url) || uploadedFileName || t('no_file_chosen')}
+ {isUploading ? : getPublishURLFilename(url) || uploadedFileName || t('no_file_chosen')}
)}
diff --git a/src/components/reply-modal/__tests__/reply-modal.test.tsx b/src/components/reply-modal/__tests__/reply-modal.test.tsx
index 294a5e07..1cbe315a 100644
--- a/src/components/reply-modal/__tests__/reply-modal.test.tsx
+++ b/src/components/reply-modal/__tests__/reply-modal.test.tsx
@@ -165,6 +165,10 @@ vi.mock('../../../hooks/use-file-upload', () => ({
},
}));
+vi.mock('../../loading-ellipsis', () => ({
+ default: ({ string }: { string: string }) => createElement('span', { 'data-testid': 'loading-ellipsis' }, string),
+}));
+
vi.mock('lodash/debounce', () => ({
default: void>(fn: T) => {
const wrapped = ((...args: Parameters) => fn(...args)) as T & { cancel: () => void };
@@ -344,6 +348,14 @@ describe('ReplyModal', () => {
expect(testState.setPublishReplyOptionsMock).toHaveBeenCalledWith({ displayName: 'Alice' });
});
+ it('uses the shared loading ellipsis while a reply upload is running', async () => {
+ testState.isUploading = true;
+
+ await renderReplyModal('/mu/thread/post-1');
+
+ expect(container.querySelector('[data-testid="loading-ellipsis"]')?.textContent).toBe('uploading');
+ });
+
it('does not render an offline warning when the shared offline hook reports the board as online', async () => {
await renderReplyModal('/mu/thread/post-1');
diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx
index 23003c1f..c538c371 100644
--- a/src/components/reply-modal/reply-modal.tsx
+++ b/src/components/reply-modal/reply-modal.tsx
@@ -14,6 +14,7 @@ import usePublishReply from '../../hooks/use-publish-reply';
import useIsMobile from '../../hooks/use-is-mobile';
import { useFileUpload } from '../../hooks/use-file-upload';
import BoardOfflineAlert from '../board-offline-alert/board-offline-alert';
+import LoadingEllipsis from '../loading-ellipsis';
import styles from './reply-modal.module.css';
import capitalize from 'lodash/capitalize';
import debounce from 'lodash/debounce';
@@ -374,7 +375,7 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, parentNumber, threa
- {isUploading ? t('uploading') : displayedFileName || t('no_file_chosen')}
+ {isUploading ? : displayedFileName || t('no_file_chosen')}
)}