diff --git a/VERSION.properties b/VERSION.properties
index 9d5f554..fce437a 100644
--- a/VERSION.properties
+++ b/VERSION.properties
@@ -1,2 +1,2 @@
-client.version=1.2.14
-server.version=1.2.14
+client.version=1.2.15
+server.version=1.2.15
diff --git a/shine-UI/js/pages/network-view.js b/shine-UI/js/pages/network-view.js
index 2083586..7f3cea6 100644
--- a/shine-UI/js/pages/network-view.js
+++ b/shine-UI/js/pages/network-view.js
@@ -513,7 +513,10 @@ export function render({ navigate, route }) {
}
const screen = document.createElement('section');
- screen.className = 'stack network-screen';
+ screen.className = 'network-screen';
+
+ const stage = document.createElement('div');
+ stage.className = 'network-stage';
const board = document.createElement('div');
board.className = 'network-board network-board--full';
@@ -843,6 +846,8 @@ export function render({ navigate, route }) {
}
setBackButtonState(backBtnEl);
- screen.append(header, board);
+ header.classList.add('network-header-overlay');
+ stage.append(board, header);
+ screen.append(stage);
return screen;
}
diff --git a/shine-UI/js/pages/profile-view.js b/shine-UI/js/pages/profile-view.js
index 42b1869..f21ff76 100644
--- a/shine-UI/js/pages/profile-view.js
+++ b/shine-UI/js/pages/profile-view.js
@@ -1,5 +1,4 @@
-import { renderHeader } from '../components/header.js';
-import { profile } from '../mock-data.js';
+import { profile } from '../mock-data.js';
import { state } from '../state.js';
import {
PROFILE_GENDER_FEMALE,
@@ -36,23 +35,20 @@ export function render({ navigate }) {
const screen = document.createElement('section');
screen.className = 'stack profile-screen';
- const status = document.createElement('div');
- status.className = 'status-line';
- status.textContent = 'Загрузка параметров...';
-
- screen.append(
- renderHeader({
- title: '',
- leftAction: { label: 'Изменить профиль', onClick: () => navigate('profile-edit-view') },
- rightActions: [
- { label: 'Кошелёк', onClick: () => navigate('wallet-view') },
- { label: 'Настройки', onClick: () => navigate('settings-view') },
- ],
- }),
- );
+ const topActions = document.createElement('div');
+ topActions.className = 'profile-top-actions';
+ topActions.innerHTML = `
+
+
+
+ `;
+ topActions.querySelector('[data-top-action="edit"]')?.addEventListener('click', () => navigate('profile-edit-view'));
+ topActions.querySelector('[data-top-action="wallet"]')?.addEventListener('click', () => navigate('wallet-view'));
+ topActions.querySelector('[data-top-action="settings"]')?.addEventListener('click', () => navigate('settings-view'));
+ screen.append(topActions);
const card = document.createElement('div');
- card.className = 'card stack';
+ card.className = 'card stack profile-main-card';
const topRow = document.createElement('div');
topRow.className = 'row';
@@ -63,7 +59,13 @@ export function render({ navigate }) {
${String(login || '').trim() || 'unknown'}
-
+ `;
+
+ const statusRow = document.createElement('div');
+ statusRow.className = 'row profile-status-row';
+ statusRow.innerHTML = `
+ Загрузка параметров...
+
`;
const badgesRow = document.createElement('div');
@@ -76,7 +78,8 @@ export function render({ navigate }) {
const listWrap = document.createElement('div');
listWrap.className = 'stack profile-param-list';
- const reloadBtn = topRow.querySelector('[data-reload="true"]');
+ const reloadBtn = statusRow.querySelector('[data-reload="true"]');
+ const statusLineEl = statusRow.querySelector('[data-profile-status-line="true"]');
const officialBtn = badgesRow.querySelector('[data-toggle="official"]');
const shineBtn = badgesRow.querySelector('[data-toggle="shine"]');
const identityEl = topRow.querySelector('[data-profile-identity="true"]');
@@ -150,8 +153,10 @@ export function render({ navigate }) {
async function refreshProfileSnapshot() {
try {
- status.className = 'status-line';
- status.textContent = 'Загрузка параметров...';
+ if (statusLineEl instanceof HTMLElement) {
+ statusLineEl.className = 'status-line';
+ statusLineEl.textContent = 'Загрузка параметров...';
+ }
const snapshot = await loadProfileSnapshot(login);
currentFields = Array.isArray(snapshot.fields) ? snapshot.fields : [];
currentToggles = Array.isArray(snapshot.toggles) ? snapshot.toggles : [];
@@ -161,11 +166,15 @@ export function render({ navigate }) {
updateAvatarUi();
updateTogglesUi();
renderFields(currentFields);
- status.className = 'status-line is-available';
- status.textContent = 'Профиль обновлён.';
+ if (statusLineEl instanceof HTMLElement) {
+ statusLineEl.className = 'status-line is-available';
+ statusLineEl.textContent = 'Профиль обновлён.';
+ }
} catch (error) {
- status.className = 'status-line is-unavailable';
- status.textContent = `Ошибка загрузки профиля: ${error?.message || 'unknown'}`;
+ if (statusLineEl instanceof HTMLElement) {
+ statusLineEl.className = 'status-line is-unavailable';
+ statusLineEl.textContent = `Ошибка загрузки профиля: ${error?.message || 'unknown'}`;
+ }
}
}
@@ -174,13 +183,14 @@ export function render({ navigate }) {
const isEnabled = Boolean(item?.enabled);
if (toggleKey === 'official') {
status.className = 'status-line is-available';
- status.textContent = isEnabled
+ if (statusLineEl instanceof HTMLElement) statusLineEl.className = 'status-line is-available';
+ if (statusLineEl instanceof HTMLElement) statusLineEl.textContent = isEnabled
? 'Аккаунт является официальным.'
: 'Аккаунт не является официальным.';
return;
}
- status.className = 'status-line is-available';
- status.textContent = isEnabled
+ if (statusLineEl instanceof HTMLElement) statusLineEl.className = 'status-line is-available';
+ if (statusLineEl instanceof HTMLElement) statusLineEl.textContent = isEnabled
? 'Аккаунт является сияющим.'
: 'Аккаунт не является сияющим.';
};
@@ -189,7 +199,7 @@ export function render({ navigate }) {
officialBtn?.addEventListener('click', () => showToggleInfo('official'));
shineBtn?.addEventListener('click', () => showToggleInfo('shine'));
- card.append(topRow, badgesRow, status, listWrap);
+ card.append(topRow, badgesRow, statusRow, listWrap);
screen.append(card);
updateAvatarUi();
diff --git a/shine-UI/styles/components.css b/shine-UI/styles/components.css
index b2a6222..d6a446a 100644
--- a/shine-UI/styles/components.css
+++ b/shine-UI/styles/components.css
@@ -1328,14 +1328,45 @@ textarea.input {
}
.network-screen {
- gap: 8px;
- min-height: calc(100dvh - 124px);
+ position: relative;
+ margin: -14px -14px -24px;
+ min-height: calc(100dvh - 74px);
+}
+
+.network-stage {
+ position: relative;
+ height: calc(100dvh - 74px);
}
.network-board--full {
- flex: 1 1 auto;
- min-height: calc(100dvh - 212px);
- height: auto;
+ position: absolute;
+ inset: 0;
+ min-height: 0;
+ height: 100%;
+ border-radius: 0;
+}
+
+.network-header-overlay {
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ right: 8px;
+ margin-bottom: 0;
+ z-index: 3;
+}
+
+.network-header-overlay .page-title {
+ font-size: 17px;
+ text-shadow: 0 1px 8px rgba(0, 0, 0, 0.45);
+}
+
+.network-header-overlay .icon-btn {
+ min-height: 32px;
+ padding: 6px 8px;
+ font-size: 12px;
+ background: rgba(10, 20, 37, 0.6);
+ border-color: rgba(166, 196, 245, 0.32);
+ backdrop-filter: blur(10px);
}
.network-legend {
@@ -3669,6 +3700,7 @@ textarea.input {
background: #05070A;
color: rgba(255, 255, 255, 0.9);
min-height: 100%;
+ gap: 6px;
}
.profile-screen::before {
@@ -3695,6 +3727,45 @@ textarea.input {
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.37);
}
+.profile-top-actions {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 6px;
+}
+
+.profile-top-action-btn {
+ min-height: 30px;
+ padding: 5px 8px;
+ font-size: 12px;
+ text-align: center;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.profile-main-card {
+ padding: 10px;
+ gap: 8px;
+}
+
+.profile-status-row {
+ align-items: center;
+ gap: 8px;
+}
+
+.profile-status-row .status-line {
+ flex: 1 1 auto;
+ min-height: 16px;
+ margin: 0;
+}
+
+.profile-refresh-btn {
+ min-height: 30px;
+ padding: 5px 8px;
+ font-size: 12px;
+ line-height: 1.1;
+}
+
.profile-screen .primary-btn {
background: rgba(212, 175, 55, 0.2);
border: 1px solid rgba(212, 175, 55, 0.45);