Compare commits

...

2 Commits

Author SHA1 Message Date
c9b4ec26fd video elements shift fix 2025-04-08 14:15:26 +03:00
f7d99ee5fc Videos page new design 2025-04-08 14:12:38 +03:00
8 changed files with 396 additions and 173 deletions

105
app.py
View File

@ -40,7 +40,7 @@ app.config.from_object(Config)
db.init_app(app)
bcrypt.init_app(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_view = 'auth.login'
@login_manager.user_loader
def load_user(user_id):
@ -114,8 +114,6 @@ def vote_art(image_id):
return redirect(url_for('view', content_type='art', id=image_id))
@app.route('/view/<content_type>/<int:id>', methods=['GET', 'POST'])
@app.route('/view/<content_type>/<int:id>', methods=['GET', 'POST'])
def view(content_type, id):
comments = []
@ -131,6 +129,13 @@ def view(content_type, id):
content = Image.query.get_or_404(id)
comments = Comments.query.filter_by(image_id=id).order_by(Comments.comment_date.desc()).all()
if current_user.is_authenticated:
existing_view = Views.query.filter_by(image_id=id, username=current_user.username).first()
if not existing_view:
new_view = Views(image_id=id, username=current_user.username)
db.session.add(new_view)
db.session.commit()
search_query = request.args.get('search')
page = request.args.get('page', 1, type=int)
subscriptions = []
@ -157,6 +162,13 @@ def view(content_type, id):
content = Video.query.get_or_404(id)
comments = Comments.query.filter_by(video_id=id).order_by(Comments.comment_date.desc()).all()
if current_user.is_authenticated:
existing_view = Views.query.filter_by(video_id=id, username=current_user.username).first()
if not existing_view:
new_view = Views(video_id=id, username=current_user.username)
db.session.add(new_view)
db.session.commit()
all_videos = Video.query.order_by(Video.id).all()
video_ids = [video.id for video in all_videos]
current_index = video_ids.index(id)
@ -172,6 +184,13 @@ def view(content_type, id):
content = Comic.query.get_or_404(id)
comments = Comments.query.filter_by(comic_id=id).order_by(Comments.comment_date.desc()).all()
if current_user.is_authenticated:
existing_view = Views.query.filter_by(image_id=id, username=current_user.username).first()
if not existing_view:
new_view = Views(image_id=id, username=current_user.username)
db.session.add(new_view)
db.session.commit()
comic_pages = ComicPage.query.filter_by(comic_id=id).order_by(ComicPage.page_number).all()
if not comic_pages:
@ -286,8 +305,7 @@ def image_edit(id):
@app.route('/video_edit/<int:id>', methods=['GET', 'POST'])
@login_required
def video_edit(id):
async def video_edit(id):
video = Video.query.get_or_404(id)
if video.username != current_user.username:
@ -301,7 +319,6 @@ def video_edit(id):
form.tags.data = video.tags
if form.validate_on_submit():
video.video_name = form.video_name.data
video.description = form.description.data
video.tags = form.tags.data
@ -310,10 +327,15 @@ def video_edit(id):
thumbnail_file = form.video_thumbnail.data
if allowed_file(thumbnail_file.filename, app.config['ALLOWED_IMAGE_EXTENSIONS']):
thumbnail_filename = generate_unique_filename(thumbnail_file.filename, app.config['UPLOAD_FOLDER']['thumbnails'])
thumbnail_filename = await generate_unique_filename(
app.config['UPLOAD_FOLDER']['thumbnails'], 'webp'
)
thumbnail_path = os.path.join(app.config['UPLOAD_FOLDER']['thumbnails'], thumbnail_filename)
thumbnail_file.save(thumbnail_path)
webp_thumbnail = await convert_to_webp(thumbnail_file)
async with aiofiles.open(thumbnail_path, 'wb') as f:
await f.write(webp_thumbnail.read())
video.video_thumbnail_file = thumbnail_filename
db.session.commit()
@ -476,6 +498,40 @@ def videos():
query = get_content_query(Video, subscriptions, search_query)
pagination = query.paginate(page=page, per_page=10, error_out=False)
videos_with_views = []
for video in pagination.items:
views_count = db.session.query(func.count(Views.id)).filter(Views.video_id == video.id).scalar()
videos_with_views.append({
'video': video,
'views_count': views_count
})
popular_videos = [
{
'video': video[0],
'views_count': video[1]
}
for video in db.session.query(Video, func.count(Views.id).label('views_count'))
.outerjoin(Views, Views.video_id == Video.id)
.group_by(Video.id)
.order_by(func.count(Views.id).desc(), Video.cookie_votes.desc())
.limit(8)
.all()
]
most_viewed_videos = [
{
'video': video[0],
'views_count': video[1]
}
for video in db.session.query(Video, func.count(Views.id).label('views_count'))
.outerjoin(Views, Views.video_id == Video.id)
.group_by(Video.id)
.order_by(func.count(Views.id).desc())
.limit(8)
.all()
]
videos_tags = [video.tags for video in Video.query.all() if video.tags]
all_tags = [tag.strip() for tags in videos_tags for tag in tags.split(',')]
sorted_tags = sorted(set(all_tags))
@ -487,12 +543,14 @@ def videos():
return render_template(
'videos.html',
videos=pagination.items,
videos=videos_with_views,
pagination=pagination,
user_cookies=user_cookies,
search_query=search_query,
content_type='video',
tags=sorted_tags
tags=sorted_tags,
popular_videos=popular_videos,
most_viewed_videos=most_viewed_videos
)
@ -889,33 +947,6 @@ def terms_of_use():
def publication_rules():
return render_template('publication_rules.html')
@app.route('/shop')
@login_required
def shop():
items = Item.query.filter_by(visible=True).all()
user_cookies = Cookies.query.filter_by(username=current_user.username).first().cookies if Cookies.query.filter_by(username=current_user.username).first() else 0
user_item_ids = {ui.item_id for ui in UserItem.query.filter_by(username=current_user.username).all()}
return render_template('shop.html', items=items, user=current_user, user_cookies=user_cookies, user_item_ids=user_item_ids)
@app.route('/buy_item/<int:item_id>', methods=['POST'])
@login_required
def buy_item(item_id):
username = current_user.username
user_cookies = Cookies.query.filter_by(username=username).first()
item = Item.query.get(item_id)
if not user_cookies or not item or not item.visible or user_cookies.cookies < item.price:
return redirect(url_for('shop'))
if UserItem.query.filter_by(username=username, item_id=item.id).first():
return redirect(url_for('shop'))
user_cookies.cookies -= item.price
db.session.add(UserItem(username=username, item_id=item.id))
db.session.commit()
return redirect(url_for('shop'))
if __name__ == '__main__':
with app.app_context():
db.create_all()

View File

@ -1,12 +1,14 @@
$dark-violet: #0D0C1C;
$violet: #3c3882;
$violet: #3C3882;
$light-violet: #8784C9;
@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&family=Playwrite+IT+Moderna:wght@100..400&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
body {
background-color: #05040A;
font-family: Nunito, sans-serif;
}
.container {
position: absolute;
display: flex;
@ -31,6 +33,7 @@ body{
padding: 0;
box-sizing: border-box;
}
.img-new-content {
width: 1502px;
height: 423px;
@ -54,9 +57,11 @@ body{
gap: 20px;
width: 1502px;
height: 631px;
left: 209px;
position: absolute;
top: 653px;
left: 50%;
transform: translateX(-50%);
position: absolute;
box-sizing: border-box;
}
.img-popular-content {
@ -80,10 +85,13 @@ body{
gap: 20px;
width: 1502px;
height: 631px;
left: 209px;
position: absolute;
top: 1340px;
left: 50%;
transform: translateX(-50%);
position: absolute;
box-sizing: border-box;
}
.img-viewed-content {
display: flex;
flex-direction: column;
@ -97,7 +105,6 @@ body{
top: 1617px;
}
.popular-categories {
display: flex;
justify-content: space-between;
@ -108,9 +115,11 @@ body{
box-sizing: border-box;
position: absolute;
top: 2095px;
left: 210px;
left: 50%;
transform: translateX(-50%);
gap: 20px;
}
.img-popular-categories {
display: flex;
justify-content: space-between;
@ -196,7 +205,7 @@ body{
}
.view-more-button:hover {
background-color: #3C3882;
background-color: $violet;
transition: background-color 0.3s ease, color 0.3s ease;
}
@ -229,14 +238,13 @@ body{
}
.img-view-more-button:hover {
background-color: #3C3882;
background-color: $violet;
transition: background-color 0.3s ease, color 0.3s ease;
}
.img-view-more-button:hover .new-context-button-text {
color: $light-violet;
transition: color 0.3s ease;
}
.new-context-button-text {
@ -246,9 +254,11 @@ body{
font-size: 16px;
line-height: 100%;
letter-spacing: 0%;
color: #3C3882;
color: $violet;
}
/* navbar */
.navbar {
width: 100%;
max-width: 1500px;
@ -259,16 +269,19 @@ body{
padding: 0 20px;
gap: 20px;
}
.navbar-wrapper {
width: 100%;
background: $dark-violet;
display: flex;
justify-content: center;
}
.logo {
width: 307px;
height: 60px;
}
.search-container {
display: flex;
align-items: center;
@ -281,12 +294,14 @@ body{
position: relative;
transition: border-color 0.3s ease;
}
.search-icon-container {
position: relative;
width: 24px;
height: 24px;
margin-right: 10px;
}
.search-icon,
.search-hover-icon {
width: 24px;
@ -296,9 +311,11 @@ body{
left: 0;
transition: opacity 0.3s ease;
}
.search-hover-icon {
opacity: 0;
}
.search-container:hover .search-hover-icon,
.search-container:focus-within .search-hover-icon {
opacity: 1;
@ -320,11 +337,11 @@ body{
}
.search-container:hover {
border-color: #3C3882;
border-color: $violet;
}
.search-container:focus-within {
border-color: #3C3882;
border-color: $violet;
}
.icon-container {
@ -338,11 +355,13 @@ body{
height: 24px;
margin-left: 10px;
}
.tray-icon {
width: 11px;
height: 7px;
margin-left: 5px;
}
.translate-btn {
position: relative;
width: 23px;
@ -357,6 +376,7 @@ body{
padding: 15px;
transition: border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
}
.translate-icon,
.translate-hover-icon {
width: 24px;
@ -367,9 +387,11 @@ body{
transform: translate(-50%, -50%);
transition: opacity 0.3s ease;
}
.translate-hover-icon {
opacity: 0;
}
.translate-btn:hover .translate-hover-icon {
opacity: 1;
}
@ -377,9 +399,11 @@ body{
.translate-btn:hover .translate-icon {
opacity: 0;
}
.translate-btn:hover {
border-color: #3C3882;
border-color: $violet;
}
.overlay-icon {
position: absolute;
top: 50%;
@ -389,6 +413,7 @@ body{
height: 20px;
opacity: 0.7;
}
.menu {
display: flex;
gap: 22px;
@ -398,25 +423,30 @@ body{
padding-left: 60px;
padding-right: 60px;
}
.menu a {
text-decoration: none;
color: $light-violet;
font-size: 16px;
transition: color 0.3s ease;
}
.menu a:hover {
color: #3C3882;
color: $violet;
}
.auth-container {
display: flex;
align-items: center;
margin-left: auto;
}
.discord-icon-container {
position: relative;
width: 42px;
height: 42px;
}
.discord-icon,
.discord-hover-icon {
width: 42px;
@ -426,15 +456,19 @@ body{
left: 0;
transition: opacity 0.3s ease;
}
.discord-hover-icon {
opacity: 0;
}
.discord-icon-container:hover .discord-hover-icon {
opacity: 1;
}
.discord-icon-container:hover .discord-icon {
opacity: 0;
}
.login-btn {
width: 87px;
height: 42px;
@ -451,17 +485,19 @@ body{
margin-left: 10px;
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.login-btn:hover {
background-color: #3C3882;
background-color: $violet;
color: $dark-violet;
border-color: #3C3882;
border-color: $violet;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: $dark-violet;
border: 1px solid #3C3882;
border: 1px solid $violet;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: none;
@ -469,6 +505,7 @@ flex-direction: column;
width: 150px;
z-index: 10;
}
.dropdown-item {
padding: 10px 15px;
font-size: 14px;
@ -477,16 +514,21 @@ color: $light-violet;
cursor: pointer;
transition: background 0.3s ease, color 0.3s ease;
}
.dropdown-item:hover {
background: #3C3882;
background: $violet;
color: white;
}
/* tags-list */
.tags-container {
width: 1500px;
height: 35px;
position: absolute;
top: 192px;
left: 210px;
left: 50%;
transform: translateX(-50%);
display: flex;
justify-content: flex-start;
align-items: center;
@ -509,7 +551,7 @@ color: white;
display: inline-flex;
align-items: center;
justify-content: center;
background-color: #3C3882;
background-color: $violet;
border: none;
color: $light-violet;
margin: 0;
@ -527,7 +569,7 @@ color: white;
justify-content: center;
border: 2px solid $light-violet;
background-color: transparent;
color: #3C3882;
color: $violet;
margin-left: 10px;
gap: 5px;
position: relative;
@ -541,6 +583,9 @@ color: white;
right: 0;
background: linear-gradient(to right, rgba(5, 4, 10, 0) 30%, rgba(5, 4, 10, 0.5) 60%, #05040A 100%);
}
/* cards */
.img-cards-grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
@ -549,6 +594,7 @@ color: white;
height: 708px;
margin-top: 60px;
}
.img-card {
width: 225px;
height: 344px;
@ -556,6 +602,7 @@ color: white;
flex-direction: column;
gap: 5px;
}
.img-card-cover {
width: 100%;
height: 280px;
@ -577,12 +624,35 @@ color: white;
display: flex;
flex-direction: column;
gap: 5px;
overflow: hidden;
}
.card-cover {
width: 100%;
height: 180px;
background: #1D1C2E;
position: relative;
overflow: hidden;
}
.card-cover img {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
.card-cover video.preview-video {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
display: none;
z-index: 1;
}
.card-info {
@ -614,6 +684,7 @@ color: white;
font-size: 14px;
color: $light-violet;
}
.img-small-cards-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
@ -621,11 +692,14 @@ color: white;
width: 100%;
margin-top: 60px;
}
.img-small-card-cover {
width: 189px;
height: 250px;
background: #1D1C2E;
}
.img-small-card {
width: 189px;
height: 314px;
@ -633,6 +707,7 @@ color: white;
flex-direction: column;
gap: 5px;
}
.small-cards-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
@ -647,12 +722,35 @@ color: white;
display: flex;
flex-direction: column;
gap: 5px;
overflow: hidden;
}
.small-card-cover {
width: 100%;
height: 163px;
background: #1D1C2E;
position: relative;
overflow: hidden;
}
.small-card-cover img {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
.small-card-cover video.preview-video {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
display: none;
z-index: 1;
}
.small-card-info {
@ -684,6 +782,7 @@ color: white;
font-size: 14px;
color: $light-violet;
}
.pc-card {
width: 233px;
height: 164px;
@ -724,7 +823,7 @@ color: white;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
color: #3C3882;
color: $violet;
text-align: right;
position: relative;
right: 5px;
@ -794,7 +893,7 @@ color: white;
width: 276px;
height: 40px;
border-radius: 10px;
background-color: #3C3882;
background-color: $violet;
color: white;
border: none;
cursor: pointer;
@ -813,6 +912,9 @@ color: white;
letter-spacing: 0%;
white-space: nowrap;
}
/* pagination */
.pagination-container {
width: 626px;
height: 50px;

View File

@ -0,0 +1,8 @@
document.addEventListener("DOMContentLoaded", () => {
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
document.body.style.paddingRight = `${scrollbarWidth}px`;
const navbarHeight = document.querySelector('.navbar').offsetHeight;
document.documentElement.style.scrollPaddingTop = `${navbarHeight}px`;
});

64
static/js/hoverPreview.js Normal file
View File

@ -0,0 +1,64 @@
document.addEventListener('DOMContentLoaded', () => {
const cardCovers = document.querySelectorAll('.small-card-cover, .card-cover');
cardCovers.forEach(cardCover => {
const thumbnail = cardCover.querySelector('.thumbnail');
const video = cardCover.querySelector('.preview-video');
const videoSource = video.querySelector('source');
let hoverTimeout;
cardCover.addEventListener('mouseenter', () => {
hoverTimeout = setTimeout(() => {
if (!videoSource.src) {
videoSource.src = video.dataset.src;
video.load();
}
thumbnail.style.display = 'none';
video.style.display = 'block';
video.addEventListener('loadedmetadata', () => {
if (video.duration > 15) {
video.currentTime = 10;
const loopSegment = () => {
if (video.currentTime >= 15) {
video.currentTime = 10;
video.play();
}
};
video.addEventListener('timeupdate', loopSegment);
cardCover.loopSegment = loopSegment;
} else {
video.currentTime = 0;
const loopEntireVideo = () => {
if (video.currentTime >= video.duration) {
video.currentTime = 0;
video.play();
}
};
video.addEventListener('timeupdate', loopEntireVideo);
cardCover.loopSegment = loopEntireVideo;
}
video.play();
});
}, 2000);
});
cardCover.addEventListener('mouseleave', () => {
clearTimeout(hoverTimeout);
video.pause();
video.style.display = 'none';
thumbnail.style.display = 'block';
if (cardCover.loopSegment) {
video.removeEventListener('timeupdate', cardCover.loopSegment);
delete cardCover.loopSegment;
}
});
});
});

View File

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Navbar</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
</head>
<body>
@ -46,7 +45,7 @@
<img src="{{ url_for('static', filename='navbar/discord-hover.svg') }}" alt="Discord Hover"
class="discord-hover-icon">
</div>
<button class="login-btn">ВОЙТИ</button>
<a href="{{ url_for('auth.login') }}"><button class="login-btn">ВОЙТИ</button></a>
</div>
</div>
</div>

View File

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Subnav</title>
<style>
body {
margin: 0;

View File

@ -5,7 +5,6 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tags List</title>
<body>
<div class="tags-container">
{% for tag in tags %}

View File

@ -10,24 +10,30 @@
<div class="container new-content">
<a class="new-content-text">НОВИНКИ</a>
<div class="small-cards-grid">
{% for i in range(5) %}
{% for video_data in videos[:5] %}
<div class="small-card">
<div class="small-card-cover"></div>
<div class="small-card-cover">
<img src="{{ url_for('static', filename='thumbnails/' + video_data.video.video_thumbnail_file) }}" alt="Thumbnail" class="thumbnail">
<video class="preview-video" muted preload="none" data-src="{{ url_for('static', filename='videos/' + video_data.video.video_file) }}">
<source type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<div class="small-card-info">
<div class="small-card-header">
<span class="small-card-text">Totoka</span>
<span class="small-card-text">{{ video_data.video.username }}</span>
<div class="small-card-stats">
<div class="small-stat">
<img src="{{ url_for('static', filename='card/like-icon.svg') }}" alt="Лайк" width="20" height="20">
<span class="small-card-text">134</span>
<span class="small-card-text">{{ video_data.video.cookie_votes }}</span>
</div>
<div class="small-stat">
<img src="{{ url_for('static', filename='card/views-icon.svg') }}" alt="Просмотры" width="20" height="20">
<span class="small-card-text">32113</span>
<span class="small-card-text">{{ video_data.views_count }}</span>
</div>
</div>
</div>
<p class="small-card-text">Big Brother Keep Hugging Me 4</p>
<p class="small-card-text">{{ video_data.video.video_name }}</p>
</div>
</div>
{% endfor %}
@ -37,51 +43,64 @@
<div class="container popular-content">
<a class="popular-content-text">ПОПУЛЯРНОЕ</a>
<div class="cards-grid">
{% for i in range(8) %}
{% for video_data in popular_videos[:8] %}
<div class="card">
<div class="card-cover"></div>
<div class="card-cover">
<img src="{{ url_for('static', filename='thumbnails/' + video_data.video.video_thumbnail_file) }}" alt="Thumbnail" class="thumbnail">
<video class="preview-video" muted preload="none" data-src="{{ url_for('static', filename='videos/' + video_data.video.video_file) }}">
<source type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<div class="card-info">
<div class="card-header">
<span class="card-title" style="color: #3C3882;">Totoka</span>
<span class="card-title" style="color: #3C3882;">{{ video_data.video.username }}</span>
<div class="card-stats">
<div class="stat">
<img src="{{ url_for('static', filename='card/like-icon.svg') }}" alt="Лайк" width="20" height="20">
<span style="color: #8784C9;">134</span>
<span style="color: #8784C9;">{{ video_data.video.cookie_votes }}</span>
</div>
<div class="stat">
<img src="{{ url_for('static', filename='card/views-icon.svg') }}" alt="Просмотры" width="20" height="20">
<span style="color: #8784C9;">32113</span>
<span style="color: #8784C9;">{{ video_data.views_count }}</span>
</div>
</div>
</div>
<p class="card-text" style="font-family: Nunito, sans-serif;">Big Brother Keep Hugging Me 4</p>
<p class="card-text" style="font-family: Nunito, sans-serif;">{{ video_data.video.video_name }}</p>
</div>
</div>
{% endfor %}
</div>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
<div class="container viewed-content">
<a class="viewed-content-text">ПРОСМАТРИВАЕМОЕ</a>
<div class="cards-grid">
{% for i in range(8) %}
{% for video_data in most_viewed_videos[:8] %}
<div class="card">
<div class="card-cover"></div>
<div class="card-cover">
<img src="{{ url_for('static', filename='thumbnails/' + video_data.video.video_thumbnail_file) }}" alt="Thumbnail" class="thumbnail">
<video class="preview-video" muted preload="none" data-src="{{ url_for('static', filename='videos/' + video_data.video.video_file) }}">
<source type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<div class="card-info">
<div class="card-header">
<span class="card-title" style="color: #3C3882;">Totoka</span>
<span class="card-title" style="color: #3C3882;">{{ video_data.video.username }}</span>
<div class="card-stats">
<div class="stat">
<img src="{{ url_for('static', filename='card/like-icon.svg') }}" alt="Лайк" width="20" height="20">
<span style="color: #8784C9;">134</span>
<span style="color: #8784C9;">{{ video_data.video.cookie_votes }}</span>
</div>
<div class="stat">
<img src="{{ url_for('static', filename='card/views-icon.svg') }}" alt="Просмотры" width="20" height="20">
<span style="color: #8784C9;">32113</span>
<span style="color: #8784C9;">{{ video_data.views_count }}</span>
</div>
</div>
</div>
<p class="card-text" style="font-family: Nunito, sans-serif;">Big Brother Keep Hugging Me 4</p>
<p class="card-text" style="font-family: Nunito, sans-serif;">{{ video_data.video.video_name }}</p>
</div>
</div>
{% endfor %}
@ -104,5 +123,7 @@
{% endfor %}
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
<script src="{{ url_for('static', filename='js/hoverPreview.js') }}"></script>
<script src="{{ url_for('static', filename='js/adjustScrollbar.js') }}"></script>
</body>
</html>