Update delete mutation to use affected_subscriptions from API response.
Show contextual success notification with subscription count.
Add deleteSuccessWithSubscriptions translation key in all 4 locales.
Move the empty apps check before the subscription check so that
an empty or unconfigured appConfig shows "not configured" instead
of the misleading "no subscription" message.
Show different messages depending on user role:
- Regular users see a friendly "check back later" message
- Admins see a prompt with a link to /admin/apps settings
Back button was showing on all non-root routes including top-level
pages reachable from the bottom navigation menu (subscription, balance,
referral, support, wheel). These pages don't need a back button since
users navigate between them via the bottom tab bar.
The hook checked closeOthersSignal > 0 which only skipped signal=0.
After first payment, signal stays at 1+ forever causing TopUpAmount
to immediately navigate away on every mount. Now tracks the signal
value at mount time and only reacts to changes after mount.
Replace raw preformatted text with rendered markdown:
headers, bold, links, lists, inline code. Sanitized
with DOMPurify. Styled with Tailwind child selectors.
Show connected devices in subscription tab with ability to:
- View device platform, model, HWID and connection date
- Delete individual devices
- Reset all devices at once
OGL renderer.setSize() sets both the internal buffer and CSS dimensions,
so the 10% resolution canvas was only covering 10% of the screen.
Now explicitly reset canvas.style.width/height to 100% after setSize()
so the small buffer is upscaled by the browser to full viewport.
- Render WebGL canvas at 10% viewport resolution (~20K px vs 2M px)
- Replace backdrop-filter: blur(80px) with filter: blur(20px) on canvas
(backdrop-filter composites ALL layers underneath — 10-20x more expensive)
- Disable antialiasing (useless when output is blurred)
- Lower target FPS from 30 to 20 (imperceptible for ambient background)
- Add CSS contain: strict to isolate layout/paint recalculations
- Remove separate blur overlay div (one element instead of two)
Reported: GTX 1660S showed 30-55% GPU load with cabinet open.
Expected: ~1-5% GPU after this change.
Logo images were exposing the backend API URL in the DOM via <img src>.
Now preloadLogo() fetches the image as a blob and serves it through
URL.createObjectURL(), so only blob: URLs appear in the page source.
Blob is invalidated on logo upload/delete.
Telegram Mini App creates a new WebView on each open, clearing
sessionStorage. Combined with 24h auth_date validation on backend,
returning users couldn't re-authenticate after closing the app.
- Move refresh token to localStorage for persistence across sessions
- Keep access token in sessionStorage (short-lived, OK to lose)
- Fix auth store initialize() to recover when access token is missing
but refresh token exists in localStorage
- Remove separate mountThemeParams() call to fix ConcurrentCallError
(mountMiniApp() handles it internally in SDK v3)
- Update token migration logic for new storage strategy
- Add CountryFilter dropdown with flag emoji + node count per country
- Country filter merges with node filter for both table and CSV export
- Pass total/node GB/day thresholds to backend for risk columns in CSV
- CSV now includes Risk Level, Risk Ratio, Risk GB/day when thresholds set
Expand invisible touch area from 4px to 20px for comfortable finger
interaction on iPhone. Visual indicator stays thin (4px) inside the
wider hit zone. Use inline touchAction: none to prevent scroll conflict.
- RiskBadge now shows real daily GB/d value + mini progress bar
- Node cells show daily rate subtitle when threshold is active
- Total column shows daily rate subtitle when threshold is active
- getCompositeRisk returns both ratio and dominant GB/d value
- formatGbPerDay helper for clean number formatting