Compare commits
2 Commits
04e282d097
...
c9b4ec26fd
Author | SHA1 | Date | |
---|---|---|---|
c9b4ec26fd | |||
f7d99ee5fc |
105
app.py
105
app.py
@ -40,7 +40,7 @@ app.config.from_object(Config)
|
|||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
bcrypt.init_app(app)
|
bcrypt.init_app(app)
|
||||||
login_manager = LoginManager(app)
|
login_manager = LoginManager(app)
|
||||||
login_manager.login_view = 'login'
|
login_manager.login_view = 'auth.login'
|
||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(user_id):
|
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))
|
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'])
|
@app.route('/view/<content_type>/<int:id>', methods=['GET', 'POST'])
|
||||||
def view(content_type, id):
|
def view(content_type, id):
|
||||||
comments = []
|
comments = []
|
||||||
@ -131,6 +129,13 @@ def view(content_type, id):
|
|||||||
content = Image.query.get_or_404(id)
|
content = Image.query.get_or_404(id)
|
||||||
comments = Comments.query.filter_by(image_id=id).order_by(Comments.comment_date.desc()).all()
|
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')
|
search_query = request.args.get('search')
|
||||||
page = request.args.get('page', 1, type=int)
|
page = request.args.get('page', 1, type=int)
|
||||||
subscriptions = []
|
subscriptions = []
|
||||||
@ -157,6 +162,13 @@ def view(content_type, id):
|
|||||||
content = Video.query.get_or_404(id)
|
content = Video.query.get_or_404(id)
|
||||||
comments = Comments.query.filter_by(video_id=id).order_by(Comments.comment_date.desc()).all()
|
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()
|
all_videos = Video.query.order_by(Video.id).all()
|
||||||
video_ids = [video.id for video in all_videos]
|
video_ids = [video.id for video in all_videos]
|
||||||
current_index = video_ids.index(id)
|
current_index = video_ids.index(id)
|
||||||
@ -172,6 +184,13 @@ def view(content_type, id):
|
|||||||
content = Comic.query.get_or_404(id)
|
content = Comic.query.get_or_404(id)
|
||||||
comments = Comments.query.filter_by(comic_id=id).order_by(Comments.comment_date.desc()).all()
|
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()
|
comic_pages = ComicPage.query.filter_by(comic_id=id).order_by(ComicPage.page_number).all()
|
||||||
|
|
||||||
if not comic_pages:
|
if not comic_pages:
|
||||||
@ -286,8 +305,7 @@ def image_edit(id):
|
|||||||
|
|
||||||
@app.route('/video_edit/<int:id>', methods=['GET', 'POST'])
|
@app.route('/video_edit/<int:id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def video_edit(id):
|
async def video_edit(id):
|
||||||
|
|
||||||
video = Video.query.get_or_404(id)
|
video = Video.query.get_or_404(id)
|
||||||
|
|
||||||
if video.username != current_user.username:
|
if video.username != current_user.username:
|
||||||
@ -301,7 +319,6 @@ def video_edit(id):
|
|||||||
form.tags.data = video.tags
|
form.tags.data = video.tags
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
|
|
||||||
video.video_name = form.video_name.data
|
video.video_name = form.video_name.data
|
||||||
video.description = form.description.data
|
video.description = form.description.data
|
||||||
video.tags = form.tags.data
|
video.tags = form.tags.data
|
||||||
@ -310,10 +327,15 @@ def video_edit(id):
|
|||||||
thumbnail_file = form.video_thumbnail.data
|
thumbnail_file = form.video_thumbnail.data
|
||||||
if allowed_file(thumbnail_file.filename, app.config['ALLOWED_IMAGE_EXTENSIONS']):
|
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_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
|
video.video_thumbnail_file = thumbnail_filename
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@ -476,6 +498,40 @@ def videos():
|
|||||||
query = get_content_query(Video, subscriptions, search_query)
|
query = get_content_query(Video, subscriptions, search_query)
|
||||||
pagination = query.paginate(page=page, per_page=10, error_out=False)
|
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]
|
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(',')]
|
all_tags = [tag.strip() for tags in videos_tags for tag in tags.split(',')]
|
||||||
sorted_tags = sorted(set(all_tags))
|
sorted_tags = sorted(set(all_tags))
|
||||||
@ -487,12 +543,14 @@ def videos():
|
|||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
'videos.html',
|
'videos.html',
|
||||||
videos=pagination.items,
|
videos=videos_with_views,
|
||||||
pagination=pagination,
|
pagination=pagination,
|
||||||
user_cookies=user_cookies,
|
user_cookies=user_cookies,
|
||||||
search_query=search_query,
|
search_query=search_query,
|
||||||
content_type='video',
|
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():
|
def publication_rules():
|
||||||
return render_template('publication_rules.html')
|
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__':
|
if __name__ == '__main__':
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.create_all()
|
db.create_all()
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
$dark-violet: #0D0C1C;
|
$dark-violet: #0D0C1C;
|
||||||
$violet: #3c3882;
|
$violet: #3C3882;
|
||||||
$light-violet: #8784C9;
|
$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=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');
|
@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{
|
|
||||||
|
body {
|
||||||
background-color: #05040A;
|
background-color: #05040A;
|
||||||
font-family: Nunito, sans-serif;
|
font-family: Nunito, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -31,6 +33,7 @@ body{
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-new-content {
|
.img-new-content {
|
||||||
width: 1502px;
|
width: 1502px;
|
||||||
height: 423px;
|
height: 423px;
|
||||||
@ -54,9 +57,11 @@ body{
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 1502px;
|
width: 1502px;
|
||||||
height: 631px;
|
height: 631px;
|
||||||
left: 209px;
|
|
||||||
position: absolute;
|
|
||||||
top: 653px;
|
top: 653px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-popular-content {
|
.img-popular-content {
|
||||||
@ -80,10 +85,13 @@ body{
|
|||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 1502px;
|
width: 1502px;
|
||||||
height: 631px;
|
height: 631px;
|
||||||
left: 209px;
|
|
||||||
position: absolute;
|
|
||||||
top: 1340px;
|
top: 1340px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
position: absolute;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-viewed-content {
|
.img-viewed-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -97,7 +105,6 @@ body{
|
|||||||
top: 1617px;
|
top: 1617px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.popular-categories {
|
.popular-categories {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -108,9 +115,11 @@ body{
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 2095px;
|
top: 2095px;
|
||||||
left: 210px;
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-popular-categories {
|
.img-popular-categories {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -196,7 +205,7 @@ body{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.view-more-button:hover {
|
.view-more-button:hover {
|
||||||
background-color: #3C3882;
|
background-color: $violet;
|
||||||
transition: background-color 0.3s ease, color 0.3s ease;
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,14 +238,13 @@ body{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.img-view-more-button:hover {
|
.img-view-more-button:hover {
|
||||||
background-color: #3C3882;
|
background-color: $violet;
|
||||||
transition: background-color 0.3s ease, color 0.3s ease;
|
transition: background-color 0.3s ease, color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-view-more-button:hover .new-context-button-text {
|
.img-view-more-button:hover .new-context-button-text {
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-context-button-text {
|
.new-context-button-text {
|
||||||
@ -246,9 +254,11 @@ body{
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
letter-spacing: 0%;
|
letter-spacing: 0%;
|
||||||
color: #3C3882;
|
color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* navbar */
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 1500px;
|
max-width: 1500px;
|
||||||
@ -259,16 +269,19 @@ body{
|
|||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar-wrapper {
|
.navbar-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: $dark-violet;
|
background: $dark-violet;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: 307px;
|
width: 307px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container {
|
.search-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -281,12 +294,14 @@ body{
|
|||||||
position: relative;
|
position: relative;
|
||||||
transition: border-color 0.3s ease;
|
transition: border-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-icon-container {
|
.search-icon-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-icon,
|
.search-icon,
|
||||||
.search-hover-icon {
|
.search-hover-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
@ -296,9 +311,11 @@ body{
|
|||||||
left: 0;
|
left: 0;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-hover-icon {
|
.search-hover-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container:hover .search-hover-icon,
|
.search-container:hover .search-hover-icon,
|
||||||
.search-container:focus-within .search-hover-icon {
|
.search-container:focus-within .search-hover-icon {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -320,11 +337,11 @@ body{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-container:hover {
|
.search-container:hover {
|
||||||
border-color: #3C3882;
|
border-color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-container:focus-within {
|
.search-container:focus-within {
|
||||||
border-color: #3C3882;
|
border-color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-container {
|
.icon-container {
|
||||||
@ -338,11 +355,13 @@ body{
|
|||||||
height: 24px;
|
height: 24px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tray-icon {
|
.tray-icon {
|
||||||
width: 11px;
|
width: 11px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translate-btn {
|
.translate-btn {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 23px;
|
width: 23px;
|
||||||
@ -357,6 +376,7 @@ body{
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
transition: border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
|
transition: border-color 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translate-icon,
|
.translate-icon,
|
||||||
.translate-hover-icon {
|
.translate-hover-icon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
@ -367,9 +387,11 @@ body{
|
|||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translate-hover-icon {
|
.translate-hover-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translate-btn:hover .translate-hover-icon {
|
.translate-btn:hover .translate-hover-icon {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
@ -377,9 +399,11 @@ body{
|
|||||||
.translate-btn:hover .translate-icon {
|
.translate-btn:hover .translate-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.translate-btn:hover {
|
.translate-btn:hover {
|
||||||
border-color: #3C3882;
|
border-color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.overlay-icon {
|
.overlay-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
@ -389,6 +413,7 @@ body{
|
|||||||
height: 20px;
|
height: 20px;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 22px;
|
gap: 22px;
|
||||||
@ -398,25 +423,30 @@ body{
|
|||||||
padding-left: 60px;
|
padding-left: 60px;
|
||||||
padding-right: 60px;
|
padding-right: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu a {
|
.menu a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
transition: color 0.3s ease;
|
transition: color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu a:hover {
|
.menu a:hover {
|
||||||
color: #3C3882;
|
color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-container {
|
.auth-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discord-icon-container {
|
.discord-icon-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 42px;
|
width: 42px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discord-icon,
|
.discord-icon,
|
||||||
.discord-hover-icon {
|
.discord-hover-icon {
|
||||||
width: 42px;
|
width: 42px;
|
||||||
@ -426,15 +456,19 @@ body{
|
|||||||
left: 0;
|
left: 0;
|
||||||
transition: opacity 0.3s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discord-hover-icon {
|
.discord-hover-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discord-icon-container:hover .discord-hover-icon {
|
.discord-icon-container:hover .discord-hover-icon {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discord-icon-container:hover .discord-icon {
|
.discord-icon-container:hover .discord-icon {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn {
|
.login-btn {
|
||||||
width: 87px;
|
width: 87px;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
@ -451,42 +485,50 @@ body{
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn:hover {
|
.login-btn:hover {
|
||||||
background-color: #3C3882;
|
background-color: $violet;
|
||||||
color: $dark-violet;
|
color: $dark-violet;
|
||||||
border-color: #3C3882;
|
border-color: $violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
right: 0;
|
right: 0;
|
||||||
background: $dark-violet;
|
background: $dark-violet;
|
||||||
border: 1px solid #3C3882;
|
border: 1px solid $violet;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
display: none;
|
display: none;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 150px;
|
width: 150px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
border-radius:4px;
|
border-radius: 4px;
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background 0.3s ease, color 0.3s ease;
|
transition: background 0.3s ease, color 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-item:hover {
|
.dropdown-item:hover {
|
||||||
background: #3C3882;
|
background: $violet;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tags-list */
|
||||||
|
|
||||||
.tags-container {
|
.tags-container {
|
||||||
width: 1500px;
|
width: 1500px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 192px;
|
top: 192px;
|
||||||
left: 210px;
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -509,7 +551,7 @@ color: white;
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: #3C3882;
|
background-color: $violet;
|
||||||
border: none;
|
border: none;
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -527,7 +569,7 @@ color: white;
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 2px solid $light-violet;
|
border: 2px solid $light-violet;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: #3C3882;
|
color: $violet;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -541,6 +583,9 @@ color: white;
|
|||||||
right: 0;
|
right: 0;
|
||||||
background: linear-gradient(to right, rgba(5, 4, 10, 0) 30%, rgba(5, 4, 10, 0.5) 60%, #05040A 100%);
|
background: linear-gradient(to right, rgba(5, 4, 10, 0) 30%, rgba(5, 4, 10, 0.5) 60%, #05040A 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cards */
|
||||||
|
|
||||||
.img-cards-grid {
|
.img-cards-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(6, 1fr);
|
grid-template-columns: repeat(6, 1fr);
|
||||||
@ -549,6 +594,7 @@ color: white;
|
|||||||
height: 708px;
|
height: 708px;
|
||||||
margin-top: 60px;
|
margin-top: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-card {
|
.img-card {
|
||||||
width: 225px;
|
width: 225px;
|
||||||
height: 344px;
|
height: 344px;
|
||||||
@ -556,6 +602,7 @@ color: white;
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-card-cover {
|
.img-card-cover {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 280px;
|
height: 280px;
|
||||||
@ -577,12 +624,35 @@ color: white;
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-cover {
|
.card-cover {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 180px;
|
height: 180px;
|
||||||
background: #1D1C2E;
|
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 {
|
.card-info {
|
||||||
@ -614,6 +684,7 @@ color: white;
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-small-cards-grid {
|
.img-small-cards-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(7, 1fr);
|
grid-template-columns: repeat(7, 1fr);
|
||||||
@ -621,11 +692,14 @@ color: white;
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 60px;
|
margin-top: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img-small-card-cover {
|
.img-small-card-cover {
|
||||||
width: 189px;
|
width: 189px;
|
||||||
height: 250px;
|
height: 250px;
|
||||||
background: #1D1C2E;
|
background: #1D1C2E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.img-small-card {
|
.img-small-card {
|
||||||
width: 189px;
|
width: 189px;
|
||||||
height: 314px;
|
height: 314px;
|
||||||
@ -633,6 +707,7 @@ color: white;
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small-cards-grid {
|
.small-cards-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(5, 1fr);
|
grid-template-columns: repeat(5, 1fr);
|
||||||
@ -647,12 +722,35 @@ color: white;
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.small-card-cover {
|
.small-card-cover {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 163px;
|
height: 163px;
|
||||||
background: #1D1C2E;
|
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 {
|
.small-card-info {
|
||||||
@ -684,6 +782,7 @@ color: white;
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: $light-violet;
|
color: $light-violet;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pc-card {
|
.pc-card {
|
||||||
width: 233px;
|
width: 233px;
|
||||||
height: 164px;
|
height: 164px;
|
||||||
@ -724,10 +823,10 @@ color: white;
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
letter-spacing: 0%;
|
letter-spacing: 0%;
|
||||||
color: #3C3882;
|
color: $violet;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
position: relative;
|
position: relative;
|
||||||
right:5px;
|
right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ac-img-small-cards-grid {
|
.ac-img-small-cards-grid {
|
||||||
@ -794,7 +893,7 @@ color: white;
|
|||||||
width: 276px;
|
width: 276px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: #3C3882;
|
background-color: $violet;
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -813,6 +912,9 @@ color: white;
|
|||||||
letter-spacing: 0%;
|
letter-spacing: 0%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pagination */
|
||||||
|
|
||||||
.pagination-container {
|
.pagination-container {
|
||||||
width: 626px;
|
width: 626px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
|
8
static/js/adjustScrollbar.js
Normal file
8
static/js/adjustScrollbar.js
Normal 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
64
static/js/hoverPreview.js
Normal 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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -46,7 +45,7 @@
|
|||||||
<img src="{{ url_for('static', filename='navbar/discord-hover.svg') }}" alt="Discord Hover"
|
<img src="{{ url_for('static', filename='navbar/discord-hover.svg') }}" alt="Discord Hover"
|
||||||
class="discord-hover-icon">
|
class="discord-hover-icon">
|
||||||
</div>
|
</div>
|
||||||
<button class="login-btn">ВОЙТИ</button>
|
<a href="{{ url_for('auth.login') }}"><button class="login-btn">ВОЙТИ</button></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Subnav</title>
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/styles.css') }}">
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Tags List</title>
|
|
||||||
<body>
|
<body>
|
||||||
<div class="tags-container">
|
<div class="tags-container">
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
|
@ -7,102 +7,123 @@
|
|||||||
{% include 'navbar.html' %}
|
{% include 'navbar.html' %}
|
||||||
{% include 'subnav.html' %}
|
{% include 'subnav.html' %}
|
||||||
{% include 'tags_list.html' %}
|
{% include 'tags_list.html' %}
|
||||||
<div class="container new-content">
|
<div class="container new-content">
|
||||||
<a class="new-content-text">НОВИНКИ</a>
|
<a class="new-content-text">НОВИНКИ</a>
|
||||||
<div class="small-cards-grid">
|
<div class="small-cards-grid">
|
||||||
{% for i in range(5) %}
|
{% for video_data in videos[:5] %}
|
||||||
<div class="small-card">
|
<div class="small-card">
|
||||||
<div class="small-card-cover"></div>
|
<div class="small-card-cover">
|
||||||
<div class="small-card-info">
|
<img src="{{ url_for('static', filename='thumbnails/' + video_data.video.video_thumbnail_file) }}" alt="Thumbnail" class="thumbnail">
|
||||||
<div class="small-card-header">
|
<video class="preview-video" muted preload="none" data-src="{{ url_for('static', filename='videos/' + video_data.video.video_file) }}">
|
||||||
<span class="small-card-text">Totoka</span>
|
<source type="video/mp4">
|
||||||
<div class="small-card-stats">
|
Your browser does not support the video tag.
|
||||||
<div class="small-stat">
|
</video>
|
||||||
<img src="{{ url_for('static', filename='card/like-icon.svg') }}" alt="Лайк" width="20" height="20">
|
|
||||||
<span class="small-card-text">134</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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="small-card-text">Big Brother Keep Hugging Me 4</p>
|
<div class="small-card-info">
|
||||||
</div>
|
<div class="small-card-header">
|
||||||
</div>
|
<span class="small-card-text">{{ video_data.video.username }}</span>
|
||||||
{% endfor %}
|
<div class="small-card-stats">
|
||||||
</div>
|
<div class="small-stat">
|
||||||
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
|
<img src="{{ url_for('static', filename='card/like-icon.svg') }}" alt="Лайк" width="20" height="20">
|
||||||
</div>
|
<span class="small-card-text">{{ video_data.video.cookie_votes }}</span>
|
||||||
<div class="container popular-content">
|
</div>
|
||||||
<a class="popular-content-text">ПОПУЛЯРНОЕ</a>
|
<div class="small-stat">
|
||||||
<div class="cards-grid">
|
<img src="{{ url_for('static', filename='card/views-icon.svg') }}" alt="Просмотры" width="20" height="20">
|
||||||
{% for i in range(8) %}
|
<span class="small-card-text">{{ video_data.views_count }}</span>
|
||||||
<div class="card">
|
|
||||||
<div class="card-cover"></div>
|
|
||||||
<div class="card-info">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="card-title" style="color: #3C3882;">Totoka</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>
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="card-text" style="font-family: Nunito, sans-serif;">Big Brother Keep Hugging Me 4</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) %}
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-cover"></div>
|
|
||||||
<div class="card-info">
|
|
||||||
<div class="card-header">
|
|
||||||
<span class="card-title" style="color: #3C3882;">Totoka</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>
|
|
||||||
</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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p class="card-text" style="font-family: Nunito, sans-serif;">Big Brother Keep Hugging Me 4</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container popular-categories">
|
|
||||||
<a class="popular-categories-text">ПОПУЛЯРНЫЕ КАТЕГОРИИ</a>
|
|
||||||
{% for i in range(6) %}
|
|
||||||
<div class="pc-card">
|
|
||||||
<div class="pc-card-cover"></div>
|
|
||||||
<div class="pc-card-info">
|
|
||||||
<div class="pc-card-stats">
|
|
||||||
<span class="category-name-text">Category</span>
|
|
||||||
<span class="categories-number" style="--length: 4;">14655</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<p class="small-card-text">{{ video_data.video.video_name }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<button class="view-more-button"><span class="new-context-button-text">Смотреть Больше</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="container popular-content">
|
||||||
|
<a class="popular-content-text">ПОПУЛЯРНОЕ</a>
|
||||||
|
<div class="cards-grid">
|
||||||
|
{% for video_data in popular_videos[:8] %}
|
||||||
|
<div class="card">
|
||||||
|
<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;">{{ 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;">{{ 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;">{{ video_data.views_count }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<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 video_data in most_viewed_videos[:8] %}
|
||||||
|
<div class="card">
|
||||||
|
<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;">{{ 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;">{{ 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;">{{ video_data.views_count }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<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 popular-categories">
|
||||||
|
<a class="popular-categories-text">ПОПУЛЯРНЫЕ КАТЕГОРИИ</a>
|
||||||
|
{% for i in range(6) %}
|
||||||
|
<div class="pc-card">
|
||||||
|
<div class="pc-card-cover"></div>
|
||||||
|
<div class="pc-card-info">
|
||||||
|
<div class="pc-card-stats">
|
||||||
|
<span class="category-name-text">Category</span>
|
||||||
|
<span class="categories-number" style="--length: 4;">14655</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% 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>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user