Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/scratch-gui/src/containers/connection-modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class ConnectionModal extends React.Component {
PHASES.connected :
(props.extensionId === 'meshV2' ? PHASES.meshV2Initial : PHASES.scanning);
// === Smalruby: End of meshV2 initial step feature ===
// Track whether the user explicitly changed the domain input.
// When false and the user clicks Create/Join, we clear the cached
// domain so createDomain() auto-detects from source IP.
this.userChangedDomain = false;
this.state = {
extension: extensionData.find(ext => ext.extensionId === props.extensionId),
phase: initialPhase,
Expand Down Expand Up @@ -201,6 +205,9 @@ class ConnectionModal extends React.Component {
}
// === Smalruby: Start of meshV2 initial step feature ===
handleMeshV2CreateGroup () {
// If domain input is empty, clear any cached domain from localStorage
// so that createDomain() will be called to auto-detect from source IP
this.clearMeshV2DomainIfEmpty();
// Connect as host using special host ID
this.handleConnecting('meshV2_host');
analytics.event({
Expand All @@ -210,6 +217,9 @@ class ConnectionModal extends React.Component {
});
}
handleMeshV2JoinGroup () {
// If domain input is empty, clear any cached domain from localStorage
// so that createDomain() will be called to auto-detect from source IP
this.clearMeshV2DomainIfEmpty();
// Switch to scanning phase to show group list
this.handleScanning();
analytics.event({
Expand All @@ -218,7 +228,20 @@ class ConnectionModal extends React.Component {
label: this.props.extensionId
});
}
clearMeshV2DomainIfEmpty () {
// If user did not explicitly change the domain input in this modal
// session, clear any cached domain from localStorage so that
// createDomain() will auto-detect from source IP.
if (!this.userChangedDomain) {
const extension = this.props.vm.runtime.peripheralExtensions.meshV2;
if (extension && extension.setDomain) {
extension.setDomain(null);
}
this.props.onDomainChange(null);
}
}
handleMeshV2DomainChange (domain) {
this.userChangedDomain = true;
// Save domain to Redux
this.props.onDomainChange(domain);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,27 @@ describe('ConnectionModal container', () => {
});
});

describe('meshV2 domain handling on modal open', () => {
test('shows meshV2Initial phase when not connected', () => {
const vm = createMockVm({isConnected: false});
const {getByTestId} = renderWithStore(vm, {domain: 'cached-domain'});

// Should show meshV2Initial phase (domain input visible)
expect(getByTestId('phase').textContent).toBe('meshV2Initial');
});

test('preserves cached domain in Redux when modal opens', () => {
const {setDomain} = require('../../../src/reducers/mesh-v2');
setDomain.mockClear();

const vm = createMockVm({isConnected: false});
renderWithStore(vm, {domain: 'cached-domain'});

// Should NOT reset domain on modal open (preserves user's previous input)
expect(setDomain).not.toHaveBeenCalledWith(null);
});
});

describe('handleConnected updates connectedMessage', () => {
test('updates connectedMessage from vm after PERIPHERAL_CONNECTED event', () => {
const vm = createMockVm({
Expand Down
Loading