diff --git a/frontend/src/components/BulkAddChannelResultModal.tsx b/frontend/src/components/BulkAddChannelResultModal.tsx index 40085b1..30c97e9 100644 --- a/frontend/src/components/BulkAddChannelResultModal.tsx +++ b/frontend/src/components/BulkAddChannelResultModal.tsx @@ -84,12 +84,12 @@ export function BulkAddChannelResultModal({ ) : ( -

No new rooms were added.

+

No new channels were added.

)} {result && result.invalid_names.length > 0 && (
- Ignored invalid room names: {result.invalid_names.join(', ')} + Ignored invalid channel names: {result.invalid_names.join(', ')}
)} diff --git a/frontend/src/components/ContactInfoPane.tsx b/frontend/src/components/ContactInfoPane.tsx index 448d20c..020239f 100644 --- a/frontend/src/components/ContactInfoPane.tsx +++ b/frontend/src/components/ContactInfoPane.tsx @@ -298,17 +298,16 @@ export function ContactInfoPane({ {isPrefixOnlyResolvedContact && (
- We only know a key prefix for this sender, which can happen when a fallback DM - arrives before we hear an advertisement. This contact stays read-only until the full - key resolves from a later advertisement. + We've received a message from this sender but don't have their full + identity yet. This contact stays read-only until their identity is confirmed — + this usually happens automatically when they next advertise.
)} {isUnknownFullKeyResolvedContact && (
- We know this sender's full key, but we have not yet heard an advertisement that - fills in their identity details. Those details will appear automatically when an - advertisement arrives. + This sender's profile details (name, location) haven't arrived yet. They + will fill in automatically when the sender's next advertisement is heard.
)} diff --git a/frontend/src/components/ConversationPane.tsx b/frontend/src/components/ConversationPane.tsx index a5d24d0..b2d49b7 100644 --- a/frontend/src/components/ConversationPane.tsx +++ b/frontend/src/components/ConversationPane.tsx @@ -103,17 +103,17 @@ function ContactResolutionBanner({ variant }: { variant: 'unknown-full-key' | 'p if (variant === 'prefix-only') { return (
- We only know a key prefix for this sender, which can happen when a fallback DM arrives - before we learn their full identity. This conversation is read-only until we hear an - advertisement that resolves the full key. + We've received a message from this sender but don't have their full identity yet. + Sending is disabled until their identity is confirmed — this usually happens + automatically when they next advertise.
); } return (
- A full identity profile is not yet available because we have not heard an advertisement from - this sender. The contact will fill in automatically when an advertisement arrives. + This sender's profile details (name, location) haven't arrived yet. They will fill + in automatically when the sender's next advert is heard.
); } diff --git a/frontend/src/components/NewMessageModal.tsx b/frontend/src/components/NewMessageModal.tsx index ae28e44..2914abe 100644 --- a/frontend/src/components/NewMessageModal.tsx +++ b/frontend/src/components/NewMessageModal.tsx @@ -183,11 +183,11 @@ export function NewMessageModal({ permitCapitals ); if (channelNames.length === 0) { - setError('Enter at least one valid room name'); + setError('Enter at least one valid channel name'); return; } if (invalidNames.length > 0) { - setError(`Invalid room names: ${invalidNames.join(', ')}`); + setError(`Invalid channel names: ${invalidNames.join(', ')}`); return; } await onBulkAddHashtagChannels(channelNames, tryHistorical); @@ -249,7 +249,7 @@ export function NewMessageModal({ {tab === 'new-contact' && 'Add a new contact by entering their name and public key'} {tab === 'new-channel' && 'Create a private channel with a shared encryption key'} {tab === 'hashtag' && 'Join a public hashtag channel'} - {tab === 'bulk-hashtag' && 'Paste multiple hashtag rooms to add them in one batch'} + {tab === 'bulk-hashtag' && 'Paste multiple hashtag channels to add them in one batch'} @@ -377,11 +377,11 @@ export function NewMessageModal({ aria-label="Bulk channel names" value={bulkChannelText} onChange={(e) => setBulkChannelText(e.target.value)} - placeholder={'#ops\nmesh-room\nanother-room'} + placeholder={'#ops\nmesh-chat\nanother-channel'} className="min-h-48 w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm outline-none transition-colors placeholder:text-muted-foreground focus-visible:ring-2 focus-visible:ring-ring" />

- Paste room names separated by lines, spaces, or commas. Leading # marks are + Paste channel names separated by lines, spaces, or commas. Leading # marks are stripped automatically.

diff --git a/frontend/src/components/settings/SettingsRadioSection.tsx b/frontend/src/components/settings/SettingsRadioSection.tsx index c3bee72..292edb7 100644 --- a/frontend/src/components/settings/SettingsRadioSection.tsx +++ b/frontend/src/components/settings/SettingsRadioSection.tsx @@ -668,10 +668,10 @@ export function SettingsRadioSection({ variant="outline" className="flex-1" > - {busy && !rebooting ? 'Saving...' : 'Save'} + {busy && !rebooting ? 'Saving...' : 'Save Radio Config'}

@@ -769,7 +769,7 @@ export function SettingsRadioSection({ )} diff --git a/frontend/src/test/bulkAddChannelResultModal.test.tsx b/frontend/src/test/bulkAddChannelResultModal.test.tsx index cee5386..829a3dd 100644 --- a/frontend/src/test/bulkAddChannelResultModal.test.tsx +++ b/frontend/src/test/bulkAddChannelResultModal.test.tsx @@ -43,6 +43,6 @@ describe('BulkAddChannelResultModal', () => { expect(opsLink.getAttribute('href')).toContain('#channel/'); expect(meshLink.getAttribute('href')).toContain('#channel/'); expect(screen.queryByRole('link', { name: /bad_room/i })).toBeNull(); - expect(screen.getByText(/Ignored invalid room names: bad_room/)).toBeTruthy(); + expect(screen.getByText(/Ignored invalid channel names: bad_room/)).toBeTruthy(); }); }); diff --git a/frontend/src/test/conversationPane.test.tsx b/frontend/src/test/conversationPane.test.tsx index 84939b9..d8240cd 100644 --- a/frontend/src/test/conversationPane.test.tsx +++ b/frontend/src/test/conversationPane.test.tsx @@ -379,7 +379,7 @@ describe('ConversationPane', () => { /> ); - expect(screen.getByText(/A full identity profile is not yet available/i)).toBeInTheDocument(); + expect(screen.getByText(/profile details.*haven't arrived yet/i)).toBeInTheDocument(); expect(screen.getByTestId('message-input')).toBeInTheDocument(); }); @@ -416,7 +416,9 @@ describe('ConversationPane', () => { /> ); - expect(screen.getByText(/This conversation is read-only/i)).toBeInTheDocument(); + expect( + screen.getByText(/Sending is disabled until their identity is confirmed/i) + ).toBeInTheDocument(); expect(screen.queryByTestId('message-input')).not.toBeInTheDocument(); }); }); diff --git a/frontend/src/test/newMessageModal.test.tsx b/frontend/src/test/newMessageModal.test.tsx index c655fb0..b6ef18a 100644 --- a/frontend/src/test/newMessageModal.test.tsx +++ b/frontend/src/test/newMessageModal.test.tsx @@ -119,7 +119,7 @@ describe('NewMessageModal form reset', () => { expect(screen.queryByRole('tab', { name: 'Bulk Add Channel' })).toBeNull(); }); - it('opens on the bulk tab when enabled and submits normalized room names', async () => { + it('opens on the bulk tab when enabled and submits normalized channel names', async () => { const user = userEvent.setup(); renderModal(true, { showBulkAddChannelTab: true }); @@ -145,7 +145,7 @@ describe('NewMessageModal form reset', () => { expect(onClose).toHaveBeenCalled(); }); - it('shows invalid bulk room names before submitting', async () => { + it('shows invalid bulk channel names before submitting', async () => { const user = userEvent.setup(); renderModal(true, { showBulkAddChannelTab: true }); @@ -156,7 +156,7 @@ describe('NewMessageModal form reset', () => { await user.click(screen.getByRole('button', { name: 'Add Channels' })); expect(onBulkAddHashtagChannels).not.toHaveBeenCalled(); - expect(screen.getByText('Invalid room names: bad_room')).toBeTruthy(); + expect(screen.getByText('Invalid channel names: bad_room')).toBeTruthy(); }); }); diff --git a/frontend/src/test/settingsModal.test.tsx b/frontend/src/test/settingsModal.test.tsx index f728e26..785ab2a 100644 --- a/frontend/src/test/settingsModal.test.tsx +++ b/frontend/src/test/settingsModal.test.tsx @@ -334,7 +334,7 @@ describe('SettingsModal', () => { fireEvent.change(screen.getByLabelText('Advert Location Source'), { target: { value: 'off' }, }); - fireEvent.click(screen.getByRole('button', { name: 'Save' })); + fireEvent.click(screen.getByRole('button', { name: 'Save Radio Config' })); await waitFor(() => { expect(onSave).toHaveBeenCalledWith( @@ -348,7 +348,7 @@ describe('SettingsModal', () => { openRadioSection(); fireEvent.click(screen.getByLabelText('Extra Direct ACK Transmission')); - fireEvent.click(screen.getByRole('button', { name: 'Save' })); + fireEvent.click(screen.getByRole('button', { name: 'Save Radio Config' })); await waitFor(() => { expect(onSave).toHaveBeenCalledWith(expect.objectContaining({ multi_acks_enabled: true })); @@ -362,8 +362,8 @@ describe('SettingsModal', () => { const maxContactsInput = screen.getByLabelText('Max Contacts on Radio'); fireEvent.change(maxContactsInput, { target: { value: '250' } }); - // Click the "Save Settings" button in the Flood & Advert Control section - const saveButtons = screen.getAllByRole('button', { name: 'Save Settings' }); + // Click the "Save Messaging Settings" button + const saveButtons = screen.getAllByRole('button', { name: 'Save Messaging Settings' }); fireEvent.click(saveButtons[0]); await waitFor(() => { @@ -377,8 +377,8 @@ describe('SettingsModal', () => { }); openRadioSection(); - // Click the "Save Settings" button in the Flood & Advert Control section - const saveButtons = screen.getAllByRole('button', { name: 'Save Settings' }); + // Click the "Save Messaging Settings" button + const saveButtons = screen.getAllByRole('button', { name: 'Save Messaging Settings' }); fireEvent.click(saveButtons[0]); await waitFor(() => { @@ -542,7 +542,7 @@ describe('SettingsModal', () => { }); openRadioSection(); - fireEvent.click(screen.getByRole('button', { name: 'Save & Reboot' })); + fireEvent.click(screen.getByRole('button', { name: 'Save Radio Config & Reboot' })); await waitFor(() => { expect(onSave).toHaveBeenCalledTimes(1); expect(onReboot).toHaveBeenCalledTimes(1);