Update files

This commit is contained in:
glpshchn 2025-12-04 23:27:45 +03:00
parent 5d9892d744
commit cf953709ff
12 changed files with 93 additions and 33 deletions

View File

@ -55,6 +55,8 @@ const respondWithUser = async (user, res) => {
role: populatedUser.role, role: populatedUser.role,
followersCount: populatedUser.followers.length, followersCount: populatedUser.followers.length,
followingCount: populatedUser.following.length, followingCount: populatedUser.following.length,
followers: populatedUser.followers,
following: populatedUser.following,
referralCode: populatedUser.referralCode, referralCode: populatedUser.referralCode,
referralsCount: populatedUser.referralsCount || 0, referralsCount: populatedUser.referralsCount || 0,
settings, settings,

View File

@ -6,9 +6,10 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
background: var(--bg-secondary); background: var(--bg-secondary);
z-index: 999; /* Выше навигации (50) */ z-index: 10500;
overflow: hidden; overflow: hidden;
/* Убираем touch-action: none чтобы не блокировать клики */ touch-action: none;
overscroll-behavior: contain;
} }
.comments-modal { .comments-modal {

View File

@ -1,4 +1,5 @@
import { useState } from 'react' import { useState } from 'react'
import { createPortal } from 'react-dom'
import { X, Send } from 'lucide-react' import { X, Send } from 'lucide-react'
import { commentPost } from '../utils/api' import { commentPost } from '../utils/api'
import { hapticFeedback } from '../utils/telegram' import { hapticFeedback } from '../utils/telegram'
@ -49,7 +50,7 @@ export default function CommentsModal({ post, onClose, onUpdate }) {
} }
} }
return ( return createPortal(
<div <div
className="comments-modal-overlay" className="comments-modal-overlay"
onMouseDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()}

View File

@ -1,4 +1,5 @@
import { useState, useRef } from 'react' import { useState, useRef } from 'react'
import { createPortal } from 'react-dom'
import { X, Image as ImageIcon, Tag, AtSign } from 'lucide-react' import { X, Image as ImageIcon, Tag, AtSign } from 'lucide-react'
import { createPost, searchUsers } from '../utils/api' import { createPost, searchUsers } from '../utils/api'
import { hapticFeedback } from '../utils/telegram' import { hapticFeedback } from '../utils/telegram'
@ -138,8 +139,13 @@ export default function CreatePostModal({ user, onClose, onPostCreated, initialI
} }
} }
return ( return createPortal(
<div className="modal-overlay" onClick={onClose}> <div
className="modal-overlay"
onMouseDown={(e) => e.stopPropagation()}
onTouchStart={(e) => e.stopPropagation()}
onClick={onClose}
>
<div className="modal-content create-post-modal" onClick={e => e.stopPropagation()}> <div className="modal-content create-post-modal" onClick={e => e.stopPropagation()}>
{/* Хедер */} {/* Хедер */}
<div className="modal-header"> <div className="modal-header">
@ -293,7 +299,8 @@ export default function CreatePostModal({ user, onClose, onPostCreated, initialI
</div> </div>
)} )}
</div> </div>
</div> </div>,
document.body
) )
} }

View File

@ -6,10 +6,12 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
z-index: 10000; z-index: 10500;
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
animation: fadeIn 0.2s ease-out; animation: fadeIn 0.2s ease-out;
touch-action: none;
overscroll-behavior: contain;
} }
@keyframes fadeIn { @keyframes fadeIn {

View File

@ -1,6 +1,7 @@
import { X, UserPlus, UserMinus } from 'lucide-react' import { X, UserPlus, UserMinus } from 'lucide-react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { useState } from 'react' import { useState } from 'react'
import { createPortal } from 'react-dom'
import { followUser, unfollowUser } from '../utils/api' import { followUser, unfollowUser } from '../utils/api'
import { hapticFeedback } from '../utils/telegram' import { hapticFeedback } from '../utils/telegram'
import './FollowListModal.css' import './FollowListModal.css'
@ -56,7 +57,7 @@ export default function FollowListModal({ users, title, onClose, currentUser })
} }
} }
return ( return createPortal(
<div <div
className="follow-list-modal-overlay" className="follow-list-modal-overlay"
onMouseDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()}
@ -130,7 +131,8 @@ export default function FollowListModal({ users, title, onClose, currentUser })
)} )}
</div> </div>
</div> </div>
</div> </div>,
document.body
) )
} }

View File

@ -1,5 +1,6 @@
import { useState } from 'react' import { useState } from 'react'
import { useNavigate } from 'react-router-dom' import { useNavigate } from 'react-router-dom'
import { createPortal } from 'react-dom'
import { Heart, MessageCircle, MoreVertical, ChevronLeft, ChevronRight, Download, Send, X, ZoomIn, Share2 } from 'lucide-react' import { Heart, MessageCircle, MoreVertical, ChevronLeft, ChevronRight, Download, Send, X, ZoomIn, Share2 } from 'lucide-react'
import { likePost, deletePost, sendPhotoToTelegram } from '../utils/api' import { likePost, deletePost, sendPhotoToTelegram } from '../utils/api'
import { hapticFeedback, showConfirm, openTelegramLink } from '../utils/telegram' import { hapticFeedback, showConfirm, openTelegramLink } from '../utils/telegram'
@ -261,8 +262,8 @@ export default function PostCard({ post, currentUser, onUpdate }) {
</button> </button>
</div> </div>
{/* Fullview модал */} {/* Fullview модал через Portal */}
{showFullView && ( {showFullView && createPortal(
<div <div
className="image-fullview" className="image-fullview"
onMouseDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()}
@ -325,20 +326,22 @@ export default function PostCard({ post, currentUser, onUpdate }) {
))} ))}
</div> </div>
)} )}
</div> </div>,
document.body
)} )}
{/* Модалка комментариев */} {/* Модалка комментариев через Portal */}
{showComments && ( {showComments && createPortal(
<CommentsModal <CommentsModal
post={post} post={post}
onClose={() => setShowComments(false)} onClose={() => setShowComments(false)}
onUpdate={onUpdate} onUpdate={onUpdate}
/> />,
document.body
)} )}
{/* Модалка меню */} {/* Модалка меню через Portal */}
{showMenu && ( {showMenu && createPortal(
<PostMenu <PostMenu
post={post} post={post}
currentUser={currentUser} currentUser={currentUser}
@ -347,7 +350,8 @@ export default function PostCard({ post, currentUser, onUpdate }) {
await handleDelete() await handleDelete()
setShowMenu(false) setShowMenu(false)
}} }}
/> />,
document.body
)} )}
</div> </div>
) )

View File

@ -6,12 +6,13 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
background: var(--bg-secondary); background: var(--bg-secondary);
z-index: 999; /* Выше навигации (50) */ z-index: 10500;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 16px; padding: 16px;
overflow: hidden; overflow: hidden;
/* Убираем pointer-events и touch-action чтобы не блокировать клики */ touch-action: none;
overscroll-behavior: contain;
} }
.report-modal-overlay { .report-modal-overlay {
@ -21,10 +22,11 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
background: var(--bg-secondary); background: var(--bg-secondary);
z-index: 9999; z-index: 10600;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
/* Убираем pointer-events и touch-action чтобы не блокировать клики */ touch-action: none;
overscroll-behavior: contain;
} }
.menu-header { .menu-header {

View File

@ -1,5 +1,6 @@
import { X, Trash2, AlertCircle, Flag } from 'lucide-react' import { X, Trash2, AlertCircle, Flag } from 'lucide-react'
import { useState } from 'react' import { useState } from 'react'
import { createPortal } from 'react-dom'
import { reportPost } from '../utils/api' import { reportPost } from '../utils/api'
import { hapticFeedback, showConfirm } from '../utils/telegram' import { hapticFeedback, showConfirm } from '../utils/telegram'
import './PostMenu.css' import './PostMenu.css'
@ -41,8 +42,13 @@ export default function PostMenu({ post, currentUser, onClose, onDelete }) {
} }
} }
return ( return createPortal(
<div className="report-modal-overlay" onClick={handleReportOverlayClick}> <div
className="report-modal-overlay"
onMouseDown={(e) => e.stopPropagation()}
onTouchStart={(e) => e.stopPropagation()}
onClick={handleReportOverlayClick}
>
<div className="report-modal-header" onClick={(e) => e.stopPropagation()}> <div className="report-modal-header" onClick={(e) => e.stopPropagation()}>
<button className="menu-close-btn" onClick={onClose}> <button className="menu-close-btn" onClick={onClose}>
<X size={24} /> <X size={24} />
@ -66,7 +72,8 @@ export default function PostMenu({ post, currentUser, onClose, onDelete }) {
autoFocus autoFocus
/> />
</div> </div>
</div> </div>,
document.body
) )
} }
@ -77,7 +84,7 @@ export default function PostMenu({ post, currentUser, onClose, onDelete }) {
} }
} }
return ( return createPortal(
<div <div
className="post-menu-overlay" className="post-menu-overlay"
onMouseDown={(e) => e.stopPropagation()} onMouseDown={(e) => e.stopPropagation()}
@ -110,7 +117,8 @@ export default function PostMenu({ post, currentUser, onClose, onDelete }) {
<span>Отмена</span> <span>Отмена</span>
</button> </button>
</div> </div>
</div> </div>,
document.body
) )
} }

View File

@ -396,7 +396,7 @@ export default function Profile({ user, setUser }) {
)} )}
{/* Модалка подписчиков */} {/* Модалка подписчиков */}
{showFollowers && ( {showFollowers && user && (
<FollowListModal <FollowListModal
users={user.followers || []} users={user.followers || []}
title="Подписчики" title="Подписчики"
@ -406,7 +406,7 @@ export default function Profile({ user, setUser }) {
)} )}
{/* Модалка подписок */} {/* Модалка подписок */}
{showFollowing && ( {showFollowing && user && (
<FollowListModal <FollowListModal
users={user.following || []} users={user.following || []}
title="Подписки" title="Подписки"

View File

@ -310,6 +310,17 @@
/* Просмотрщик изображений */ /* Просмотрщик изображений */
.image-viewer { .image-viewer {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.95);
z-index: 10500;
display: flex;
flex-direction: column;
touch-action: none;
overscroll-behavior: contain;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;

View File

@ -1,4 +1,5 @@
import { useState, useEffect, useRef } from 'react' import { useState, useEffect, useRef } from 'react'
import { createPortal } from 'react-dom'
import { Search as SearchIcon, ChevronLeft, ChevronRight, Download, X, Plus } from 'lucide-react' import { Search as SearchIcon, ChevronLeft, ChevronRight, Download, X, Plus } from 'lucide-react'
import { searchFurry, searchAnime, getFurryTags, getAnimeTags } from '../utils/api' import { searchFurry, searchAnime, getFurryTags, getAnimeTags } from '../utils/api'
import { hapticFeedback, getTelegramUser } from '../utils/telegram' import { hapticFeedback, getTelegramUser } from '../utils/telegram'
@ -463,9 +464,13 @@ const isVideoUrl = (url = '') => {
)} )}
</div> </div>
{/* Просмотрщик изображений */} {/* Просмотрщик изображений через Portal */}
{showViewer && results[currentIndex] && ( {showViewer && results[currentIndex] && createPortal(
<div className="image-viewer"> <div
className="image-viewer"
onMouseDown={(e) => e.stopPropagation()}
onTouchStart={(e) => e.stopPropagation()}
>
<div className="viewer-header"> <div className="viewer-header">
<button className="viewer-btn" onClick={() => setShowViewer(false)}> <button className="viewer-btn" onClick={() => setShowViewer(false)}>
<X size={24} /> <X size={24} />
@ -488,6 +493,7 @@ const isVideoUrl = (url = '') => {
onTouchStart={handleTouchStart} onTouchStart={handleTouchStart}
onTouchMove={handleTouchMove} onTouchMove={handleTouchMove}
onTouchEnd={handleTouchEnd} onTouchEnd={handleTouchEnd}
onClick={(e) => e.stopPropagation()}
> >
{isVideoUrl(results[currentIndex].url) ? ( {isVideoUrl(results[currentIndex].url) ? (
<video <video
@ -546,7 +552,21 @@ const isVideoUrl = (url = '') => {
<span>Source: {results[currentIndex].source}</span> <span>Source: {results[currentIndex].source}</span>
</div> </div>
</div> </div>
</div> </div>,
document.body
)}
{/* Модалка создания поста */}
{showCreatePost && (
<CreatePostModal
user={user}
onClose={() => setShowCreatePost(false)}
onPostCreated={() => {
setShowCreatePost(false)
setShowViewer(false)
}}
initialImage={results[currentIndex]?.url}
/>
)} )}
</div> </div>
) )