Interiors with TG (updated) Fix MID

This commit is contained in:
2025-08-26 16:35:03 +03:00
parent 2754eb1e26
commit e5c6f9edc9

View File

@@ -106,6 +106,10 @@ function Game({ avatarUrl, gender }) {
const [activeChat, setActiveChat] = useState(null); const [activeChat, setActiveChat] = useState(null);
// Добавьте этот код в начало компонента Game, рядом с другими состояниями // Добавьте этот код в начало компонента Game, рядом с другими состояниями
const [telegramContacts, setTelegramContacts] = useState([]); const [telegramContacts, setTelegramContacts] = useState([]);
const [tgLoading, setTgLoading] = useState(false);
const [tgError, setTgError] = useState(null);
const [sysTime, setSysTime] = useState(new Date());
const isPhoneNarrow = true; // экран виртуального телефона — всегда узкий
const [isIframeOpen, setIsIframeOpen] = useState(false); const [isIframeOpen, setIsIframeOpen] = useState(false);
const [iframeUrl, setIframeUrl] = useState(''); const [iframeUrl, setIframeUrl] = useState('');
@@ -188,7 +192,9 @@ function Game({ avatarUrl, gender }) {
setAppsHidden(true); setAppsHidden(true);
setActiveApp(appName); setActiveApp(appName);
if (appName === "Telegram") { if (appName === "Telegram") {
loadTelegramContacts(); // Загрузка контактов при открытии setTgError(null);
setTgLoading(true);
loadTelegramContacts().finally(() => setTgLoading(false));
} }
if (appName === "Chrome") { if (appName === "Chrome") {
loadQuestsProgress(); loadQuestsProgress();
@@ -1322,17 +1328,23 @@ function Game({ avatarUrl, gender }) {
async function loadTelegramContacts() { async function loadTelegramContacts() {
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
try { try {
setTgError(null);
const res = await fetch('/api/users', { const res = await fetch('/api/users', {
headers: { Authorization: `Bearer ${token}` } headers: { Authorization: `Bearer ${token}` },
credentials: 'include',
cache: 'no-cache'
}); });
if (res.ok) { if (res.ok) {
const data = await res.json(); const data = await res.json();
setTelegramContacts(data); setTelegramContacts(data);
} else { } else {
console.error('Ошибка загрузки контактов Telegram'); const txt = await res.text().catch(()=> '');
console.error('Ошибка загрузки контактов Telegram', res.status, txt);
setTgError('Не удалось загрузить контакты');
} }
} catch (err) { } catch (err) {
console.error('Ошибка сети:', err); console.error('Ошибка сети:', err);
setTgError('Проблема сети');
} }
} }
@@ -5519,122 +5531,64 @@ useEffect(() => {
)} )}
{activeApp === "Telegram" && ( {activeApp === "Telegram" && (
<div style={{ width: "100%", height: "100%", display: "flex", flexDirection: "column" }}> <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', background: '#fff' }}>
<div style={{ width: "100%", height: "10%", backgroundColor: "#0088cc", display: "flex", alignItems: "center", justifyContent: "center" }}> {/* Заголовок приложения */}
<div style={{ fontSize: "150%", color: "white" }}>Shipgram Messenger</div> <div style={{ padding: '8px 12px', background: '#0088cc', color: '#fff', fontWeight: 700, textAlign: 'center' }}>Shipgram</div>
</div> {/* Контент */}
<div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
<div style={{ width: "100%", height: "90%", display: "flex" }}> {/* Список контактов */}
<div style={{ width: "30%", height: "100%", borderRight: "1px solid #ddd", overflowY: "auto" }}> <div style={{ width: isPhoneNarrow ? (activeChat ? '0%' : '100%') : '30%', display: isPhoneNarrow && activeChat ? 'none' : 'block', borderRight: '1px solid #ddd', overflowY: 'auto', background: '#fff' }}>
<div style={{ padding: "10px", fontWeight: "bold", borderBottom: "1px solid #ddd" }}>Contacts</div> <div style={{ padding: 10, fontWeight: 600, borderBottom: '1px solid #eee' }}>Контакты</div>
<div id="user-list" style={{ overflowY: "auto" }}> {tgLoading && (
{telegramContacts.length === 0 && ( <div style={{ padding: 12, color: '#666' }}>Загрузка</div>
<div style={{ padding: 10, textAlign: "center" }}>
{telegramContacts.length === 0
? "Загрузка контактов..."
: "Контакты не найдены"}
</div>
)} )}
{telegramContacts.map((user, index) => ( {tgError && (
<div <div style={{ padding: 12, color: '#b91c1c' }}>{tgError}</div>
key={index} )}
style={{ {!tgLoading && !tgError && telegramContacts.length === 0 && (
padding: "10px", <div style={{ padding: 12, color: '#666' }}>Контакты не найдены</div>
borderBottom: "1px solid #eee", )}
cursor: "pointer", {telegramContacts.map((user) => (
display: "flex", <div key={user.id} onClick={() => setActiveChat(user)} style={{ padding: '10px 12px', display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer', color: '#111' }}>
alignItems: "center" <div style={{ width: 28, height: 28, borderRadius: 14, background: '#e5e7eb', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12 }}>
}} {user.firstName?.[0]}{user.lastName?.[0]}
onClick={() => setActiveChat(user)} </div>
> <div style={{ overflow: 'hidden' }}>
<div> <div style={{ whiteSpace: 'nowrap', textOverflow: 'ellipsis', overflow: 'hidden' }}>{user.firstName} {user.lastName}</div>
{user.firstName} {user.lastName} <div style={{ fontSize: 12, color: '#6b7280' }}>Онлайн</div>
</div> </div>
</div> </div>
))} ))}
</div> </div>
</div> {/* Область чата */}
<div style={{ width: "70%", height: "100%" }}> <div style={{ flex: 1, display: isPhoneNarrow && !activeChat ? 'none' : 'flex', flexDirection: 'column', background: '#fff' }}>
{activeChat && ( {activeChat && (
<div style={{ padding: "10px" }}> <>
<h3>Чат с {activeChat.firstName} {activeChat.lastName}</h3> <div style={{ padding: '8px 12px', borderBottom: '1px solid #eee', display: 'flex', alignItems: 'center', gap: 8 }}>
{/* Контейнер сообщений с прокруткой */} {isPhoneNarrow && (
<div <button onClick={() => setActiveChat(null)} style={{ border: 'none', background: 'transparent', fontSize: 16, cursor: 'pointer' }}></button>
id="chatContainer" )}
style={{ <span style={{ fontWeight: 600 }}>{activeChat.firstName} {activeChat.lastName}</span>
flex: 1, </div>
border: "1px solid #ddd", <div id="chatContainer" style={{ flex: 1, overflowY: 'auto', padding: 10, background: '#fafafa' }}>
padding: "10px",
overflowY: "auto",
marginBottom: "10px"
}}
>
{messages.length === 0 ? ( {messages.length === 0 ? (
<p style={{ textAlign: 'center', color: '#888' }}>Нет сообщений</p> <p style={{ textAlign: 'center', color: '#666' }}>Нет сообщений</p>
) : ( ) : (
messages.map((msg) => ( messages.map(msg => (
<div <div key={msg.id} style={{ display: 'flex', justifyContent: (msg.sender_id === userProfile?.id) ? 'flex-end' : 'flex-start', margin: '8px 0' }}>
key={msg.id} <div style={{ maxWidth: '75%', background: (msg.sender_id === userProfile?.id) ? '#0084ff' : '#e5e5ea', color: (msg.sender_id === userProfile?.id) ? '#fff' : '#000', padding: '8px 12px', borderRadius: 12 }}>{msg.message}</div>
style={{
textAlign: msg.sender_id === userProfile?.id ? 'right' : 'left',
margin: '10px 0'
}}
>
<div style={{
display: 'inline-block',
padding: '8px 12px',
borderRadius: '12px',
background: msg.sender_id === userProfile?.id ? '#0084ff' : '#e5e5ea',
color: msg.sender_id === userProfile?.id ? '#fff' : '#000',
maxWidth: '80%'
}}>
{msg.message}
</div>
<div style={{
fontSize: '0.8em',
color: '#666',
marginTop: '4px'
}}>
{new Date(msg.created_at).toLocaleTimeString()}
</div>
</div> </div>
)) ))
)} )}
</div> </div>
<div style={{ padding: 8, display: 'flex', gap: 8, borderTop: '1px solid #eee', background: '#fff' }}>
{/* Поле ввода и кнопка отправки */} <input type="text" value={newMessage} onChange={(e) => setNewMessage(e.target.value)} placeholder="Сообщение" onKeyDown={(e) => { if (e.key === 'Enter') sendMessage(); }} style={{ flex: 1, padding: '10px 12px', borderRadius: 12, border: '1px solid #ddd' }} />
<div style={{ display: 'flex' }}> <button onClick={sendMessage} style={{ padding: '10px 14px', background: '#0084ff', color: '#fff', border: 'none', borderRadius: 12, cursor: 'pointer' }}>Отправить</button>
<input
type="text"
value={newMessage}
onChange={(e) => setNewMessage(e.target.value)}
placeholder="Введите сообщение..."
style={{
flex: 1,
padding: '8px',
borderRadius: '20px',
border: '1px solid #ddd'
}}
onKeyDown={(e) => {
if (e.key === 'Enter') sendMessage();
}}
/>
<button
onClick={sendMessage}
style={{
marginLeft: '8px',
padding: '8px 16px',
background: '#0084ff',
color: 'white',
border: 'none',
borderRadius: '20px',
cursor: 'pointer'
}}
>
Отправить
</button>
</div>
</div> </div>
</>
)}
{!activeChat && (
<div style={{ margin: 'auto', color: '#666' }}>Выберите контакт</div>
)} )}
</div> </div>
</div> </div>