Update files
This commit is contained in:
parent
5d9892d744
commit
cf953709ff
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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()}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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="Подписки"
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue