From cd802d965e6f43063e06f976a90a7da424d3195c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sun, 20 Sep 2026 13:34:21 +0300 Subject: [PATCH] ui: network-monitor status on its own line + Refresh translation (v2.7.3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The location line in the Phone-tab network monitor grew too long once the status was appended (e.g. "262-01 · Germany · Telekom · Guest (roaming) ⛔ PLMN not allowed"). netStateRender now keeps the identity (mcc-mnc · country · operator) on the first line and renders the status elements (roaming tag + forbidden badge) in a block span on a second line; a location without a status still renders on one line. Also add the missing Russian translation for the monitor's Refresh button (t() fell back to English): 'Refresh': 'Обновить'. - frontend/index.html: two-line location render, LANG_RU Refresh, 2.7.3 - frontend/tests/netstate.test.js: pins the block-span layout and the one-line no-status case - sw.js cache simple-v206; version trio 2.7.3 --- frontend/index.html | 9 ++++++--- frontend/sw.js | 2 +- frontend/tests/netstate.test.js | 13 +++++++++++++ pyproject.toml | 2 +- pysim_simple_server/server.py | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index d6a7047..fbbe4bc 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1414,7 +1414,7 @@ // ===== Version ===== // Single source of truth for the PWA version: shown in the header and used // by the server version check in pysimConnect(). -const SIMPLE_VERSION = '2.7.2'; +const SIMPLE_VERSION = '2.7.3'; document.getElementById('app-version').textContent = 'v' + SIMPLE_VERSION; // ===== Tab switching ===== @@ -12643,11 +12643,13 @@ function netStateRender(state) { const loc = state && state.network ? state.network.location : null; const locEl = document.getElementById('netstate-location'); if (loc) { + const statuses = []; + if (loc.roaming) statuses.push(esc(t(NET_STATE_ROAMING[loc.roaming] || loc.roaming))); + if (loc.rejected) statuses.push('⛔ ' + esc(t('PLMN not allowed')) + ''); let h = '' + esc(loc.mcc + '-' + loc.mnc) + ''; if (loc.country) h += ' · ' + esc(loc.country); if (loc.operator) h += ' · ' + esc(loc.operator); - if (loc.roaming) h += ' · ' + esc(t(NET_STATE_ROAMING[loc.roaming] || loc.roaming)); - if (loc.rejected) h += ' ⛔ ' + esc(t('PLMN not allowed')) + ''; + if (statuses.length) h += '' + statuses.join(' · ') + ''; locEl.innerHTML = h; } else { locEl.innerHTML = ''; @@ -12949,6 +12951,7 @@ const LANG_RU = { 'pySim command line': 'Командная строка pySim', 'Raw APDU': 'Отправка APDU', 'Read': 'Прочитать', + 'Refresh': 'Обновить', 'Save': 'Сохранить', 'Raw': 'Данные как на карте', 'Decoded': 'Декодированные данные', diff --git a/frontend/sw.js b/frontend/sw.js index 16f9323..95b823a 100644 --- a/frontend/sw.js +++ b/frontend/sw.js @@ -1,4 +1,4 @@ -const CACHE = 'simple-v205'; +const CACHE = 'simple-v206'; const URLS = [ 'index.html', 'help.html', diff --git a/frontend/tests/netstate.test.js b/frontend/tests/netstate.test.js index bd01e4e..eb06f83 100644 --- a/frontend/tests/netstate.test.js +++ b/frontend/tests/netstate.test.js @@ -106,12 +106,25 @@ test('netStateRender paints the service badge, location and rows', () => { assert.ok(els['netstate-location'].innerHTML.includes('Germany')); assert.ok(els['netstate-location'].innerHTML.includes('Guest (roaming)')); assert.ok(els['netstate-location'].innerHTML.includes('PLMN not allowed')); + assert.ok(els['netstate-location'].innerHTML.includes( + 'TelekomGuest (roaming) · ⛔ PLMN not allowed')); + assert.ok(!els['netstate-location'].innerHTML.includes('Telekom · ')); assert.strictEqual(els['netstate-area'].textContent, 'LAI 6CD7'); assert.ok(els['netstate-body'].innerHTML.includes('EF.IMSI')); assert.ok(els['netstate-body'].innerHTML.includes('262011234567890')); assert.ok(els['netstate-body'].innerHTML.includes('>write<')); }); +test('netStateRender keeps the location on one line when there is no status', () => { + const els = setup(); + decoder({}); + netStateRender({ service: { state: 'normal' }, files: {}, + network: { location: { mcc: '262', mnc: '01', country: 'Germany', + operator: 'Telekom', area: 'LAI', lac: '6CD7' } } }); + assert.strictEqual(els['netstate-location'].innerHTML, + '262-01 · Germany · Telekom'); +}); + test('netStateRender shows Undefined until something is simulated', () => { const els = setup(); decoder({}); diff --git a/pyproject.toml b/pyproject.toml index 367b22a..3e1df7a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "pysim-simple-server" -version = "2.7.2" +version = "2.7.3" description = "HTTP REST server wrapping pysim for the SIMple PWA" requires-python = ">=3.8" # pysim is a git-only dependency installed explicitly by setup.bat/setup.sh. diff --git a/pysim_simple_server/server.py b/pysim_simple_server/server.py index 87442b2..74e3f2c 100644 --- a/pysim_simple_server/server.py +++ b/pysim_simple_server/server.py @@ -25,7 +25,7 @@ from osmocom.construct import GsmOrUcs2Adapter from osmocom.tlv import BER_TLV_IE -VERSION = '2.7.2' +VERSION = '2.7.3' MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE