static rfiles and design changes

This commit is contained in:
aneuhmanh 2025-03-10 22:45:16 +02:00
parent db675ccf36
commit b3dc06e438
17 changed files with 1075 additions and 1413 deletions

2
.gitignore vendored
View File

@ -8,4 +8,6 @@
/static/videos/
/venv/
/__pycache__/
static/css/*.css
static/css/*.css.map
.env

45
app.py
View File

@ -212,6 +212,37 @@ def view(content_type, id):
comic_pages=comic_pages if content_type == 'comic' else None
)
@app.route('/images')
def drawings():
return render_template(
'images.html'
)
@app.route('/tags_list/<page_type>')
def tags_list(page_type):
comics_tags = [comic.tags for comic in Comic.query.all() if comic.tags]
images_tags = [image.tags for image in Image.query.all() if image.tags]
videos_tags = [video.tags for video in Video.query.all() if video.tags]
if page_type == 'video':
all_tags = [tag.strip() for tags in videos_tags for tag in tags.split(',')]
elif page_type == 'comic':
all_tags = [tag.strip() for tags in comics_tags for tag in tags.split(',')]
elif page_type == 'image':
all_tags = [tag.strip() for tags in images_tags for tag in tags.split(',')]
else:
all_tags = set(tag.strip() for tags in (comics_tags + images_tags + videos_tags) for tag in tags.split(','))
sorted_tags = sorted(set(all_tags))
return render_template('tags_list.html', tags=sorted_tags, page_type=page_type)
@app.route('/subnav')
def subnav():
return render_template(
'subnav.html'
)
@app.route('/image_edit/<int:id>', methods=['GET', 'POST'])
@login_required
def image_edit(id):
@ -297,6 +328,12 @@ def card():
'card.html'
)
@app.route('/gifs')
def gifs():
return render_template(
'gifs.html'
)
@app.route('/autocomplete')
def autocomplete():
search_query = request.args.get('search', '', type=str)
@ -427,6 +464,10 @@ def videos():
query = get_content_query(Video, subscriptions, search_query)
pagination = query.paginate(page=page, per_page=10, error_out=False)
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))
user_cookies = 0
if current_user.is_authenticated:
user_cookies_record = Cookies.query.filter_by(username=current_user.username).first()
@ -438,9 +479,11 @@ def videos():
pagination=pagination,
user_cookies=user_cookies,
search_query=search_query,
content_type='video'
content_type='video',
tags=sorted_tags
)
@app.route('/vote_video/<int:video_id>', methods=['POST'])
@login_required
def vote_video(video_id):

9
license Normal file
View File

@ -0,0 +1,9 @@
Copyright (c) 2025 artberry.xyz
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The "artberry.xyz" brand, logo, and trademarks are protected and may not be used without explicit permission from the copyright holder. This license does not grant any rights to use the brand or trademarks associated with "artberry.xyz".

File diff suppressed because it is too large Load Diff

428
static/css/styles.scss Normal file
View File

@ -0,0 +1,428 @@
.container {
position: absolute;
display: flex;
flex-wrap: wrap;
gap: 20px;
background-color: #1f091b;
padding: 10px;
box-sizing: border-box;
}
.new-content {
width: 1500px;
height: 340px;
top: 349px;
left: 50%;
transform: translateX(-50%);
}
.popular-content {
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0px;
gap: 20px;
width: 1502px;
height: 900px;
top: 737px;
left: 50%;
transform: translateX(-50%);
position: absolute;
}
.viewed-content {
width: 1502px;
height: 631px;
top: 1677px;
left: 50%;
transform: translateX(-50%);
position: absolute;
}
.popular-categories {
width: 1500px;
height: 277px;
top: 2308px;
left: 50%;
transform: translateX(-50%);
position: absolute;
}
.new-content-text {
width: 123px;
height: 33px;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 24px;
line-height: 100%;
letter-spacing: 0%;
position: absolute;
top: 10px;
left: 10px;
color: #8784C9;
}
.popular-content-text {
width: 123px;
height: 33px;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 24px;
line-height: 100%;
letter-spacing: 0%;
position: absolute;
top: 10px;
left: 10px;
color: #8784C9;
}
.viewed-content-text {
width: 123px;
height: 33px;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 24px;
line-height: 100%;
letter-spacing: 0%;
position: absolute;
top: 10px;
left: 10px;
color: #8784C9;
}
.popular-categories-text {
width: 321px;
height: 33px;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 24px;
line-height: 100%;
letter-spacing: 0%;
position: absolute;
top: 10px;
left: 10px;
color: #8784C9;
}
.view-more-button {
width: 1500px;
height: 40px;
border-radius: 10px;
gap: 10px;
padding-top: 10px;
padding-right: 679px;
padding-bottom: 10px;
padding-left: 679px;
background-color: #8784C9;
border: none;
color: #fff;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 16px;
cursor: pointer;
white-space: nowrap;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
}
.new-context-button-text {
width: 134px;
height: 22px;
font-family: Nunito, sans-serif;
font-weight: 500;
font-size: 16px;
line-height: 100%;
letter-spacing: 0%;
color: #3C3882;
}
.navbar {
width: 100%;
max-width: 1500px;
height: 120px;
background: #05040A;
display: flex;
align-items: center;
padding: 0 20px;
gap: 20px;
margin: 0 auto;
}
.logo {
width: 307px;
height: 60px;
}
.search-container {
display: flex;
align-items: center;
width: 452.5px;
height: 27px;
border: 1px solid #8784C9;
border-radius: 20px;
padding: 15px;
background: #05040A;
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;
height: 24px;
position: absolute;
top: 0;
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;
}
.search-container:hover .search-icon,
.search-container:focus-within .search-icon {
opacity: 0;
}
.search-input {
border: none;
outline: none;
flex-grow: 1;
font-size: 16px;
height: 24px;
color: #8784C9;
background-color: #05040A;
}
.search-container:hover {
border-color: #3C3882;
}
.search-container:focus-within {
border-color: #3C3882;
}
.icon-container {
display: flex;
align-items: center;
margin-left: 10px;
}
.video-icon {
width: 24px;
height: 24px;
margin-left: 10px;
}
.tray-icon {
width: 11px;
height: 7px;
margin-left: 5px;
}
.translate-btn {
position: relative;
width: 23px;
height: 27px;
border: 1px solid #8784C9;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
background: #05040A;
cursor: pointer;
padding: 15px;
transition: border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
}
.translate-icon,
.translate-hover-icon {
width: 24px;
height: 24px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: opacity 0.3s ease;
}
.translate-hover-icon {
opacity: 0;
}
.translate-btn:hover .translate-hover-icon {
opacity: 1;
}
.translate-btn:hover .translate-icon {
opacity: 0;
}
.translate-btn:hover {
border-color: #3C3882;
}
.overlay-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
opacity: 0.7;
}
.menu {
display: flex;
font-family: Nunito, sans-serif;
gap: 22px;
width: 519.5px;
height: 22px;
justify-content: space-between;
padding-left: 60px;
padding-right: 60px;
}
.menu a {
text-decoration: none;
color: #8784C9;
font-size: 16px;
transition: color 0.3s ease;
}
.menu a:hover {
color: #3C3882;
}
.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;
height: 42px;
position: absolute;
top: 0;
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;
border-radius: 20px;
background: #8784C9;
border: 1px solid #8784C9;
padding: 10px 15px;
font-size: 16px;
font-family: Nunito, sans-serif;
font-weight: 500;
line-height: 21.82px;
letter-spacing: 0%;
color: #05040A;
cursor: pointer;
margin-left: 10px;
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.login-btn:hover {
background-color: #3C3882;
color: #05040A;
border-color: #3C3882;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: #05040A;
border: 1px solid #3C3882;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: none;
flex-direction: column;
width: 150px;
z-index: 10;
}
.dropdown-item {
padding: 10px 15px;
font-size: 14px;
border-radius:4px;
color: #8784C9;
cursor: pointer;
transition: background 0.3s ease, color 0.3s ease;
}
.dropdown-item:hover {
background: #3C3882;
color: white;
}
.tags-container {
width: 1500px;
height: 35px;
position: absolute;
top: 266px;
left: 210px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 10px;
border: none;
background-color: #05040A;
overflow: hidden;
}
.tag {
height: 35px;
border-radius: 5px;
padding: 6px 10px;
display: inline-flex;
align-items: center;
justify-content: center;
background-color: #3C3882;
border: none;
color: #8784C9;
margin: 0;
visibility: visible;
transition: visibility 0.3s ease;
}
.list-button {
width: 35px;
height: 35px;
border-radius: 10px;
padding: 5px;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #8784C9;
background-color: transparent;
color: #3C3882;
margin-left: 10px;
gap: 5px;
position: relative;
z-index: 2;
}
.tags-container > .list-button {
position: absolute;
right: 0;
z-index: 2;
}
.taglist-shadow {
width: 64px;
height: 35px;
position: absolute;
right: 0;
background: linear-gradient(to right, rgba(5, 4, 10, 0) 30%, rgba(5, 4, 10, 0.5) 60%, #05040A 100%);
}

View File

@ -0,0 +1,3 @@
<svg width="15" height="25" viewBox="0 0 15 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14.0607 13.5607C14.6464 12.9749 14.6464 12.0251 14.0607 11.4393L4.51472 1.8934C3.92893 1.30761 2.97919 1.30761 2.3934 1.8934C1.80761 2.47919 1.80761 3.42893 2.3934 4.01472L10.8787 12.5L2.3934 20.9853C1.80761 21.5711 1.80761 22.5208 2.3934 23.1066C2.97919 23.6924 3.92893 23.6924 4.51472 23.1066L14.0607 13.5607ZM12 14H13V11H12V14Z" fill="#8784C9"/>
</svg>

After

Width:  |  Height:  |  Size: 462 B

17
static/js/navbar.js Normal file
View File

@ -0,0 +1,17 @@
document.addEventListener('DOMContentLoaded', function () {
const iconContainer = document.querySelector('.icon-container');
const dropdownMenu = document.querySelector('.dropdown-menu');
iconContainer.addEventListener('click', function (event) {
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
event.stopPropagation();
});
document.addEventListener('click', function () {
dropdownMenu.style.display = 'none';
});
dropdownMenu.addEventListener('click', function (event) {
event.stopPropagation();
});
});

22
static/js/taglist.js Normal file
View File

@ -0,0 +1,22 @@
window.addEventListener('DOMContentLoaded', function() {
const listButton = document.querySelector('.list-button');
const tags = document.querySelectorAll('.tag');
const buttonRect = listButton.getBoundingClientRect();
function checkTagVisibility() {
tags.forEach(tag => {
const tagRect = tag.getBoundingClientRect();
if (tagRect.right > buttonRect.left) {
tag.style.visibility = 'hidden';
} else {
tag.style.visibility = 'visible';
}
});
}
document.querySelector('.tags-container').addEventListener('scroll', checkTagVisibility);
checkTagVisibility();
});

View File

@ -1,74 +0,0 @@
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Navbar</title>
<head>
<body>
{% include 'navbar.html' %}
<style>
.card {
width: 353px;
height: auto;
position: absolute;
display: flex;
flex-direction: column;
font-family: Nunito, sans-serif;
gap: 5px;
}
.card-cover {
width: 353px;
height: 180px;
background: #1D1C2E;
}
.card-info {
width: 353px;
height: 59px;
display: flex;
flex-direction: column;
gap: 5px;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.card-stats {
display: flex;
gap: 10px;
}
.stat {
display: flex;
align-items: center;
gap: 5px;
}
.card-text {
font-family: 'Nunito';
font-size: 14px;
color: #8784C9;
}
</style>
<div class="card">
<div class="card-cover"></div>
<div class="card-info">
<div class="card-header">
<span class="card-title" style="color: #3C3882;">Netwide Assembler</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;">1344</span>
</div>
<div class="stat">
<img src="{{ url_for('static', filename='card/views-icon.svg') }}" alt="Просмотры" width="20" height="20">
<span style="color: #8784C9;">321132</span>
</div>
</div>
</div>
<p class="card-text" style="font-family: Nunito, sans-serif;">The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed for portability and
modularity. It supports a range of object file formats, including Linux and *BSD a.out, ELF, Mach-O,
16-bit and 32-bit .obj (OMF) format, COFF (including its Win32 and Win64 variants.)</p>
</div>
</div>
</body>
</head>
</html>

View File

@ -1,151 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}🫐artberry🫐{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
<link rel="icon" href="{{ url_for('static', filename='artberry.ico') }}" type="image/x-icon">
{% if extra_css %}
<link rel="stylesheet" href="{{ url_for('static', filename=extra_css) }}">
{% endif %}
<link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@300&display=swap" rel="stylesheet">
</head>
<body>
{% include 'navbar.html' %}
<header class="header">
<form method="GET"
action="{{ search_url if search_url else url_for(request.endpoint, pub_type=pub_type, username=username) }}"
class="search-form">
<!-- </form>
<div id="autocomplete-suggestions" class="autocomplete-suggestions"></div>
</form>
подсказки будут добавлены позже -->
</header>
<section class="content" id="content">
{% block content %}
{% if content_type in ['art', 'video', 'comic'] %}
<div class="{{ content_type }}-details">
<h2>{{ content.title }}</h2>
{% if content_type == 'art' %}
<img src="{{ url_for('static', filename='uploads/' + content.filename) }}" alt="{{ content.title }}"
class="art-image" loading="lazy" width="800" height="600">
{% elif content_type == 'video' %}
<video controls class="video-player">
<source src="{{ url_for('static', filename='uploads/videos/' + content.filename) }}" type="video/mp4">
Your browser does not support the video tag.
</video>
{% elif content_type == 'comic' %}
<div class="comic-pages">
{% for page in content.pages %}
<img src="{{ url_for('static', filename='uploads/comics/' + content.name + '/' + page) }}"
alt="Comic Page {{ loop.index }}" class="comic-page">
{% endfor %}
</div>
{% endif %}
</div>
{% else %}
{% endif %}
{% endblock %}
</section>
<!-- {% if pagination %}
<div class="pagination">
{% if pagination.has_prev %}
<a href="{{ url_for(request.endpoint, page=pagination.prev_num, search=request.args.get('search')) }}"
class="button">«</a>
{% endif %}
{% for page in pagination.iter_pages() %}
{% if page %}
<a href="{{ url_for(request.endpoint, page=page, search=request.args.get('search')) }}" class="button"
style="{% if page == pagination.page %}color: yellow;{% endif %}">
{{ page }}
</a>
{% endif %}
{% endfor %}
{% if pagination.has_next %}
<a href="{{ url_for(request.endpoint, page=pagination.next_num, search=request.args.get('search')) }}"
class="button">»</a>
{% endif %}
</div>
{% endif %} -->
<div class="modal-overlay" id="ageVerificationModal">
<div class="modal-content">
<p>By clicking "Yes", you agree that you are of legal age according to your state/city/province/country.</p>
<div class="modal-buttons">
<button class="modal-button" id="yesButton">Yes</button>
<button class="modal-button cancel" id="noButton">No</button>
</div>
{% include 'subnav.html' %}
{% include 'tags_list.html' %}
{% block content %}
{% block new_content %}
<div class="container new-content">
<a class="new-content-text">НОВИНКИ</a>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
</div>
{% endblock %}
<!-- <script>
window.onload = function () {
var modal = document.getElementById('ageVerificationModal');
var body = document.body;
var content = document.getElementById('content');
<div class="container popular-content">
<a class="popular-content-text">ПОПУЛЯРНОЕ</a>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
if (document.cookie.indexOf('ageVerified=true') !== -1) {
return;
}
<div class="container viewed-content">
<a class="viewed-content-text">ПРОСМАТРИВАЕМОЕ</a>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
modal.style.display = 'flex';
content.classList.add('blur');
document.getElementById('yesButton').addEventListener('click', function () {
modal.style.display = 'none';
content.classList.remove('blur');
document.cookie = "ageVerified=true; path=/; max-age=31536000";
});
document.getElementById('noButton').addEventListener('click', function () {
window.location.href = 'https://www.google.com/search?q=cats';
});
};
document.getElementById('search-input').addEventListener('input', function () {
var query = this.value;
if (query.length < 2) {
document.getElementById('autocomplete-suggestions').innerHTML = '';
return;
}
fetch(`/autocomplete?search=${encodeURIComponent(query)}`)
.then(response => response.json())
.then(data => {
var suggestionsContainer = document.getElementById('autocomplete-suggestions');
suggestionsContainer.innerHTML = '';
if (data.length > 0) {
data.forEach(function (suggestion) {
var suggestionElement = document.createElement('div');
suggestionElement.classList.add('suggestion-item');
suggestionElement.textContent = suggestion;
suggestionElement.addEventListener('click', function () {
var searchInput = document.getElementById('search-input');
var currentValue = searchInput.value;
var tags = currentValue.split(',').map(tag => tag.trim());
tags[tags.length - 1] = suggestion;
searchInput.value = tags.join(', ');
suggestionsContainer.innerHTML = '';
});
suggestionsContainer.appendChild(suggestionElement);
});
}
})
.catch(error => console.error('Error fetching autocomplete data:', error));
});
</script> -->
<div class="container popular-categories">
<a class="popular-categories-text">ПОПУЛЯРНЫЕ КАТЕГОРИИ</a>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
{% endblock %}
</body>
</head>
</html>

1
templates/gifs.html Normal file
View File

@ -0,0 +1 @@
{% include 'navbar.html' %}

View File

@ -1,16 +1,14 @@
{% extends "content.html" %}
{% include 'subnav.html' %}
{% block title %}🫐videos - artberry🫐{% endblock %}
{% block title %}🫐arts - artberry🫐{% endblock %}
{% block new_content %}
<div class="container new-content">
<a class="new-content-text">НОВИНКИ (Updated for Videos)</a>
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
</div>
{% endblock %}
{% block content %}
<section class="gallery">
{% for image in images %}
<div class="card">
<a href="{{ url_for('view', content_type='art', id=image.id) }}" class="card-link">
<img src="{{ url_for('static', filename='arts/' + image.image_file) }}" alt="Art Image" class="art-image">
<p>{{ image.cookie_votes }} 🍪</p>
</a>
</div>
{% endfor %}
</section>
{% include 'tags_list.html' %}
{% endblock %}

View File

@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Navbar</title>
</head>
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
<body>
<div class="navbar">
<img src="{{ url_for('static', filename='navbar/logo.svg') }}" alt="Логотип" class="logo">
@ -47,256 +47,8 @@
<button class="login-btn">ВОЙТИ</button>
</div>
</div>
<style>
.navbar {
width: 100%;
max-width: 1500px;
height: 120px;
background: #05040A;
display: flex;
align-items: center;
padding: 0 20px;
gap: 20px;
margin: 0 auto;
}
.logo {
width: 307px;
height: 60px;
}
.search-container {
display: flex;
align-items: center;
width: 452.5px;
height: 27px;
border: 1px solid #8784C9;
border-radius: 20px;
padding: 15px;
background: #05040A;
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;
height: 24px;
position: absolute;
top: 0;
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;
}
.search-container:hover .search-icon,
.search-container:focus-within .search-icon {
opacity: 0;
}
.search-input {
border: none;
outline: none;
flex-grow: 1;
font-size: 16px;
height: 24px;
color: #8784C9;
background-color: #05040A;
}
.search-container:hover {
border-color: #3C3882;
}
.search-container:focus-within {
border-color: #3C3882;
}
.icon-container {
display: flex;
align-items: center;
margin-left: 10px;
}
.video-icon {
width: 24px;
height: 24px;
margin-left: 10px;
}
.tray-icon {
width: 11px;
height: 7px;
margin-left: 5px;
}
.translate-btn {
position: relative;
width: 23px;
height: 27px;
border: 1px solid #8784C9;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
background: #05040A;
cursor: pointer;
padding: 15px;
transition: border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
}
.translate-icon,
.translate-hover-icon {
width: 24px;
height: 24px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: opacity 0.3s ease;
}
.translate-hover-icon {
opacity: 0;
}
.translate-btn:hover .translate-hover-icon {
opacity: 1;
}
.translate-btn:hover .translate-icon {
opacity: 0;
}
.translate-btn:hover {
border-color: #3C3882;
}
.overlay-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 20px;
height: 20px;
opacity: 0.7;
}
.menu {
display: flex;
font-family: Nunito, sans-serif;
gap: 22px;
width: 519.5px;
height: 22px;
justify-content: space-between;
padding-left: 60px;
padding-right: 60px;
}
.menu a {
text-decoration: none;
color: #8784C9;
font-size: 16px;
transition: color 0.3s ease;
}
.menu a:hover {
color: #3C3882;
}
.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;
height: 42px;
position: absolute;
top: 0;
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;
border-radius: 20px;
background: #8784C9;
border: 1px solid #8784C9;
padding: 10px 15px;
font-size: 16px;
font-family: Nunito, sans-serif;
font-weight: 500;
line-height: 21.82px;
letter-spacing: 0%;
color: #05040A;
cursor: pointer;
margin-left: 10px;
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}
.login-btn:hover {
background-color: #3C3882;
color: #05040A;
border-color: #3C3882;
}
.dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: #05040A;
border: 1px solid #3C3882;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: none;
flex-direction: column;
width: 150px;
z-index: 10;
}
.dropdown-item {
padding: 10px 15px;
font-size: 14px;
border-radius:4px;
color: #8784C9;
cursor: pointer;
transition: background 0.3s ease, color 0.3s ease;
}
.dropdown-item:hover {
background: #3C3882;
color: white;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function () {
const iconContainer = document.querySelector('.icon-container');
const dropdownMenu = document.querySelector('.dropdown-menu');
iconContainer.addEventListener('click', function (event) {
dropdownMenu.style.display = dropdownMenu.style.display === 'block' ? 'none' : 'block';
event.stopPropagation();
});
document.addEventListener('click', function () {
dropdownMenu.style.display = 'none';
});
dropdownMenu.addEventListener('click', function (event) {
event.stopPropagation();
});
});
</script>
<script src="{{ url_for('static', filename='js/navbar.js') }}"></script>
</body>
</head>
</html>

54
templates/subnav.html Normal file
View File

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Subnav</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
}
.subnav-container {
max-width: 1500px;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: #3C3882;
padding: 0 20px;
box-sizing: border-box;
position: absolute;
top: 168px;
left: 50%;
transform: translateX(-50%);
}
.button {
width: 375px;
height: 50px;
background-color: #3C3882;
border: none;
font-size: 16px;
cursor: pointer;
color: #8784C9;
box-sizing: border-box;
}
.button:nth-child(1) { padding: 15px 139px; }
.button:nth-child(2) { padding: 15px 134px; }
.button:nth-child(3) { padding: 15px 136px; }
.button:nth-child(4) { padding: 15px 136px; }
</style>
</head>
<body>
<div class="subnav-container">
<button class="button">ТЕГИ</button>
<button class="button">КАТЕГОРИИ</button>
<button class="button">ПЕРСОНАЖИ</button>
<button class="button">КОЛЛЕКЦИИ</button>
</div>
</body>
</html>

22
templates/tags_list.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<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 %}
<button class="tag">{{ tag }}</button>
{% endfor %}
<button class="list-button">
<img src="{{ url_for('static', filename='icons/list-icon.svg') }}" alt="List Icon">
</button>
<div class="taglist-shadow"></div>
</div>
<script src="{{ url_for('static', filename='js/taglist.js') }}"></script>
</body>
</head>
</html>

View File

@ -1,27 +0,0 @@
{% extends "content.html" %}
{% block title %}🫐videos - artberry🫐{% endblock %}
{% block content %}
<section class="gallery">
{% for video in videos %}
<div class="card video-card">
<a href="{{ url_for('view', content_type='video', id=video.id) }}">
<img src="{{ url_for('static', filename='thumbnails/' + video.video_thumbnail_file) }}" alt="Video Thumbnail" class="video-thumbnail">
</a>
<p class="video-title">{{ video.video_name }}</p>
<p>{{ video.cookie_votes }} 🍪</p>
</div>
{% endfor %}
</section>
<div class="pagination">
{% if pagination.has_prev %}
<a href="{{ url_for('videos', page=pagination.prev_num, search=search_query) }}" class="button">Previous</a>
{% endif %}
{% if pagination.has_next %}
<a href="{{ url_for('videos', page=pagination.next_num, search=search_query) }}" class="button">Next</a>
{% endif %}
</div>
{% endblock %}

View File

@ -96,7 +96,7 @@
<button type="submit" class="button">Post Comment</button>
</form>
{% else %}
<p>You need to <a href="{{ url_for('login') }}">log in</a> to post a comment.</p>
<p>You need to <a href="{{ url_for('auth.login') }}">log in</a> to post a comment.</p>
{% endif %}
</section>
{% endif %}
@ -125,7 +125,7 @@
<button type="submit" class="button">Vote</button>
</form>
{% else %}
<p>You need to <a href="{{ url_for('login') }}">log in</a> to vote.</p>
<p>You need to <a href="{{ url_for('auth.login') }}">log in</a> to vote.</p>
{% endif %}
</div>
</body>