diff --git a/VERSION.properties b/VERSION.properties
index 2e03e5a2..f326fdfc 100644
--- a/VERSION.properties
+++ b/VERSION.properties
@@ -1,2 +1,2 @@
-client.version=1.2.343
-server.version=1.2.315
+client.version=1.2.344
+server.version=1.2.316
diff --git a/shine-UI/js/pages/chat-view.js b/shine-UI/js/pages/chat-view.js
index 3cddbf49..0cf39353 100644
--- a/shine-UI/js/pages/chat-view.js
+++ b/shine-UI/js/pages/chat-view.js
@@ -837,6 +837,16 @@ export function render({ navigate, route }) {
const wrap = document.createElement('div');
wrap.className = 'chat-wrap dm-chat-wrap';
+ const historyLoader = document.createElement('div');
+ historyLoader.className = 'dm-history-loader';
+ historyLoader.hidden = true;
+ historyLoader.innerHTML = `
+
+
+ Загрузка истории…
+
+ `;
+
const log = document.createElement('div');
log.className = 'messages-log dm-messages-log';
@@ -987,6 +997,11 @@ export function render({ navigate, route }) {
}
};
+ const setHistoryLoadingState = (isLoading) => {
+ historyLoader.hidden = !isLoading;
+ historyLoader.classList.toggle('is-visible', !!isLoading);
+ };
+
const syncComposerLayout = () => {
const height = Number.parseFloat(input?.style.height || '0');
form.classList.toggle('dm-chat-input--multiline', height > 52);
@@ -1325,6 +1340,7 @@ export function render({ navigate, route }) {
if (historyLoading) return;
if (historyBootstrapped && !historyHasMore) return;
historyLoading = true;
+ setHistoryLoadingState(true);
const scrollContainer = boundScrollContainer || log.closest('.screen-content') || wrap.parentElement || wrap;
const prevScrollTop = Number(scrollContainer?.scrollTop || 0);
const prevScrollHeight = Number(scrollContainer?.scrollHeight || 0);
@@ -1359,6 +1375,7 @@ export function render({ navigate, route }) {
});
} finally {
historyLoading = false;
+ setHistoryLoadingState(false);
}
};
@@ -1467,7 +1484,7 @@ export function render({ navigate, route }) {
window.visualViewport?.addEventListener('resize', syncKeyboardUi);
window.addEventListener('resize', syncKeyboardUi);
- wrap.append(log, form);
+ wrap.append(historyLoader, log, form);
screen.append(wrap);
renderLog(log, chatId, {
onOpenActions: handleOpenActions,
diff --git a/shine-UI/styles/components.css b/shine-UI/styles/components.css
index ef597ae9..522b8577 100644
--- a/shine-UI/styles/components.css
+++ b/shine-UI/styles/components.css
@@ -4669,6 +4669,68 @@ html, body { overflow-x: hidden; }
gap: 10px;
}
+.dm-history-loader {
+ position: sticky;
+ top: 0;
+ z-index: 3;
+ display: flex;
+ justify-content: center;
+ pointer-events: none;
+ margin-bottom: -4px;
+ opacity: 0;
+ transform: translateY(-8px);
+ transition: opacity 160ms ease, transform 160ms ease;
+}
+
+.dm-history-loader[hidden] {
+ display: none;
+}
+
+.dm-history-loader.is-visible {
+ opacity: 1;
+ transform: translateY(0);
+}
+
+.dm-history-loader__pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 10px;
+ min-height: 34px;
+ padding: 7px 14px;
+ border-radius: 999px;
+ border: 1px solid rgba(212, 175, 55, 0.24);
+ background: rgba(9, 15, 26, 0.92);
+ color: rgba(245, 226, 179, 0.96);
+ box-shadow: 0 10px 24px rgba(0, 0, 0, 0.28);
+ backdrop-filter: blur(14px);
+ -webkit-backdrop-filter: blur(14px);
+}
+
+.dm-history-loader__label {
+ font-size: 12px;
+ font-weight: 600;
+ letter-spacing: 0.02em;
+}
+
+.dm-history-loader__spinner {
+ width: 16px;
+ height: 16px;
+ border-radius: 50%;
+ border: 2px solid rgba(255, 234, 186, 0.22);
+ border-top-color: rgba(242, 201, 92, 0.96);
+ box-shadow: 0 0 10px rgba(212, 175, 55, 0.18);
+ animation: dm-history-loader-spin 0.85s linear infinite;
+}
+
+@keyframes dm-history-loader-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
.dm-screen .bubble {
max-width: 78%;
padding: 11px 14px;