Bring back orgies (watchparties), now controllable by admins, and generally better in all ways #165
|
@ -0,0 +1,14 @@
|
||||||
|
.orgy-top-container {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row nowrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.orgy-chat-window-item {
|
||||||
|
flex-grow: 2;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.orgy-info-window-item {
|
||||||
|
max-width: 550px;
|
||||||
|
width: 550px;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import time
|
||||||
|
from math import floor
|
||||||
|
from random import randint
|
||||||
|
from urllib.parse import parse_qs, urlencode, urlparse
|
||||||
|
from flask import g
|
||||||
|
|
||||||
|
from sqlalchemy import Column, ForeignKey
|
||||||
|
from sqlalchemy.dialects.postgresql import TSVECTOR
|
||||||
|
from sqlalchemy.orm import relationship, scoped_session
|
||||||
|
from sqlalchemy.schema import FetchedValue
|
||||||
|
from sqlalchemy.sql.sqltypes import *
|
||||||
|
|
||||||
|
from files.classes import Base
|
||||||
|
from files.helpers.config.const import *
|
||||||
|
from files.helpers.lazy import lazy
|
||||||
|
from files.helpers.regex import *
|
||||||
|
from files.helpers.sorting_and_time import *
|
||||||
|
|
||||||
|
class Orgy(Base):
|
||||||
|
__tablename__ = "orgies"
|
||||||
|
|
||||||
|
youtube_id = Column(String, primary_key=True)
|
||||||
|
title = Column(String)
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__}(id={self.youtube_id}, title={self.title})>"
|
||||||
|
|
||||||
|
|
||||||
|
def get_orgy():
|
||||||
|
orgy = g.db.query(Orgy).one_or_none()
|
||||||
|
return orgy
|
||||||
|
|
||||||
|
def create_orgy(youtube_id, title):
|
||||||
|
assert not get_orgy()
|
||||||
|
assert re.match(yt_id_regex, youtube_id)
|
||||||
|
orgy = Orgy(title=title, youtube_id=youtube_id)
|
||||||
|
g.db.add(orgy)
|
||||||
|
g.db.flush()
|
||||||
|
g.db.commit()
|
||||||
|
|
||||||
|
def end_orgy():
|
||||||
|
assert get_orgy()
|
||||||
|
g.db.query(Orgy).delete()
|
||||||
|
g.db.flush()
|
||||||
|
g.db.commit()
|
|
@ -519,6 +519,7 @@ PERMS = { # Minimum admin_level to perform action.
|
||||||
'LOTTERY_VIEW_PARTICIPANTS': 2,
|
'LOTTERY_VIEW_PARTICIPANTS': 2,
|
||||||
'POST_COMMENT_INFINITE_PINGS': 2,
|
'POST_COMMENT_INFINITE_PINGS': 2,
|
||||||
'IGNORE_1WEEk_EDITING_LIMIT': 2,
|
'IGNORE_1WEEk_EDITING_LIMIT': 2,
|
||||||
|
'ORGIES': 2,
|
||||||
|
|
||||||
'ADMIN_REMOVE': 3,
|
'ADMIN_REMOVE': 3,
|
||||||
'ADMIN_ACTIONS_REVERT': 3,
|
'ADMIN_ACTIONS_REVERT': 3,
|
||||||
|
|
|
@ -9,6 +9,7 @@ from psycopg2.errors import UniqueViolation
|
||||||
|
|
||||||
from files.__main__ import app, cache, limiter
|
from files.__main__ import app, cache, limiter
|
||||||
from files.classes import *
|
from files.classes import *
|
||||||
|
from files.classes.orgy import *
|
||||||
from files.helpers.actions import *
|
from files.helpers.actions import *
|
||||||
from files.helpers.alerts import *
|
from files.helpers.alerts import *
|
||||||
from files.helpers.cloudflare import *
|
from files.helpers.cloudflare import *
|
||||||
|
@ -1906,3 +1907,27 @@ def admin_reset_password(user_id, v):
|
||||||
send_repeatable_notification(user.id, text)
|
send_repeatable_notification(user.id, text)
|
||||||
|
|
||||||
return {"message": f"@{user.username}'s password has been reset! The new password has been messaged to them!"}
|
return {"message": f"@{user.username}'s password has been reset! The new password has been messaged to them!"}
|
||||||
|
|
||||||
|
@app.get("/admin/orgy")
|
||||||
|
@admin_level_required(PERMS['ORGIES'])
|
||||||
|
def orgy_control(v):
|
||||||
|
return render_template("admin/orgy_control.html", v=v, orgy=get_orgy())
|
||||||
|
|
||||||
|
@app.post("/admin/start_orgy")
|
||||||
|
@admin_level_required(PERMS['ORGIES'])
|
||||||
|
def start_orgy(v):
|
||||||
|
youtube_id = request.values.get("youtube_id")
|
||||||
|
title = request.values.get("title")
|
||||||
|
|
||||||
|
assert youtube_id
|
||||||
|
assert title
|
||||||
|
|
||||||
|
create_orgy(youtube_id, title)
|
||||||
|
|
||||||
|
return redirect("/chat")
|
||||||
|
|
||||||
|
@app.post("/admin/stop_orgy")
|
||||||
|
@admin_level_required(PERMS['ORGIES'])
|
||||||
|
def stop_orgy(v):
|
||||||
|
end_orgy()
|
||||||
|
return redirect("/chat")
|
|
@ -13,6 +13,7 @@ from files.helpers.media import *
|
||||||
from files.helpers.sanitize import *
|
from files.helpers.sanitize import *
|
||||||
from files.helpers.alerts import push_notif
|
from files.helpers.alerts import push_notif
|
||||||
from files.routes.wrappers import *
|
from files.routes.wrappers import *
|
||||||
|
from files.classes.orgy import *
|
||||||
|
|
||||||
from files.__main__ import app, cache, limiter
|
from files.__main__ import app, cache, limiter
|
||||||
|
|
||||||
|
@ -33,6 +34,19 @@ messages = cache.get(f'messages') or {}
|
||||||
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
|
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
|
||||||
@is_not_permabanned
|
@is_not_permabanned
|
||||||
def chat(v):
|
def chat(v):
|
||||||
|
if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
||||||
|
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
||||||
|
orgy = get_orgy()
|
||||||
|
if orgy:
|
||||||
|
return render_template("orgy.html", v=v, messages=messages, orgy = orgy)
|
||||||
|
else:
|
||||||
|
return render_template("chat.html", v=v, messages=messages)
|
||||||
|
|
||||||
|
@app.get("/old_chat")
|
||||||
|
@limiter.limit(DEFAULT_RATELIMIT)
|
||||||
|
@limiter.limit(DEFAULT_RATELIMIT, key_func=get_ID)
|
||||||
|
@is_not_permabanned
|
||||||
|
def old_chat(v):
|
||||||
if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
if not v.admin_level and TRUESCORE_CHAT_MINIMUM and v.truescore < TRUESCORE_CHAT_MINIMUM:
|
||||||
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
abort(403, f"Need at least {TRUESCORE_CHAT_MINIMUM} truescore for access to chat!")
|
||||||
return render_template("chat.html", v=v, messages=messages)
|
return render_template("chat.html", v=v, messages=messages)
|
||||||
|
|
|
@ -98,6 +98,12 @@
|
||||||
</ul>
|
</ul>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
|
{% if v.admin_level >= PERMS['ORGIES'] %}
|
||||||
|
<h4>Misc</h4>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/admin/orgy">Start/Stop Orgy</a></li>
|
||||||
|
</ul>
|
||||||
|
{%- endif %}
|
||||||
<h4>Statistics</h4>
|
<h4>Statistics</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="/stats">Content Stats</a></li>
|
<li><a href="/stats">Content Stats</a></li>
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
{% extends "default.html" %}
|
||||||
|
|
||||||
|
{% block pagetitle %}Orgy Control Panel{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% if msg %}{{macros.alert(msg, false)}}{% endif %}
|
||||||
|
<div class="row my-5">
|
||||||
|
<div class="col">
|
||||||
|
<div class="settings mx-3">
|
||||||
|
<div id="description">
|
||||||
|
<h2>Orgy Control Panel</h2>
|
||||||
|
<br>
|
||||||
|
</div>
|
||||||
|
<div class="body d-lg-flex">
|
||||||
|
<div class="w-lg-100">
|
||||||
|
{%if not orgy%}
|
||||||
|
<form id="orgy" action="/admin/start_orgy" method="post">
|
||||||
|
<div class="d-lg-flex border-bottom">
|
||||||
|
<div class="title w-lg-25">
|
||||||
|
<label for="title">Title</label>
|
||||||
|
</div>
|
||||||
|
<div class="body w-lg-100">
|
||||||
|
<input id="title" autocomplete="off" type="text" name="title" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="d-lg-flex border-bottom">
|
||||||
|
<div class="title w-lg-25">
|
||||||
|
<label for="youtube_id">Youtube ID</label>
|
||||||
|
</div>
|
||||||
|
<div class="body w-lg-100">
|
||||||
|
<input id="youtube_id" autocomplete="off" type="text" name="youtube_id" class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input hidden name="formkey" value="{{v|formkey}}">
|
||||||
|
<div class="d-flex mt-2">
|
||||||
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Start Orgy">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{%else%}
|
||||||
|
<form id="orgy" action="/admin/stop_orgy" method="post">
|
||||||
|
<input hidden name="formkey" value="{{v|formkey}}">
|
||||||
|
<div class="d-flex mt-2">
|
||||||
|
<input autocomplete="off" class="btn btn-primary ml-auto" type="submit" value="Stop Orgy">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{%endif%}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
|
@ -6,132 +6,27 @@
|
||||||
{% include "header.html" %}
|
{% include "header.html" %}
|
||||||
{% include "modals/expanded_image.html" %}
|
{% include "modals/expanded_image.html" %}
|
||||||
{% include "modals/emoji.html" %}
|
{% include "modals/emoji.html" %}
|
||||||
|
{% include "util/macros.html" %}
|
||||||
{% set vlink = '<a href="/id/' ~ v.id ~ '">' %}
|
{% set vlink = '<a href="/id/' ~ v.id ~ '">' %}
|
||||||
<div class="container pb-4">
|
<div class="container pb-4">
|
||||||
<div class="row justify-content-around" id="main-content-row">
|
<div class="row justify-content-around" id="main-content-row">
|
||||||
<div class="col h-100 {% block customPadding %}custom-gutters{% endblock %}" id="main-content-col">
|
<div class="col h-100 {% block customPadding %}custom-gutters{% endblock %}" id="main-content-col">
|
||||||
|
|
||||||
<div class="border-right pb-1 px-3">
|
{{ macros.chat_users_online() }}
|
||||||
<span id="online2" data-bs-html="true" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Users Online" class="text-muted">
|
|
||||||
<i class="far fa-user fa-sm mr-1"></i>
|
|
||||||
<span class="board-chat-count">0</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% macro chat_group_template(id, m) %}
|
|
||||||
<div class="chat-group">
|
|
||||||
<a class="font-weight-bold userlink" target="_blank" {% if m %}style="color:#{{m['namecolor']}}" href="/@{{m['username']}}" {% endif %}><div class="avatar profile-pic-20-wrapper mr-1"><img loading="lazy" class="avatar-pic pp20 mr-1" {% if m %}src="/pp/{{m['user_id']}}"{% endif %}><img class="avatar-hat profile-pic-20-hat hat" loading="lazy" {% if m %}src="{{m['hat']}}"{% endif %}></div>{% if m %}{{m['username']}}{% else %}NULL{% endif %}</a>
|
|
||||||
<span class="text-black time ml-1 mb-3 text-center">{% if m %}{{m['time'] | timestamp}}{% else %}just now{% endif %}</span>
|
|
||||||
<input hidden class="user_id" {% if m %}value="{{m['user_id']}}"{% endif %}>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
{% macro chat_line_template(id, m) %}
|
|
||||||
{% set quote_exists = m and m['quotes'] and messages.get(m['quotes']) %}
|
|
||||||
{% set mentioned = m and vlink in m['text_html'] or (quote_exists and messages[m['quotes']]['user_id'] == v.id) %}
|
|
||||||
<div class="chat-line {% if mentioned %}chat-mention{% endif %}" {% if m %}id="{{id}}"{% endif %}>
|
|
||||||
<div class="d-flex align-items-center">
|
|
||||||
<div class="text-muted chat-line-content">
|
|
||||||
<div class="{% if not (m and m['quotes']) %}d-none{% endif %} quotes" style="font-size:12px">
|
|
||||||
<a class="QuotedMessageLink" {% if m and m['quotes'] %}href="#{{m['quotes']}}"{% endif %}>
|
|
||||||
<i class="fas fa-reply"></i>
|
|
||||||
<span class="text-primary">@<span class="QuotedUser">
|
|
||||||
{%- if quote_exists -%}
|
|
||||||
{{messages[m['quotes']]['username']}}
|
|
||||||
{%- endif -%}
|
|
||||||
</span></span>:
|
|
||||||
<em class="QuotedMessage text-break">
|
|
||||||
{%- if quote_exists -%}
|
|
||||||
{{messages[m['quotes']]['text']}}
|
|
||||||
{%- endif -%}
|
|
||||||
</em>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex">
|
|
||||||
<span class="chat-message text-black text-break">
|
|
||||||
{% if m %}
|
|
||||||
{% if v.slurreplacer %}
|
|
||||||
{{m['text_censored'] | safe}}
|
|
||||||
{% else %}
|
|
||||||
{{m['text_html'] | safe}}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
<span class="text d-none">{% if m %}{{m['text']}}{% endif %}</span>
|
|
||||||
<i class="quote btn fas fa-reply ml-auto" data-nonce="{{g.nonce}}" data-onclick="quote(this)"></i>
|
|
||||||
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
|
|
||||||
<i class="btn del delconfirm fas fa-trash-alt"></i>
|
|
||||||
<i class="btn d-none del delmsg fas fa-trash-alt text-danger" data-nonce="{{g.nonce}}" data-onclick="del(this)"></i>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endmacro %}
|
|
||||||
|
|
||||||
|
|
||||||
<div id="chat-group-template" class="d-none">
|
<div id="chat-group-template" class="d-none">
|
||||||
{{chat_group_template()}}
|
{{macros.chat_group_template()}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="chat-line-template" class="d-none">
|
<div id="chat-line-template" class="d-none">
|
||||||
{{chat_line_template()}}
|
{{macros.chat_line_template()}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="shrink">
|
{{macros.chat_window(vlink)}}
|
||||||
<div id="chat-window" class="container p-0">
|
|
||||||
{% set messages_list = messages.items()|list %}
|
|
||||||
{% for id, m in messages_list %}
|
|
||||||
{% set same = loop.index > 1 and m['user_id'] == messages_list[loop.index-2][1]['user_id'] %}
|
|
||||||
{% if not same %}
|
|
||||||
{% if loop.index > 1 %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
{{chat_group_template(id, m)}}
|
|
||||||
{% endif %}
|
|
||||||
{{chat_line_template(id, m)}}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3"></div>
|
|
||||||
<div id="quotes" class="mt-3 ml-3 mb-2 d-none" style="font-size:12px">
|
|
||||||
<a id="QuotedMessageLink">
|
|
||||||
<i class="fas fa-reply"></i> <span class="text-primary">@<span id="QuotedUser"></span></span>: <em id="QuotedMessage"></em>
|
|
||||||
<button type="button" id="cancel" class="btn btn-secondary">Cancel</button>
|
|
||||||
<input hidden id="quotes_id">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id='message' class="d-none position-relative form-group d-flex">
|
|
||||||
<div class="position-absolute text-muted text-small ml-1" style="bottom: -1.5rem; line-height: 1;">
|
|
||||||
<span id="typing-indicator"></span>
|
|
||||||
<span id="loading-indicator" class="d-none"></span>
|
|
||||||
</div>
|
|
||||||
<span class="my-auto">
|
|
||||||
<i class="btn btn-secondary fas fa-smile-beam" style="font-size:1.3rem!important" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('input-text')" data-bs-toggle="modal" data-bs-target="#emojiModal"></i>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span class="my-auto ml-1">
|
|
||||||
<label class="btn btn-secondary format mb-0">
|
|
||||||
<div class="mr-3" style="font-size:12px"><i class="fas fa-image" style="font-size:1.3rem!important"></i></div>
|
|
||||||
<input autocomplete="off" id="file" accept="image/*" type="file" name="file" {% if g.is_tor %}disabled{% endif %} hidden>
|
|
||||||
</label>
|
|
||||||
<button type="button" class="text-danger text-lg font-weight-bold ml-2 remove-files d-none" data-bs-toggle="tooltip" title="Remove Files">X</button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<textarea id="input-text" minlength="1" maxlength="{% if SITE == 'rdrama.net' %}200{% else %}1000{% endif %}" {% if g.browser in ("iphone","mac") %}style="font-size:16px!important"{% endif %} class="file-ta form-control" placeholder="Message" autocomplete="off" autofocus rows="1"></textarea>
|
|
||||||
|
|
||||||
<i id="chatsend" data-nonce="{{g.nonce}}" data-onclick="send()" class="btn btn-secondary fas fa-reply ml-3 my-auto" style="transform:rotateY(180deg);font-size:1.3rem!important"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col text-left d-none d-lg-block pt-3" style="max-width:300px">
|
{{macros.chat_users_list()}}
|
||||||
<h5>Users Online</h5>
|
|
||||||
<div id="online" class="mt-3"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input id="vid" hidden value="{{v.id}}">
|
<input id="vid" hidden value="{{v.id}}">
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
{%- extends 'root.html' -%}
|
||||||
|
{% block pagetitle -%}Chat{%- endblock %}
|
||||||
|
{% block pagetype %}chat{% endblock %}
|
||||||
|
{% block body_attributes %}class="has_header"{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
{% include "header.html" %}
|
||||||
|
{% include "modals/expanded_image.html" %}
|
||||||
|
{% include "modals/emoji.html" %}
|
||||||
|
{% include "util/macros.html" %}
|
||||||
|
{% set vlink = '<a href="/id/' ~ v.id ~ '">' %}
|
||||||
|
<div class="container pb-4">
|
||||||
|
|
||||||
|
<div class="orgy-top-container">
|
||||||
|
<div class="col text-left d-none d-lg-block pt-3 orgy-info-window-item">
|
||||||
|
<h2>{{orgy.title}}</h1>
|
||||||
|
<div>
|
||||||
|
<lite-youtube videoid="{{orgy.youtube_id}}" params="autoplay=1&modestbranding=1"/>
|
||||||
|
</div>
|
||||||
|
{{macros.chat_users_list()}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="orgy-chat-window-item">
|
||||||
|
<div id="chat-group-template" class="d-none">
|
||||||
|
{{macros.chat_group_template()}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="chat-line-template" class="d-none">
|
||||||
|
{{macros.chat_line_template()}}
|
||||||
|
</div>
|
||||||
|
{{macros.chat_users_online()}}
|
||||||
|
{{macros.chat_window(vlink)}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input id="vid" hidden value="{{v.id}}">
|
||||||
|
<input id="site_name" hidden value="{{SITE_NAME}}">
|
||||||
|
<input id="slurreplacer" hidden value="{{v.slurreplacer}}">
|
||||||
|
<input id="admin_level" hidden value="{{v.admin_level}}">
|
||||||
|
<script defer src="{{'js/vendor/socketio.js' | asset}}"></script>
|
||||||
|
<script defer src="{{'js/chat.js' | asset}}"></script>
|
||||||
|
<script defer src="{{'js/vendor/lozad.js' | asset}}"></script>
|
||||||
|
<script defer src="{{'js/vendor/lite-youtube.js' | asset}}"></script>
|
||||||
|
{% endblock %}
|
|
@ -1,6 +1,6 @@
|
||||||
<h3 style="filter: sepia(100%) saturate(500%) hue-rotate(60deg) drop-shadow(-4px 4px 10px lime);">CURRENT EVENTS:</h3>
|
<h3 style="filter: sepia(100%) saturate(500%) hue-rotate(60deg) drop-shadow(-4px 4px 10px lime);">CURRENT EVENTS:</h3>
|
||||||
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px pink);"><a href="https://rdrama.net/h/vidya/post/182848/contest-photoshop-your-pet-as-a" rel="nofollow">Bing Bing Wahoo Pet Contest</a></h4><sup>Dramacoin prizes!</sup><br>
|
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px pink);"><a href="https://rdrama.net/h/vidya/post/182848/contest-photoshop-your-pet-as-a" rel="nofollow noopener" target="_blank">Bing Bing Wahoo Pet Contest</a></h4><sup>Dramacoin prizes!</sup><br>
|
||||||
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px pink);"><a href="https://rdrama.net/post/184174" rel="nofollow">Independence Gay Grill-Off</a></h4><sup>BADGE</sup><br>
|
<h4 style="filter: sepia(50%) saturate(500%) hue-rotate(10deg) drop-shadow(-1px 1px 5px pink);"><a href="https://rdrama.net/post/184174" rel="nofollow noopener" target="_blank">Independence Gay Grill-Off</a></h4><sup>BADGE</sup><br>
|
||||||
<hr>
|
<hr>
|
||||||
<hr>
|
<hr>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><p>Asking to see who saved comments/posts=1 day ban</p></li>
|
<li><p>Asking to see who saved comments/posts=1 day ban</p></li>
|
||||||
<li><p>You must be over 18 to view this site.</p></li>
|
<li><p>You must be over 18 to view this site.</p></li>
|
||||||
<li><p><strong><a href="https://rdrama.net//post/19711/a-short-guide-on-how-to" rel="nofollow">NO RIGHTWING AGENDAPOSTING.</a></strong></p></li>
|
<li><p><strong><a href="https://rdrama.net//post/19711/a-short-guide-on-how-to" rel="nofollow noopener" target="_blank">NO RIGHTWING AGENDAPOSTING.</a></strong></p></li>
|
||||||
<li><p>Discord users will be banned on sight.</p></li>
|
<li><p>Discord users will be banned on sight.</p></li>
|
||||||
<li><p>Don't post anything illegal.</p></li>
|
<li><p>Don't post anything illegal.</p></li>
|
||||||
<li><p>No sexualizing minors, even as a joke. This includes cartoons.</p></li>
|
<li><p>No sexualizing minors, even as a joke. This includes cartoons.</p></li>
|
||||||
|
@ -45,4 +45,5 @@
|
||||||
<li><p><a href="https://old.reddit.com/r/Egg_IRL" rel="nofollow noopener" target="_blank">/r/Egg_IRL</a></p></li>
|
<li><p><a href="https://old.reddit.com/r/Egg_IRL" rel="nofollow noopener" target="_blank">/r/Egg_IRL</a></p></li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<p style="color: hotpink;">𝐜𝐚𝐫𝐩 𝐰𝐨𝐳 𝐞𝐫𝐞</p>
|
<p style="color: hotpink;">𝐜𝐚𝐫𝐩 𝐰𝐨𝐳 𝐞𝐫𝐞</p>
|
||||||
|
<p>gaming!</p>
|
|
@ -139,6 +139,7 @@
|
||||||
|
|
||||||
{% if request.path.endswith('/chat') %}
|
{% if request.path.endswith('/chat') %}
|
||||||
<link rel="stylesheet" href="{{'css/chat.css' | asset}}">
|
<link rel="stylesheet" href="{{'css/chat.css' | asset}}">
|
||||||
|
<link rel="stylesheet" href="{{'css/orgy.css' | asset}}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|
|
@ -222,3 +222,120 @@
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro chat_users_online() %}
|
||||||
|
<div class="border-right pb-1 px-3">
|
||||||
|
<span id="online2" data-bs-html="true" data-bs-toggle="tooltip" data-bs-placement="bottom" title="Users Online" class="text-muted">
|
||||||
|
<i class="far fa-user fa-sm mr-1"></i>
|
||||||
|
<span class="board-chat-count">0</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro chat_group_template(id, m) %}
|
||||||
|
<div class="chat-group">
|
||||||
|
<a class="font-weight-bold userlink" target="_blank" {% if m %}style="color:#{{m['namecolor']}}" href="/@{{m['username']}}" {% endif %}><div class="avatar profile-pic-20-wrapper mr-1"><img loading="lazy" class="avatar-pic pp20 mr-1" {% if m %}src="/pp/{{m['user_id']}}"{% endif %}><img class="avatar-hat profile-pic-20-hat hat" loading="lazy" {% if m %}src="{{m['hat']}}"{% endif %}></div>{% if m %}{{m['username']}}{% else %}NULL{% endif %}</a>
|
||||||
|
<span class="text-black time ml-1 mb-3 text-center">{% if m %}{{m['time'] | timestamp}}{% else %}just now{% endif %}</span>
|
||||||
|
<input hidden class="user_id" {% if m %}value="{{m['user_id']}}"{% endif %}>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro chat_line_template(id, m, vlink) %}
|
||||||
|
{% set quote_exists = m and m['quotes'] and messages.get(m['quotes']) %}
|
||||||
|
{% set mentioned = m and vlink in m['text_html'] or (quote_exists and messages[m['quotes']]['user_id'] == v.id) %}
|
||||||
|
<div class="chat-line {% if mentioned %}chat-mention{% endif %}" {% if m %}id="{{id}}"{% endif %}>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="text-muted chat-line-content">
|
||||||
|
<div class="{% if not (m and m['quotes']) %}d-none{% endif %} quotes" style="font-size:12px">
|
||||||
|
<a class="QuotedMessageLink" {% if m and m['quotes'] %}href="#{{m['quotes']}}"{% endif %}>
|
||||||
|
<i class="fas fa-reply"></i>
|
||||||
|
<span class="text-primary">@<span class="QuotedUser">
|
||||||
|
{%- if quote_exists -%}
|
||||||
|
{{messages[m['quotes']]['username']}}
|
||||||
|
{%- endif -%}
|
||||||
|
</span></span>:
|
||||||
|
<em class="QuotedMessage text-break">
|
||||||
|
{%- if quote_exists -%}
|
||||||
|
{{messages[m['quotes']]['text']}}
|
||||||
|
{%- endif -%}
|
||||||
|
</em>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="d-flex">
|
||||||
|
<span class="chat-message text-black text-break">
|
||||||
|
{% if m %}
|
||||||
|
{% if v.slurreplacer %}
|
||||||
|
{{m['text_censored'] | safe}}
|
||||||
|
{% else %}
|
||||||
|
{{m['text_html'] | safe}}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
<span class="text d-none">{% if m %}{{m['text']}}{% endif %}</span>
|
||||||
|
<i class="quote btn fas fa-reply ml-auto" data-nonce="{{g.nonce}}" data-onclick="quote(this)"></i>
|
||||||
|
{% if v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
|
||||||
|
<i class="btn del delconfirm fas fa-trash-alt"></i>
|
||||||
|
<i class="btn d-none del delmsg fas fa-trash-alt text-danger" data-nonce="{{g.nonce}}" data-onclick="del(this)"></i>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro chat_window(vlink)%}
|
||||||
|
<div id="shrink">
|
||||||
|
<div id="chat-window" class="container p-0">
|
||||||
|
{% set messages_list = messages.items()|list %}
|
||||||
|
{% for id, m in messages_list %}
|
||||||
|
{% set same = loop.index > 1 and m['user_id'] == messages_list[loop.index-2][1]['user_id'] %}
|
||||||
|
{% if not same %}
|
||||||
|
{% if loop.index > 1 %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{{chat_group_template(id, m)}}
|
||||||
|
{% endif %}
|
||||||
|
{{chat_line_template(id, m, vlink)}}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3"></div>
|
||||||
|
<div id="quotes" class="mt-3 ml-3 mb-2 d-none" style="font-size:12px">
|
||||||
|
<a id="QuotedMessageLink">
|
||||||
|
<i class="fas fa-reply"></i> <span class="text-primary">@<span id="QuotedUser"></span></span>: <em id="QuotedMessage"></em>
|
||||||
|
<button type="button" id="cancel" class="btn btn-secondary">Cancel</button>
|
||||||
|
<input hidden id="quotes_id">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id='message' class="d-none position-relative form-group d-flex">
|
||||||
|
<div class="position-absolute text-muted text-small ml-1" style="bottom: -1.5rem; line-height: 1;">
|
||||||
|
<span id="typing-indicator"></span>
|
||||||
|
<span id="loading-indicator" class="d-none"></span>
|
||||||
|
</div>
|
||||||
|
<span class="my-auto">
|
||||||
|
<i class="btn btn-secondary fas fa-smile-beam" style="font-size:1.3rem!important" data-nonce="{{g.nonce}}" data-onclick="loadEmojis('input-text')" data-bs-toggle="modal" data-bs-target="#emojiModal"></i>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="my-auto ml-1">
|
||||||
|
<label class="btn btn-secondary format mb-0">
|
||||||
|
<div class="mr-3" style="font-size:12px"><i class="fas fa-image" style="font-size:1.3rem!important"></i></div>
|
||||||
|
<input autocomplete="off" id="file" accept="image/*" type="file" name="file" {% if g.is_tor %}disabled{% endif %} hidden>
|
||||||
|
</label>
|
||||||
|
<button type="button" class="text-danger text-lg font-weight-bold ml-2 remove-files d-none" data-bs-toggle="tooltip" title="Remove Files">X</button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<textarea id="input-text" minlength="1" maxlength="{% if SITE == 'rdrama.net' %}200{% else %}1000{% endif %}" {% if g.browser in ("iphone","mac") %}style="font-size:16px!important"{% endif %} class="file-ta form-control" placeholder="Message" autocomplete="off" autofocus rows="1"></textarea>
|
||||||
|
|
||||||
|
<i id="chatsend" data-nonce="{{g.nonce}}" data-onclick="send()" class="btn btn-secondary fas fa-reply ml-3 my-auto" style="transform:rotateY(180deg);font-size:1.3rem!important"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro chat_users_list() %}
|
||||||
|
<div class="col text-left d-none d-lg-block pt-3" style="max-width:300px">
|
||||||
|
<h5>Users Online</h5>
|
||||||
|
<div id="online" class="mt-3"></div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
|
@ -0,0 +1,4 @@
|
||||||
|
CREATE TABLE public.orgies (
|
||||||
|
youtube_id character varying(12) NOT NULL,
|
||||||
|
title character varying(1000) NOT NULL
|
||||||
|
);
|
|
@ -24,6 +24,10 @@ server {
|
||||||
proxy_pass http://localhost:5001/chat;
|
proxy_pass http://localhost:5001/chat;
|
||||||
include includes/headers;
|
include includes/headers;
|
||||||
}
|
}
|
||||||
|
location /old_chat {
|
||||||
|
proxy_pass http://localhost:5001/old_chat;
|
||||||
|
include includes/headers;
|
||||||
|
}
|
||||||
location =/offline.html {
|
location =/offline.html {
|
||||||
alias /rDrama/files/assets/offline.html;
|
alias /rDrama/files/assets/offline.html;
|
||||||
include includes/headers;
|
include includes/headers;
|
||||||
|
|
|
@ -1126,6 +1126,13 @@ CREATE TABLE public.votes (
|
||||||
coins smallint DEFAULT 1 NOT NULL
|
coins smallint DEFAULT 1 NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: orgies, Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
CREATE TABLE public.orgies (
|
||||||
|
youtube_id character varying(12) NOT NULL,
|
||||||
|
title character varying(1000) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: award_relationships id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: award_relationships id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
|
Loading…
Reference in New Issue