stop using inline style/script elements

pull/83/head
Aevann 2022-12-29 16:20:27 +02:00
parent ed323817f5
commit 93e9a42fa3
99 changed files with 1123 additions and 1518 deletions

View File

@ -1,3 +1,5 @@
(window as any).global = window;
import cx from "classnames";
import throttle from "lodash.throttle";
import React, { useCallback, useEffect, useRef, useState } from "react";

View File

@ -0,0 +1,3 @@
p a {
color: #2a96f3;
}

View File

@ -0,0 +1,3 @@
html {
cursor:url('/i/dildo.webp?v=2000'), auto;
}

View File

@ -157,3 +157,25 @@
51% {transform: translateX(100vw) rotate(180deg); top: 0; bottom: unset;}
100% {transform: translateX(-15vw) rotate(180deg); top: 0; bottom: unset;}
}
@keyframes tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{p.award_count("tilt", v)}}deg);}
75% {transform: rotate(-{{p.award_count("tilt", v)}}deg);}
100% {transform: rotate(0deg);}
}
@media (max-width: 720px) {
@keyframes tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{p.award_count("tilt", v)/4}}deg);}
75% {transform: rotate(-{{p.award_count("tilt", v)/4}}deg);}
100% {transform: rotate(0deg);}
}
}
.tilt {
animation-name: tilt;
animation-duration: 60s !important;
animation-iteration-count: infinite !important;
animation-direction: alternate !important;
animation-timing-function: linear !important;
}

View File

@ -0,0 +1,56 @@
.blackjack-cardset {
position: relative;
display: flex;
align-items: center;
margin-bottom: 1rem;
max-width: 470px;
overflow: auto;
box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
-webkit-box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
-moz-box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
}
.blackjack-cardset__PLAYING {
background-image: radial-gradient(circle farthest-corner at 10% 20%, rgba(14, 174, 87, 1) 0%, rgba(12, 116, 117, 1) 90%);
}
.blackjack-cardset__LOST {
background-image: linear-gradient(109.6deg, rgba(14, 11, 56, 1) 11.2%, rgba(239, 37, 37, 1) 91.1%);
}
.blackjack-cardset__PUSHED {
background-image: linear-gradient(110.3deg, rgba(73, 93, 109, 1) 4.3%, rgba(49, 55, 82, 1) 96.7%);
}
.blackjack-cardset__WON {
background-image: radial-gradient( circle farthest-corner at -0.6% 44.4%, rgba(142,252,152,1) 0%, rgba(107,214,250,1) 90% );
}
.blackjack-cardset__BLACKJACK {
background-image: linear-gradient(64.3deg, rgba(254, 122, 152, 0.81) 17.7%, rgba(255, 206, 134, 1) 64.7%, rgba(172, 253, 163, 0.64) 112.1%);
}
.blackjack-cardset .playing-card {
margin-right: -3rem;
min-width: 100px;
}
.blackjack-cardset-value {
z-index: 3;
top: 0;
right: 0;
text-transform: uppercase;
letter-spacing: 2px;
text-align: right;
position: absolute;
background-color: rgba(70, 70, 70, 0.6);
padding: 0.5rem;
color: #DDD;
}
.twentyone-btn {
margin-right: 1rem;
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: 2px;
}

View File

@ -0,0 +1,23 @@
.game_screen-title {
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
opacity: 0.6;
}
.game_screen-title hr {
flex: 1;
margin-left: 0.5rem;
}
#casinoGameResult {
visibility: hidden;
margin-top: 1rem;
}
#casinoGameFeedList {
max-height: 110px;
overflow: auto;
list-style-type: none;
}

View File

@ -0,0 +1,96 @@
.roulette-table-number {
flex: 1;
height: 60px;
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
}
.roulette-table-number__black {
background: black;
}
.roulette-table-number__red {
background: red;
}
.roulette-table-number__green {
background: green;
}
.roulette-table-row {
display: flex;
align-items: center;
justify-content: flex-start;
}
.roulette-table-column {
flex: 1;
height: 60px;
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
writing-mode: vertical-rl;
text-orientation: sideways;
}
.roulette-table-line,
.roulette-table-1to1 {
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
}
.roulette-table-line {
flex: 4;
}
.roulette-table-1to1 {
flex: 2;
}
.roulette-poker-chip {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.roulette-bet-summary--heading {
display: flex;
align-items: center;
}
.roulette-bet-summary--heading p {
margin: 0;
margin-left: 1rem;
font-weight: bolder;
}
.roulette-bet-summary--list {
list-style-type: none;
}
.roulette-poker-chip img:last-child {
position: absolute;
border-radius: 50%;
}
.roulette-total-bets {
text-transform: uppercase;
letter-spacing: 2px;
text-align: right;
}

View File

@ -0,0 +1,22 @@
.slots_reels {
display: flex;
align-items: center;
justify-content: center;
}
.slots_reel {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
border: 2px solid black;
background-color: var(--gray);
border: 1px solid var(--black);
border-radius: 8px;
font-size: 64px;
}
.slots_reel:nth-child(2) {
margin: 0 1rem;
}

View File

@ -0,0 +1,6 @@
body {padding-top: 54px !important}
@media (max-width: 767.98px) {
body {
padding-top: 44px !important
}
}

View File

@ -6458,3 +6458,145 @@ div.markdown {
*::-webkit-scrollbar {
display: none;
}
.shop-tabs {
padding-top: 50px;
}
@media (max-width: 768px) {
#hats-banner {
width: 80%;
}
.shop-tabs {
padding-top: 30px;
}
}
.shop-tab {
display: inline-flex;
max-width: 46.6%;
letter-spacing: 3px;
border-radius: 0;
}
.shop-tab.active {
background-color: var(--primary) !important;
pointer-events: none !important;
cursor: default !important;
}
body {padding-top: 83px !important}
@media (max-width: 767.98px) {
body {
padding-top: 63px !important
}
}
.comment {
margin-top: 0.3rem;
}
body > .container {
padding-left: 20px !important;
padding-right: 20px !important;
}
@media (max-width: 767.98px) {
table {
display: inline-block;
overflow: auto;
}
}
.shop-tabs {
padding-top: 50px;
}
@media (max-width: 768px) {
#shop-banner {
width: 80%;
}
.shop-tabs {
padding-top: 30px;
}
}
.shop-tab {
display: inline-flex;
max-width: 46.6%;
letter-spacing: 3px;
border-radius: 0;
}
.shop-tab.active {
background-color: var(--primary) !important;
pointer-events: none !important;
cursor: default !important;
}
.star1 circle {r: 0.5;}
.star2 circle {r: 0.75;}
.star3 circle {r: 1.0;}
.star4 circle {r: 1.2;}
.star5 circle {r: 1.5;}
.emoji2 {
/*background: None!important;*/
width:60px;
height: 85px;
overflow: hidden;
border: none
}
.emoji2 > img {
-o-object-fit: contain;
object-fit: contain;
}
.bg-image {
padding: 0.25rem;
width: 15rem;
height: 10rem;
object-fit: cover;
}
.bg-button {
margin: 0.25rem;
padding: 0;
}
.dismiss-beg {
color: #919191;
float: left;
font-size: 14px;
padding: 0.25rem 0.7rem 2rem 0.7rem;
}
#mobile-prompt + .bs-tooltip-bottom {
transform: None !important;
inset: 0px 0px auto auto !important;
}
.mod-rdrama:before {
content: '(((';
}
.mod-rdrama:after {
content: ')))';
}
#emojiTabs {height: 80%;}
@media (max-width: 650px) {
#emojiTabs {height: 100%;}
#emojiModalInternalDivIDK {margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 3rem !important; padding-bottom: 0 !important;}
#emoji-modal-tabs-container {
overflow-x: auto;
}
#emoji-modal-tabs {
white-space: nowrap;
flex-wrap: nowrap;
}
#emoji-modal-tabs li {
display: inline-block;
}
}

View File

@ -0,0 +1,3 @@
* :not(img[src="/i/hand.webp"] + img, img.golden, img[g], img[glow], .live-circle) {
animation: unset !important;
}

View File

@ -0,0 +1,7 @@
@media (max-width: 427px) {
.smol-fp {
font-size: 2.7vw;
padding-left: 2.5vw;
padding-right: 2.1vw;
}
}

View File

@ -0,0 +1,22 @@
#post-title, #post-content p {
--color2: #cc4145;
--color1: rgb(12, 128, 101);
font-family: "Open Sans", sans-serif;
background: repeating-linear-gradient(
45deg, var(--color2), var(--color2) 10px,
var(--color1) 11px, var(--color1) 30px
);
background-clip: text;
color: transparent;
-webkit-background-clip: text;
animation: 45s linear 0s infinite candycorn-move;
}
#post-title a {
color: transparent !important;
}
@keyframes candycorn-move {
from {background-position: 0px;}
to {background-position: 1000px;}
}

View File

@ -0,0 +1,8 @@
#banner-skybox {
fill: url(#skybox-gradient-night)
}
#banner-window-1, #banner-window-2 {
filter: drop-shadow(0 0 50px orange);
fill: palegoldenrod;
}

View File

@ -0,0 +1,13 @@
:root {
--opacity-frost: 0.25;
}
.frost {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 200px 10px rgba(255, 255, 255, var(--opacity-frost)) inset;
pointer-events: none;
z-index: 1050;
}

View File

@ -0,0 +1,12 @@
#post-root::before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 57px;
width: 100%;
background: url('/assets/event/images/lights.webp?v=1');
animation: lights 1s infinite steps(2);
pointer-events: none;
z-index: 1;
}

View File

@ -0,0 +1,16 @@
#canvas-snowed-in-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 9998;
opacity: 1;
pointer-events: none;
}
#canvas-snowed-in-lines {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
opacity: 0.0;
pointer-events: none;
}

View File

@ -0,0 +1,4 @@
const root = document.querySelector(':root');
const count = 5;
const opacity = count * 0.1;
root.style.setProperty('--opacity-frost', opacity);

View File

@ -0,0 +1,8 @@
const audio = new Audio("{{song}}");
audio.loop=true;
audio.play();
window.addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true});
prepare_to_pause(audio)

View File

@ -702,3 +702,5 @@ function snow(flakesMax) {
return this;
}
snow(80)

View File

@ -0,0 +1,34 @@
function submitAddAlt(element) {
if (!element || !element.form) return;
const isLinking = element.id == 'add-alt-form-link';
const otherElement = isLinking ? document.getElementById('add-alt-form-delink') : document.getElementById('add-alt-form-link');
if (!otherElement) return;
element.disabled = true;
otherElement.disabled = true;
element.classList.add('disabled');
otherElement.classList.add('disabled');
const form = new FormData();
if (!isLinking) form.append('deleted', 'true');
form.append('other_username', document.getElementById('link-input-other').value);
const xhr = createXhrWithFormKey('/@{{u.username}}/alts/', 'POST', form);
xhr[0].onload = function() {
let data;
try {
data = JSON.parse(xhr[0].response);
}
catch(e) {
console.log(e);
}
if (xhr[0].status >= 200 && xhr[0].status < 300) {
showToast(true, getMessageFromJsonData(true, data));
window.location.reload();
} else {
showToast(false, getMessageFromJsonData(false, data));
element.disabled = false;
otherElement.disabled = false;
element.classList.remove('disabled');
otherElement.classList.remove('disabled');
}
}
xhr[0].send(xhr[1]);
}

View File

@ -0,0 +1,40 @@
const IMAGE_FORMATS = document.getElementById('IMAGE_FORMATS')
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-asset').disabled = false;
}
})

View File

@ -0,0 +1,4 @@
function unbanDomain(t, domain) {
postToastSwitch(t,'/admin/unban_domain/' + domain);
t.parentElement.parentElement.remove();
}

View File

@ -214,11 +214,4 @@ function initializeBlackjack() {
}
}
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
initializeBlackjack();
} else {
document.addEventListener("load", initializeBlackjack);
}
initializeBlackjack();

View File

@ -5,15 +5,6 @@
* - Leaderboard
*/
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
initializeGame();
} else {
document.addEventListener("load", initializeGame);
}
function initializeGame() {
updateFeed();
updateLeaderboard();
@ -199,3 +190,5 @@ function drawFromDeck() {
}, 600);
} catch { }
}
initializeGame();

View File

@ -377,11 +377,4 @@ function handleRouletteResponse(xhr) {
}
}
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
initializeGame();
} else {
document.addEventListener("load", initializeGame);
}
initializeGame();

View File

@ -0,0 +1,2 @@
if (location.hash != 'context')
location.hash = 'context'

View File

@ -60,7 +60,7 @@ function popclick(e) {
popover.getElementsByClassName('pop-postcount')[0].innerHTML = author["post_count"]
popover.getElementsByClassName('pop-commentcount')[0].innerHTML = author["comment_count"]
popover.getElementsByClassName('pop-coins')[0].innerHTML = author["coins"]
popover.getElementsByClassName('pop-viewmore')[0].href = author["url"]
popover.getElementsByClassName('pop-view_more')[0].href = author["url"]
popover.getElementsByClassName('pop-created-date')[0].innerHTML = author["created_date"]
}, 5);
}

View File

@ -273,16 +273,7 @@ function bs_trigger(e) {
}
}
let bsTriggerOnReady = function() {
bs_trigger(document);
}
if (document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)) {
bsTriggerOnReady();
} else {
document.addEventListener("load", bsTriggerOnReady);
}
bs_trigger(document);
function escapeHTML(unsafe) {
return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
@ -457,3 +448,28 @@ document.addEventListener("click", function(e){
else if (element.classList.contains('gif-cat-overlay'))
searchGifs(e.target.firstElementChild.innerHTML);
});
if (window.matchMedia('(display-mode: minimal-ui)')['matches']) {
const links = document.querySelectorAll('a[data-target="t"]');
for (const link of links) {
link.removeAttribute("target");
}
}
if (document.getElementById('gbrowser').value == 'apple') {
const videos = document.querySelectorAll('video')
for (const video of videos) {
const link = video.src
const htmlString = `
<a rel="nofollow noopener" href="${link}" target="_blank">
<div class="d-flex justify-content-between align-items-center border rounded p-2 mb-3 download-video">
<span>${link}</span>
<i class="fas fa-external-link-alt text-small"></i>
</div>
</a>`
const div = document.createElement('div');
div.innerHTML = htmlString;
video.after(div)
}
}

View File

@ -0,0 +1,4 @@
for (const x of ['css','profilecss']) {
const ta = document.getElementById(`${x}-textarea`);
autoExpand(ta);
}

View File

@ -0,0 +1,9 @@
fart = Math.floor(Math.random() * 5) + 1
let audio = new Audio(`/assets/images/${fart}.webp`);
audio.play();
if (audio.paused) {
document.addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true})
}

View File

@ -0,0 +1,4 @@
const flairchanged = document.getElementById('flairchanged').value
const date = formatDate(new Date(flairchanged*1000));
const text = ` - Your flair has been locked until ${date}`;
document.getElementById('flair-body').value += text;

View File

@ -0,0 +1,24 @@
const fp_token = document.getElementById('fp_token').value
function fp(fp) {
const xhr = new XMLHttpRequest();
xhr.open("POST", '/fp/'+fp);
xhr.setRequestHeader('xhr', 'xhr');
const form = new FormData()
form.append("formkey", formkey());
xhr.send(form);
};
const fpPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.onload = resolve;
script.onerror = reject;
script.async = true;
script.src = "{{'js/vendor/fp.js' | asset}}";
document.head.appendChild(script);
})
.then(() => FingerprintJS.load({token: fp_token}));
fpPromise
.then(fp => fp.get())
.then(result => {fp(result.visitorId);})

View File

@ -0,0 +1,11 @@
function equip_hat(t, hat_id, hat_name) {
const profile_pic_hat = document.getElementById("profile-pic-35-hat");
function extra_actions(xhr) {
if(xhr.status == 200) {
profile_pic_hat.src = `/i/hats/${hat_name}.webp?h=7`
profile_pic_hat.classList.remove('d-none')
}
}
postToastSwitch(t, `/equip_hat/${hat_id}`, `equip-${hat_id}`, `unequip-${hat_id}`, `d-none`, extra_actions)
}

View File

@ -1,41 +0,0 @@
if (typeof showNewCommentCounts === 'undefined') {
function showNewCommentCounts(postId, newTotal) {
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
const lastCount = comments[postId]
if (lastCount) {
const newComments = newTotal - lastCount.c
if (newComments > 0) {
elems = document.getElementsByClassName(`${postId}-new-comments`)
for (const elem of elems)
{
elem.textContent = ` (+${newComments})`
elem.classList.remove("d-none")
}
}
}
}
const LAST_CACHE_CLEAN_ID = "last-cache-clean"
const EXPIRE_INTERVAL_MILLIS = 5 * 24 * 60 * 60 * 1000
const CACHE_CLEAN_INTERVAL = 60 * 60 * 1000
function cleanCache() {
const lastCacheClean = JSON.parse(localStorage.getItem(LAST_CACHE_CLEAN_ID)) || Date.now()
const now = Date.now()
if (now - lastCacheClean > CACHE_CLEAN_INTERVAL) {
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
for (let [key, value] of Object.entries(comments)) {
if (now - value.t > EXPIRE_INTERVAL_MILLIS) {
delete comments[key]
}
}
localStorage.setItem("comment-counts", JSON.stringify(comments))
}
localStorage.setItem(LAST_CACHE_CLEAN_ID, JSON.stringify(now))
}
setTimeout(cleanCache, 500)
}

View File

@ -0,0 +1 @@
document.getElementById('2fa_token').focus();

View File

@ -35,15 +35,6 @@ const lotteryOnReady = function () {
});
};
if (
document.readyState === "complete" ||
(document.readyState !== "loading" && !document.documentElement.doScroll)
) {
lotteryOnReady();
} else {
document.addEventListener("load", lotteryOnReady);
}
function purchaseLotteryTicket() {
return handleLotteryRequest("buy", "POST");
}
@ -194,3 +185,5 @@ function formatTimeLeft(secondsLeft) {
return `${hours}h, ${minutes}m, ${seconds}s`;
}
lotteryOnReady();

View File

@ -0,0 +1,16 @@
if (!window.matchMedia('(display-mode: minimal-ui)')['matches']) {
if (window.innerWidth <= 737) {
const tt = bootstrap.Tooltip.getOrCreateInstance(document.getElementById('mobile-prompt'))
tt.show()
document.getElementsByClassName('tooltip')[0].onclick = function(e) {
tt.hide()
const xhr = new XMLHttpRequest();
xhr.withCredentials=true;
xhr.open("POST", '/dismiss_mobile_tip', true);
xhr.setRequestHeader('xhr', 'xhr');
xhr.send();
if (!e.target.classList.contains('dismiss-beg'))
location.href = "/app"
}
}
}

View File

@ -0,0 +1,22 @@
function more_comments(cid, sort) {
btn = document.getElementById(`btn-${cid}`);
btn.disabled = true;
btn.innerHTML = "Requesting...";
const form = new FormData();
form.append("formkey", formkey());
form.append("sort", sort);
const xhr = new XMLHttpRequest();
xhr.open("get", `/more_comments/${cid}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
if (xhr.status==200) {
let e = document.getElementById(`replies-of-c_${cid}`)
e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
bs_trigger(e)
highlight_unread("old-comment-counts")
}
btn.disabled = false;
}
xhr.send(form)
}

View File

@ -0,0 +1,44 @@
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
let pid
let pcc
for (let twoattrs of document.getElementsByClassName("twoattrs")) {
twoattrs = twoattrs.value.split(',')
pid = twoattrs[0]
pcc = twoattrs[1]
const lastCount = comments[pid]
if (lastCount) {
const newComments = pcc - lastCount.c
if (newComments > 0) {
elems = document.getElementsByClassName(`${pid}-new-comments`)
for (const elem of elems)
{
elem.textContent = ` (+${newComments})`
elem.classList.remove("d-none")
}
}
}
}
const LAST_CACHE_CLEAN_ID = "last-cache-clean"
const EXPIRE_INTERVAL_MILLIS = 5 * 24 * 60 * 60 * 1000
const CACHE_CLEAN_INTERVAL = 60 * 60 * 1000
function cleanCache() {
const lastCacheClean = JSON.parse(localStorage.getItem(LAST_CACHE_CLEAN_ID)) || Date.now()
const now = Date.now()
if (now - lastCacheClean > CACHE_CLEAN_INTERVAL) {
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
for (let [key, value] of Object.entries(comments)) {
if (now - value.t > EXPIRE_INTERVAL_MILLIS) {
delete comments[key]
}
}
localStorage.setItem("comment-counts", JSON.stringify(comments))
}
localStorage.setItem(LAST_CACHE_CLEAN_ID, JSON.stringify(now))
}
setTimeout(cleanCache, 500)

View File

@ -16,8 +16,8 @@ function urlB64ToUint8Array(base64String) {
}
function updateSubscriptionOnServer(subscription, apiEndpoint) {
const formData = new FormData();
formData.append("subscription_json", JSON.stringify(subscription));
const formData = new FormData();
formData.append("subscription_json", JSON.stringify(subscription));
const xhr = createXhrWithFormKey(
apiEndpoint,
@ -68,3 +68,9 @@ function registerServiceWorker(serviceWorkerUrl, applicationServerPublicKey, api
}
return swRegistration;
}
registerServiceWorker(
"/assets/js/service_worker.js",
document.getElementById('VAPID_PUBLIC_KEY').value,
"/push_subscribe"
)

View File

@ -0,0 +1,7 @@
function removeMod(e) {
sendFormXHR(e,
() => {
e.target.parentElement.parentElement.remove();
}
)
}

View File

@ -118,3 +118,14 @@ document.onpaste = function(event) {
}
}
}
const sr_toggle = document.getElementById("slurreplacer");
const sr_link = document.getElementById('slurreplacer-perma-link');
const pr_toggle = document.getElementById("profanityreplacer");
const pr_link = document.getElementById('profanityreplacer-perma-link');
sr_toggle.addEventListener('change', function () {
sr_link.hidden = !sr_toggle.checked;
});
pr_toggle.addEventListener('change', function () {
pr_link.hidden = !pr_toggle.checked;
});

View File

@ -0,0 +1,26 @@
function highlight_unread(localstoragevar) {
const comments = JSON.parse(localStorage.getItem(localstoragevar)) || {}
lastCount = comments[pid]
if (lastCount)
{
const comms = document.getElementById("comms").value
for (const c of comms) {
if (c[1]*1000 > lastCount.t) {
try {document.getElementById(`comment-${c[0]}-only`).classList.add('unread')}
catch(e) {}
}
}
}
}
highlight_unread("comment-counts")
if (!location.href.includes("?context")) {
localStorage.setItem("old-comment-counts", localStorage.getItem("comment-counts"))
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
const newTotal = pcc || ((comments[pid] || {c: 0}).c + 1)
comments[pid] = {c: newTotal, t: Date.now()}
localStorage.setItem("comment-counts", JSON.stringify(comments))
}

View File

@ -0,0 +1,11 @@
history.pushState(null, null, '{{p.permalink}}');
localStorage.setItem("post-title", "")
localStorage.setItem("post-text", "")
localStorage.setItem("post-url", "")
localStorage.setItem("sub", "")
localStorage.setItem("post-notify", true)
localStorage.setItem("post-new", false)
localStorage.setItem("post-nsfw", false)
localStorage.setItem("post-private", false)
localStorage.setItem("post-ghost", false)

View File

@ -1,3 +1,5 @@
const IMAGE_FORMATS = document.getElementById('IMAGE_FORMATS')
document.getElementById('post-title').value = localStorage.getItem("post-title")
document.getElementById('post-text').value = localStorage.getItem("post-text")
document.getElementById('post-url').value = localStorage.getItem("post-url")
@ -201,3 +203,8 @@ document.addEventListener('keydown', (e) => {
});
checkRepost();
if (location.href == '/submit') {
const sub = document.getElementById('sub')
if (sub) sub.value = localStorage.getItem("sub")
}

View File

@ -0,0 +1,63 @@
const IMAGE_FORMATS = document.getElementById('IMAGE_FORMATS')
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-hat').disabled = false;
}
})
function approve_hat(t, name) {
postToast(t, `/admin/approve/hat/${name}`,
{
"description": document.getElementById(`${name}-description`).value,
"name": document.getElementById(`${name}-name`).value,
"price": document.getElementById(`${name}-price`).value,
},
() => {
document.getElementById(`${name}-hat`).remove()
}
);
}
function remove_hat(t, name) {
postToast(t, `/remove/hat/${name}`,
{
},
() => {
document.getElementById(`${name}-hat`).remove()
}
);
}

View File

@ -0,0 +1,62 @@
const IMAGE_FORMATS = document.getElementById('IMAGE_FORMATS')
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-marsey').disabled = false;
}
})
function approve_marsey(t, name) {
postToast(t, `/admin/approve/marsey/${name}`,
{
"tags": document.getElementById(`${name}-tags`).value,
"name": document.getElementById(`${name}-name`).value,
},
() => {
document.getElementById(`${name}-marsey`).remove()
}
);
}
function remove_marsey(t, name) {
postToast(t, `/remove/marsey/${name}`,
{
},
() => {
document.getElementById(`${name}-marsey`).remove()
}
);
}

View File

@ -0,0 +1,20 @@
function view_more(pid,sort,offset,ids) {
btn = document.getElementById("viewbtn");
btn.disabled = true;
btn.innerHTML = "Requesting...";
const form = new FormData();
const xhr = new XMLHttpRequest();
xhr.open("get", `/view_more/${pid}/${sort}/${offset}?ids=${ids}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
if (xhr.status==200) {
let e = document.getElementById(`view_more-${offset}`);
e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
bs_trigger(e)
highlight_unread("old-comment-counts")
}
btn.disabled = false;
}
xhr.send(form)
}

View File

@ -170,7 +170,7 @@ class Comment(Base):
@property
@lazy
def morecomments(self):
def more_comments(self):
return f"{self.post.permalink}/{self.id}?context=0#context"
@property

View File

@ -90,7 +90,6 @@ class User(Base):
chudded_by = Column(Integer, ForeignKey("users.id"))
over_18 = Column(Boolean, default=False)
hidevotedon = Column(Boolean, default=False)
highlightcomments = Column(Boolean, default=True)
slurreplacer = Column(Integer, default=1)
profanityreplacer = Column(Integer, default=1)
flairchanged = Column(Integer)

View File

@ -13,8 +13,6 @@ def session_init():
@app.before_request
def before_request():
g.nonce = None
if request.host != SITE:
abort(403, "Unauthorized host provided!")
@ -72,11 +70,11 @@ CSP = {
"base-uri": "'self'",
"font-src": "'self'",
"style-src-elem": "'self' 'nonce-{nonce}'",
"style-src-elem": "'self'",
"style-src-attr": "'unsafe-inline'",
"style-src": "'self' 'unsafe-inline'",
"script-src-elem": "'self' 'nonce-{nonce}' challenges.cloudflare.com",
"script-src-elem": "'self' challenges.cloudflare.com",
"script-src-attr": "'unsafe-inline'",
"script-src": "'self' 'unsafe-inline' challenges.cloudflare.com",
@ -105,9 +103,8 @@ def after_request(response:Response):
_set_cloudflare_cookie(response)
_commit_and_close_db()
if g.nonce:
response.headers.add("Report-To", {"group":"csp","max_age":10886400,"endpoints":[{"url":"/csp_violations"}]})
response.headers.add("Content-Security-Policy", CSP_str.format(nonce=g.nonce))
response.headers.add("Report-To", {"group":"csp","max_age":10886400,"endpoints":[{"url":"/csp_violations"}]})
response.headers.add("Content-Security-Policy", CSP_str)
return response

View File

@ -179,10 +179,10 @@ def post_id(pid, anything=None, v=None, sub=None):
sort=sort, render_replies=True, offset=offset, sub=post.subr,
fart=get_setting('fart_mode'))
@app.get("/viewmore/<int:pid>/<sort>/<offset>")
@app.get("/view_more/<int:pid>/<sort>/<offset>")
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
@auth_desired_with_logingate
def viewmore(v, pid, sort, offset):
def view_more(v, pid, sort, offset):
post = get_post(pid, v=v)
try:
offset = int(offset)
@ -234,10 +234,10 @@ def viewmore(v, pid, sort, offset):
return render_template("comments.html", v=v, comments=comments, p=post, ids=list(ids), render_replies=True, pid=pid, sort=sort, offset=offset)
@app.get("/morecomments/<int:cid>")
@app.get("/more_comments/<int:cid>")
@limiter.limit(DEFAULT_RATELIMIT_SLOWER)
@auth_desired_with_logingate
def morecomments(v, cid):
def more_comments(v, cid):
try: cid = int(cid)
except: abort(404)

View File

@ -178,7 +178,6 @@ def settings_personal_post(v):
updated = updated or update_flag("hidevotedon", "hidevotedon")
updated = updated or update_flag("cardview", "cardview")
updated = updated or update_flag("highlightcomments", "highlightcomments")
updated = updated or update_flag("newtab", "newtab")
updated = updated or update_flag("newtabexternal", "newtabexternal")
updated = updated or update_flag("nitter", "nitter")
@ -605,8 +604,6 @@ def settings_css_get(v:User):
def settings_css(v):
if v.agendaposter: abort(400, "Agendapostered users can't edit CSS!")
css = request.values.get("css", v.css).strip().replace('\\', '').strip()[:CSS_LENGTH_LIMIT]
if '</style' in css.lower():
abort(400, "Please message @Aevann if you get this error")
v.css = css
g.db.add(v)

View File

@ -390,10 +390,22 @@ def get_css(id):
try: id = int(id)
except: abort(404)
css = g.db.query(User.css).filter_by(id=id).one_or_none()
css, bg = g.db.query(User.profilecss, User.profile_background).filter_by(id=id).one_or_none()
if bg:
if not css: css = ''
css += f'''
body {{
background:url("{bg}") center center fixed;
background-color: rgb(var(--background));
}}
'''
if 'anime/' not in bg and not bg.startswith('/images/'):
css += 'body {background-size: cover}'
if not css: abort(404)
resp = make_response(css[0] or "")
resp = make_response(css)
resp.headers["Content-Type"] = "text/css"
return resp
@ -402,10 +414,15 @@ def get_profilecss(id):
try: id = int(id)
except: abort(404)
css = g.db.query(User.profilecss).filter_by(id=id).one_or_none()
css, bg = g.db.query(User.profilecss, User.profile_background).filter_by(id=id).one_or_none()
if bg:
if not css: css = ''
css += f"body {{background-image: url('{bg}') !important}}"
if not css: abort(404)
resp = make_response(css[0] or "")
resp = make_response(css)
resp.headers["Content-Type"] = "text/css"
return resp

View File

@ -1,5 +1,4 @@
import time
import secrets
from flask import g, request, session
from files.classes.clients import ClientAuth
@ -72,9 +71,6 @@ def get_logged_in_user():
g.is_api_or_xhr = bool((v and v.client) or request.headers.get("xhr"))
if not g.is_api_or_xhr:
g.nonce = secrets.token_urlsafe(31)
return v
def auth_desired(f):

View File

@ -66,40 +66,5 @@
</section>
{% endif %}
<script nonce="{{g.nonce}}">
function submitAddAlt(element) {
if (!element || !element.form) return;
const isLinking = element.id == 'add-alt-form-link';
const otherElement = isLinking ? document.getElementById('add-alt-form-delink') : document.getElementById('add-alt-form-link');
if (!otherElement) return;
element.disabled = true;
otherElement.disabled = true;
element.classList.add('disabled');
otherElement.classList.add('disabled');
const form = new FormData();
if (!isLinking) form.append('deleted', 'true');
form.append('other_username', document.getElementById('link-input-other').value);
const xhr = createXhrWithFormKey('/@{{u.username}}/alts/', 'POST', form);
xhr[0].onload = function() {
let data;
try {
data = JSON.parse(xhr[0].response);
}
catch(e) {
console.log(e);
}
if (xhr[0].status >= 200 && xhr[0].status < 300) {
showToast(true, getMessageFromJsonData(true, data));
window.location.reload();
} else {
showToast(false, getMessageFromJsonData(false, data));
element.disabled = false;
otherElement.disabled = false;
element.classList.remove('disabled');
otherElement.classList.remove('disabled');
}
}
xhr[0].send(xhr[1]);
}
</script>
<script defer src="{{'js/admin/alts.js' | asset}}"></script>
{% endblock %}

View File

@ -54,13 +54,4 @@
</form>
<style nonce="{{g.nonce}}">
@media (max-width: 767.98px) {
table {
display: inline-block;
overflow: auto;
}
}
</style>
{% endblock %}

View File

@ -3,12 +3,7 @@
{% block content %}
<script nonce="{{g.nonce}}">
function unbanDomain(t, domain) {
postToastSwitch(t,'/admin/unban_domain/' + domain);
t.parentElement.parentElement.remove();
}
</script>
<script defer src="{{'js/banned_domains.js' | asset}}"></script>
<div class="overflow-x-auto mt-2">
<table class="table table-striped mb-5" id="domains-table">

View File

@ -49,30 +49,4 @@
<script defer src="{{'js/fireflies.js' | asset}}"></script>
{% endif %}
{% if p.award_count("tilt", v) %}
<style nonce="{{g.nonce}}">
@keyframes post-tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{p.award_count("tilt", v)}}deg);}
75% {transform: rotate(-{{p.award_count("tilt", v)}}deg);}
100% {transform: rotate(0deg);}
}
@media (max-width: 720px) {
@keyframes post-tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{p.award_count("tilt", v)/4}}deg);}
75% {transform: rotate(-{{p.award_count("tilt", v)/4}}deg);}
100% {transform: rotate(0deg);}
}
}
#post-root {
animation-name: post-tilt;
animation-duration: 60s !important;
animation-iteration-count: infinite !important;
animation-direction: alternate !important;
animation-timing-function: linear !important;
}
</style>
{% endif %}
</div>

View File

@ -1,7 +1,7 @@
{% extends "casino/game_screen.html" %}
{% block script %}
<script defer src="{{'js/blackjack_screen.js' | asset}}"></script>
<script defer src="{{'js/casino/blackjack_screen.js' | asset}}"></script>
{% endblock %}
{% block screen %}
@ -11,64 +11,7 @@
{% endblock %}
{% block actions %}
<style nonce="{{g.nonce}}">
.blackjack-cardset {
position: relative;
display: flex;
align-items: center;
margin-bottom: 1rem;
max-width: 470px;
overflow: auto;
box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
-webkit-box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
-moz-box-shadow: 1px 1px 5px 1px rgba(60, 60, 60, 0.81) inset;
}
.blackjack-cardset__PLAYING {
background-image: radial-gradient(circle farthest-corner at 10% 20%, rgba(14, 174, 87, 1) 0%, rgba(12, 116, 117, 1) 90%);
}
.blackjack-cardset__LOST {
background-image: linear-gradient(109.6deg, rgba(14, 11, 56, 1) 11.2%, rgba(239, 37, 37, 1) 91.1%);
}
.blackjack-cardset__PUSHED {
background-image: linear-gradient(110.3deg, rgba(73, 93, 109, 1) 4.3%, rgba(49, 55, 82, 1) 96.7%);
}
.blackjack-cardset__WON {
background-image: radial-gradient( circle farthest-corner at -0.6% 44.4%, rgba(142,252,152,1) 0%, rgba(107,214,250,1) 90% );
}
.blackjack-cardset__BLACKJACK {
background-image: linear-gradient(64.3deg, rgba(254, 122, 152, 0.81) 17.7%, rgba(255, 206, 134, 1) 64.7%, rgba(172, 253, 163, 0.64) 112.1%);
}
.blackjack-cardset .playing-card {
margin-right: -3rem;
min-width: 100px;
}
.blackjack-cardset-value {
z-index: 3;
top: 0;
right: 0;
text-transform: uppercase;
letter-spacing: 2px;
text-align: right;
position: absolute;
background-color: rgba(70, 70, 70, 0.6);
padding: 0.5rem;
color: #DDD;
}
.twentyone-btn {
margin-right: 1rem;
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: 2px;
}
</style>
<link rel="stylesheet" href="{{('css/casino/blackjack_screen.css') | asset}}">
<div role="group" class="btn-group">
<button type="button" id="twentyone-DEAL" class="btn btn-primary twentyone-btn" onclick="deal()">Deal</button>

View File

@ -1,155 +1,10 @@
{% extends "default.html" %}
{% block pagetitle %}{{game.capitalize()}}{% endblock %}
{% block content %}
<style nonce="{{g.nonce}}">
.game_screen-title {
display: flex;
align-items: center;
justify-content: center;
text-transform: uppercase;
opacity: 0.6;
}
<link rel="stylesheet" href="{{('css/casino/game_screen.css') | asset}}">
<script defer src="{{'js/casino/game_screen.js' | asset}}"></script>
.game_screen-title hr {
flex: 1;
margin-left: 0.5rem;
}
#casinoGameResult {
visibility: hidden;
margin-top: 1rem;
}
#casinoGameFeedList {
max-height: 110px;
overflow: auto;
list-style-type: none;
}
</style>
<script defer src="{{'js/game_screen.js' | asset}}"></script>
{% block script %} {% endblock %}
<style nonce="{{g.nonce}}">
@keyframes drawing {
from {
left: 0;
opacity: 1;
}
to {
left: 100px;
opacity: 0;
}
}
.drawing-a-card {
animation: drawing 1s ease-in-out;
}
.playing-card-deck {
position: relative;
z-index: 3;
box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
-webkit-box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
-moz-box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
}
.flipped-playing-card {
position: absolute;
width: 100px;
height: 150px;
border-radius: 4px;
border: 1px solid #21262C;
background-color: #FF66AC;
transform: scale(0.7);
}
.playing-card {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 150px;
border-radius: 4px;
border: 1px solid #21262C;
background-color: #FFF;
box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
-webkit-box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
-moz-box-shadow: -5px 5px 5px 0px rgba(60, 60, 60, 0.56);
}
.playing-card_red {
color: #ff0000;
}
.playing-card_black {
color: #333;
}
.playing-card_small {
font-size: 18px;
position: absolute;
}
.playing-card_large {
font-size: 48px;
text-align: center;
}
.playing-card_topright {
top: 6px;
right: 6px;
}
.playing-card_bottomleft {
bottom: 6px;
left: 6px;
transform: scaleX(-1) scaleY(-1);
}
#casinoGameResult, #casinoGameStats {
text-transform: uppercase;
text-align: center;
letter-spacing: 3px;
font-weight: 700;
}
.casino-game-leaderboard {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 1rem;
}
.casino-game-leaderboard-info {
text-align: right;
text-transform: uppercase;
letter-spacing: 2px;
}
.leaderboard-marsey-trophy {
position: relative;
width: 100px;
height: 100px;
}
.leaderboard-marsey-trophy__marsey {
position: relative;
z-index: 1;
height: 100px;
}
.leaderboard-marsey-trophy__trophy {
position: absolute;
right: 0;
bottom: 0;
z-index: 2;
font-size: 48px;
}
</style>
{% block script %}{% endblock %}
<div id="casino-game-wrapper" data-game="{{game}}" class="container-fluid" style="max-width: 500px">
<div class="row row-cols-1">

View File

@ -1,111 +1,13 @@
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
{% block script %}
<script defer src="{{'js/roulette_screen.js' | asset}}"></script>
<script defer src="{{'js/casino/roulette_screen.js' | asset}}"></script>
{% endblock %}
{% block screen %}
<style nonce="{{g.nonce}}">
.roulette-table-number {
flex: 1;
height: 60px;
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
}
.roulette-table-number__black {
background: black;
}
.roulette-table-number__red {
background: red;
}
.roulette-table-number__green {
background: green;
}
.roulette-table-row {
display: flex;
align-items: center;
justify-content: flex-start;
}
.roulette-table-column {
flex: 1;
height: 60px;
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
writing-mode: vertical-rl;
text-orientation: sideways;
}
.roulette-table-line,
.roulette-table-1to1 {
border: 1px solid white;
background: green;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bolder;
}
.roulette-table-line {
flex: 4;
}
.roulette-table-1to1 {
flex: 2;
}
.roulette-poker-chip {
display: flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.roulette-bet-summary--heading {
display: flex;
align-items: center;
}
.roulette-bet-summary--heading p {
margin: 0;
margin-left: 1rem;
font-weight: bolder;
}
.roulette-bet-summary--list {
list-style-type: none;
}
.roulette-poker-chip img:last-child {
position: absolute;
border-radius: 50%;
}
.roulette-total-bets {
text-transform: uppercase;
letter-spacing: 2px;
text-align: right;
}
</style>
<div id="roulette-table">
</div>
<link rel="stylesheet" href="{{('css/casino/roulette_screen.css') | asset}}">
<div id="roulette-table">
</div>
{% endblock %}
{% block actiontext %}

View File

@ -1,58 +1,35 @@
{% extends "casino/game_screen.html" %} {% block result %} N/A {% endblock %}
{% block script %}
<script defer src="{{'js/slots_screen.js' | asset}}"></script>
<script defer src="{{'js/casino/slots_screen.js' | asset}}"></script>
{% endblock %}
{% block screen %}
<style nonce="{{g.nonce}}">
.slots_reels {
display: flex;
align-items: center;
justify-content: center;
}
<link rel="stylesheet" href="{{('css/casino/slots_screen.css') | asset}}">
.slots_reel {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
border: 2px solid black;
background-color: var(--gray);
border: 1px solid var(--black);
border-radius: 8px;
font-size: 64px;
}
.slots_reel:nth-child(2) {
margin: 0 1rem;
}
</style>
<div class="slots_reels">
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
<div class="slots_reels">
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
</div>
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
</div>
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
</div>
</div>
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
</div>
<div class="slots_reel">
<img src="/i/rDrama/coins.webp?v=3009" alt="coin">
</div>
</div>
{% endblock %}
{% block actions %}
<div class="btn-group" role="group">
<button
type="button"
id="casinoSlotsPull"
class="btn btn-primary"
style="width: 100%"
onclick="pullSlots()"
>
Pull
</button>
</div>
<div class="btn-group" role="group">
<button
type="button"
id="casinoSlotsPull"
class="btn btn-primary"
style="width: 100%"
onclick="pullSlots()"
>
Pull
</button>
</div>
{% endblock %}

View File

@ -17,7 +17,6 @@
data-avatar="{{v.profile_url}}"
data-hat="{{v.hat_active(v)[0]}}">
</div>
<script nonce="{{g.nonce}}">window.global = window</script>
{% if IS_LOCALHOST %}
<script defer src="https://rdrama.net/assets/js/chat_done.js"></script>
{% else %}

View File

@ -1,10 +1,7 @@
{%- import 'util/macros.html' as macros with context -%}
{% if not request.headers.get("xhr") %}
{% if comment_info %}
<script nonce="{{g.nonce}}">
if (location.hash != 'context')
location.hash = 'context'
</script>
<script defer src="{{'js/comment_info.js' | asset}}"></script>
{% endif %}
{% if v %}
@ -31,14 +28,12 @@
<div class="comment-body">
<div id="comment-{{c.id}}-only" class="{% if c.award_count('glowie', v) %}glow{% endif %} comment-{{c.id}}-only">
<div id="comment-{{c.id}}-only" class="{% if c.award_count('tilt', v) %}tilt{% endif %} {% if c.award_count('glowie', v) %}glow{% endif %} comment-{{c.id}}-only">
<div class="user-info">
<span class="comment-collapse-icon" onclick="collapse_comment('{{c.id}}', this.parentElement.parentElement.parentElement.parentElement)"></span>
{% if standalone and c.over_18 %}<span class="badge badge-danger">+18</span> {% endif %}
{% if c.is_banned %}removed by @{{c.ban_reason}} (Admin){% elif c.deleted_utc %}Deleted by author{% elif c.is_blocking %}You are blocking @{{c.author_name}}{% endif %}
</div>
</div>
{% if render_replies %}
@ -48,8 +43,8 @@
{{single_comment(reply, level=level+1)}}
{% endfor %}
{% elif replies %}
<button type="button" id="btn-{{c.id}}" class="d-mob-none btn btn-primary mt-3" onclick="morecomments('{{c.id}}')">More comments</button>
<a class="d-md-none py-3" href="{{c.morecomments}}">More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<button type="button" id="btn-{{c.id}}" class="d-mob-none btn btn-primary mt-3" onclick="more_comments('{{c.id}}', '{{sort}}')">More comments</button>
<a class="d-md-none py-3" href="{{c.more_comments}}">More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
{% endif %}
</div>
{% endif %}
@ -160,7 +155,7 @@
{% if c.is_blocked %}<i class="fas fa-user-minus text-danger" data-bs-toggle="tooltip" data-bs-placement="bottom" title="This user is blocking you."></i>{% endif %}
{% if c.ghost %}
<span {% if c.distinguish_level %}class="mod"{% endif %}>👻</span>
<span {% if c.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>👻</span>
{% else %}
{% if FEATURES['PATRON_ICONS'] and c.author.patron %}
<img loading="lazy" src="/i/{{SITE_NAME}}/badges/2{{c.author.patron}}.webp?v=1" height="20" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{c.author.patron_tooltip}}" alt="{{c.author.patron_tooltip}}">
@ -180,7 +175,7 @@
<img class="profile-pic-30-hat hat" loading="lazy" src="{{c.author.hat_active(v)[0]}}?h=7" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{c.author.hat_active(v)[1]}}">
{%- endif %}
</div>
<span {% if c.author.patron and not c.distinguish_level %}class="patron" style="background-color:#{{c.author.name_color}};"{% elif c.distinguish_level %}class="mod"{% endif %}>{{c.author_name}}</span>
<span {% if c.author.patron and not c.distinguish_level %}class="patron" style="background-color:#{{c.author.name_color}};"{% elif c.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>{{c.author_name}}</span>
</a>
{% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{c.author.titlecolor}};border-color:#{{c.author.titlecolor}}">{{c.author.pronouns}}</span>
@ -190,7 +185,12 @@
{% endif %}
{% endif %}
{% if c.parent_comment_id and not standalone and level != 1 %}<a href="#comment-{{c.parent_comment_id}}-only" class="text-muted ml-2"><i class="fas fa-reply fa-sm fa-fw fa-flip-horizontal mr-1"></i>{{c.parent_comment.author_name}}</a>{% endif %}
{% if c.parent_comment_id and not standalone and level != 1 %}
<a href="#comment-{{c.parent_comment_id}}-only" class="text-muted ml-2">
<i class="fas fa-reply fa-sm fa-fw fa-flip-horizontal mr-1"></i>
{{c.parent_comment.author_name}}
</a>
{% endif %}
{% if c.notif_utc %}
<span id="timestamp-{{c.id}}" onmouseover="timestamp('timestamp-{{c.id}}','{{c.notif_utc}}')" data-bs-toggle="tooltip" data-bs-placement="bottom" class="time-stamp">&nbsp;{{c.age_string}}</span>
@ -244,32 +244,6 @@
{% if c.is_banned and c.ban_reason %}
<div id="comment-banned-warning" class="comment-text text-removed mb-0">removed by @{{c.ban_reason}} (Admin)</div>
{% endif %}
{% if c.award_count("tilt", v) %}
<style nonce="{{g.nonce}}">
@keyframes c{{c.id}}-tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{c.award_count("tilt", v)}}deg);}
75% {transform: rotate(-{{c.award_count("tilt", v)}}deg);}
100% {transform: rotate(0deg);}
}
@media (max-width: 720px) {
@keyframes c{{c.id}}-tilt {
0% {transform: rotate(0deg);}
25% {transform: rotate({{c.award_count("tilt", v)/4}}deg);}
75% {transform: rotate(-{{c.award_count("tilt", v)/4}}deg);}
100% {transform: rotate(0deg);}
}
}
.comment-{{c.id}}-only {
animation-name: c{{c.id}}-tilt;
animation-duration: 30s !important;
animation-iteration-count: infinite !important;
animation-direction: alternate !important;
animation-timing-function: linear !important;
}
</style>
{% endif %}
<div id="comment-text-{{c.id}}" class="comment-text mb-0 {% if c.author.agendaposter and not (c.parent_submission and c.post.sub == 'chudrama') %}agendaposter{% endif %} {% if c.author.rainbow %}rainbow-text{% endif %}">
{{c.realbody(v) | safe}}
@ -528,8 +502,8 @@
{{single_comment(reply, level=level+1)}}
{% endfor %}
{% elif replies %}
<button type="button" id="btn-{{c.id}}" class="d-mob-none btn btn-primary mt-3" onclick="morecomments('{{c.id}}')">More comments</button>
<a class="d-md-none py-3" href="{{c.morecomments}}">More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
<button type="button" id="btn-{{c.id}}" class="d-mob-none btn btn-primary mt-3" onclick="more_comments('{{c.id}}', '{{sort}}')">More comments</button>
<a class="d-md-none py-3" href="{{c.more_comments}}">More comments <i class="fas fa-long-arrow-right ml-1"></i></a>
{% endif %}
</div>
@ -785,93 +759,25 @@
<script defer src="{{'js/comments+submission_listing.js' | asset}}"></script>
<script defer src="{{'js/comments.js' | asset}}"></script>
<script defer src="{{'js/more_comments.js' | asset}}"></script>
{% endif %}
<script nonce="{{g.nonce}}">
{% if p and (not v or v.highlightcomments) %}
comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
lastCount = comments['{{p.id}}']
if (lastCount)
{
{% for c in p.comments %}
{% if not (v and v.id==c.author_id) and not c.voted %}
if ({{c.created_utc*1000}} > lastCount.t)
try {document.getElementById("comment-{{c.id}}-only").classList.add('unread')}
catch(e) {}
{% endif %}
{% endfor %}
}
{% endif %}
function morecomments(cid) {
btn = document.getElementById(`btn-${cid}`);
btn.disabled = true;
btn.innerHTML = "Requesting...";
const form = new FormData();
form.append("formkey", formkey());
form.append("sort", "{{sort}}");
const xhr = new XMLHttpRequest();
xhr.open("get", `/morecomments/${cid}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
if (xhr.status==200) {
let e = document.getElementById(`replies-of-c_${cid}`)
e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
bs_trigger(e)
{% if p %}
comments = JSON.parse(localStorage.getItem("old-comment-counts")) || {}
lastCount = comments['{{p.id}}']
if (lastCount)
{
{% for c in p.comments %}
{% if not (v and v.id==c.author_id) and not c.voted %}
if ({{c.created_utc*1000}} > lastCount.t)
try {document.getElementById("comment-{{c.id}}-only").classList.add('unread')}
catch(e) {}
{% endif %}
{% endfor %}
}
{% endif %}
}
btn.disabled = false;
}
xhr.send(form)
}
</script>
{% if p %}
{% set pid = p.id %}
<div class="d-none">
{% set comms = [] %}
{% for c in p.comments %}
{% if not (v and v.id==c.author_id) and not c.voted %}
{{comms.append([c.id, c.created_utc])}}
{% endif %}
{% endfor %}
<input hidden id="comms" value="{{comms}}">
</div>
{% endif %}
{% if offset %}
{% if p %}
{% set pid = p.id %}
{% endif %}
<br>
<div id="viewmore-{{offset}}"><button type="button" id="viewbtn" class="btn btn-primary" onclick="viewmore({{pid}},'{{sort}}',{{offset}},{{ids}})">VIEW MORE COMMENTS</a></div>
{% endif %}
{# TODO: disabled pending fix #}
{% if false %}
<div id="detection" style="display:none;background-color:canvas;color-scheme:light"></div>
<script nonce="{{g.nonce}}">
const detectionDiv = document.querySelector('#detection');
const isAutoDark = getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';
if (!isAutoDark) {
const element = document.getElementsByClassName('comment-section')[0]
if (element) {
let color = getComputedStyle(element).getPropertyValue('background-color');
color = 'rgba' + color.slice(3,-1) + ', 0.1)'
const markTemplate = (name) => {
return `<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='50px' height='50px'><text transform='translate(10, 50) rotate(-45)' fill='${color}' font-size='20'>${name}</text></svg>`;
};
const base64Mark = btoa(markTemplate("{{v.id}}"));
const style = document.createElement('style');
style.innerHTML = `.actual-post:not(.deleted, .banned),.comment-section>.comment{background-image:url("data:image/svg+xml;base64,${base64Mark}")}`;
document.getElementsByTagName('head')[0].appendChild(style);
}
}
</script>
<div id="view_more-{{offset}}"><button type="button" id="viewbtn" class="btn btn-primary" onclick="view_more({{pid}},'{{sort}}',{{offset}},{{ids}})">VIEW MORE COMMENTS</a></div>
{% endif %}
</body>

View File

@ -79,27 +79,7 @@
<script defer src="{{'js/spider.js' | asset}}"></script>
{% endif %}
{% if g.browser == 'apple' %}
<script nonce="{{g.nonce}}">
document.addEventListener('load', function() {
const videos = document.querySelectorAll('video')
for (const video of videos) {
const link = video.src
const htmlString = `
<a rel="nofollow noopener" href="${link}" target="_blank">
<div class="d-flex justify-content-between align-items-center border rounded p-2 mb-3 download-video">
<span>${link}</span>
<i class="fas fa-external-link-alt text-small"></i>
</div>
</a>`
const div = document.createElement('div');
div.innerHTML = htmlString;
video.after(div)
}
});
</script>
{% endif %}
<input id="gbrowser">{{g.browser}}</input>
{% if HOLIDAY_EVENT %}
{% include "event/music.html" %}

View File

@ -74,7 +74,7 @@
</a>
</div>
<div class="flex-grow-1 d-fl d-mob-none pad">
<div class="flex-grow-1 d-fl d-mob-none py-2">
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" action="/search/posts/" method="get">
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
<span class="input-group-append">

View File

@ -74,7 +74,7 @@
</a>
</div>
<div class="flex-grow-1 d-fl d-mob-none pad">
<div class="flex-grow-1 d-fl d-mob-none py-2">
<form class="form-inline search flex-nowrap mx-0 mx-lg-auto" action="/search/posts/" method="get">
<input autocomplete="off" class="form-control w-100" type="search" placeholder="Search" name="q" value="">
<span class="input-group-append">

View File

@ -9,117 +9,30 @@
{# idk why snow isn't working vvvvvvvvvv #}
{% if p.award_count("snow", v) %}
<script defer src="{{'event/js/snow.js'|asset}}"></script>
<script nonce="{{g.nonce}}">
document.addEventListener("load", () => {
snow(80)
});
</script>
{% endif %}
{% if p.award_count("frostbite", v) %}
<div class="frost"></div>
<script nonce="{{g.nonce}}">
const root = document.querySelector(':root');
const count = 5;
const opacity = count * 0.1;
root.style.setProperty('--opacity-frost', opacity);
</script>
<style nonce="{{g.nonce}}">
:root {
--opacity-frost: 0.25;
}
.frost {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 200px 10px rgba(255, 255, 255, var(--opacity-frost)) inset;
pointer-events: none;
z-index: 1050;
}
</style>
<script defer src="{{'event/js/frostbite.js' | asset}}"></script>
<script defer src="{{'event/css/frostbite.css' | asset}}"></script>
{% endif %}
{% if p.award_count("snowed-in", v) %}
<canvas id="canvas-snowed-in-overlay"></canvas>
<canvas id="canvas-snowed-in-lines"></canvas>
<style nonce="{{g.nonce}}">
#canvas-snowed-in-overlay {
position: fixed;
top: 0;
left: 0;
z-index: 9998;
opacity: 1;
pointer-events: none;
}
#canvas-snowed-in-lines {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
opacity: 0.0;
pointer-events: none;
}
</style>
<link rel="stylesheet" href="{{'event/css/snowed-in.css' | asset}}">
<script defer src="{{'event/js/snowed-in.js'|asset}}"></script>
{% endif %}
</div>
{% if p.award_count("lights", v) %}
<style nonce="{{g.nonce}}">
#post-root::before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 57px;
width: 100%;
background: url('/assets/event/images/lights.webp?v=1');
animation: lights 1s infinite steps(2);
pointer-events: none;
z-index: 1;
}
</style>
<link rel="stylesheet" href="{{('event/css/lights.css') | asset}}">
{% endif %}
{% if p.award_count("candycane", v) %}
<style nonce="{{g.nonce}}">
#post-title, #post-content p {
--color2: #cc4145;
--color1: rgb(12, 128, 101);
font-family: "Open Sans", sans-serif;
background: repeating-linear-gradient(
45deg, var(--color2), var(--color2) 10px,
var(--color1) 11px, var(--color1) 30px
);
background-clip: text;
color: transparent;
-webkit-background-clip: text;
animation: 45s linear 0s infinite candycorn-move;
}
#post-title a {
color: transparent !important;
}
@keyframes candycorn-move {
from {background-position: 0px;}
to {background-position: 1000px;}
}
</style>
<link rel="stylesheet" href="{{('event/css/candycane.css') | asset}}">
{% endif %}
{% if p.award_count("fireplace", v) %}
<style nonce="{{g.nonce}}">
#banner-skybox {
fill: url(#skybox-gradient-night)
}
#banner-window-1, #banner-window-2 {
filter: drop-shadow(0 0 50px orange);
fill: palegoldenrod;
}
</style>
<link rel="stylesheet" href="{{('event/css/fireplace.css') | asset}}">
{% endif %}

View File

@ -1,11 +1,6 @@
{# <script defer src="{{'event/js/neko.js'|asset}}"></script> #}
{% if request.path == '/' %}
<script defer src="{{'event/js/snow.js'|asset}}"></script>
<script nonce="{{g.nonce}}">
document.addEventListener("load", () => {
snow(80)
});
</script>
{% endif %}
<a rel="nofollow noopener noreferrer" href="https://www.youtube.com/watch?v=BuKft9LpL_0" style="text-decoration: none !important">

View File

@ -199,11 +199,6 @@
<circle cx="169.44" cy="10.935"/>
</g>
<defs>
<style nonce="{{g.nonce}}">.star1 circle {r: 0.5;}
.star2 circle {r: 0.75;}
.star3 circle {r: 1.0;}
.star4 circle {r: 1.2;}
.star5 circle {r: 1.5;}</style>
</defs>
</g>
<defs>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -199,11 +199,6 @@
<circle cx="169.44" cy="10.935"/>
</g>
<defs>
<style nonce="{{g.nonce}}">.star1 circle {r: 0.5;}
.star2 circle {r: 0.75;}
.star3 circle {r: 1.0;}
.star4 circle {r: 1.2;}
.star5 circle {r: 1.5;}</style>
</defs>
</g>
<defs>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -3,16 +3,5 @@
{% set path = "assets/event/media/music" %}
{% set song = "/" ~ path ~ "/" ~ listdir('files/' ~ path)|random() ~ '?v=45' %}
{% endif %}
<script nonce="{{g.nonce}}">
window.addEventListener('load', function() {
const audio = new Audio("{{song}}");
audio.loop=true;
audio.play();
window.addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true});
prepare_to_pause(audio)
});
</script>
<script defer src="{{'event/js/music.js' | asset}}"></script>
{% endif %}

View File

@ -3,34 +3,6 @@
{% block pagetype %}message{% endblock %}
{% block banner %}
<style nonce="{{g.nonce}}">
.shop-tabs {
padding-top: 50px;
}
@media (max-width: 768px) {
#hats-banner {
width: 80%;
}
.shop-tabs {
padding-top: 30px;
}
}
.shop-tab {
display: inline-flex;
max-width: 46.6%;
letter-spacing: 3px;
border-radius: 0;
}
.shop-tab.active {
background-color: var(--primary) !important;
pointer-events: none !important;
cursor: default !important;
}
</style>
<div class="container-fluid bg-white sticky shop-tabs" style="padding-bottom: 0 !important;">
<div class="row box-shadow-bottom">
<div class="col p-0">
@ -59,19 +31,7 @@
{% endblock %}
{% block content %}
<script nonce="{{g.nonce}}">
function equip_hat(t, hat_id, hat_name) {
const profile_pic_hat = document.getElementById("profile-pic-35-hat");
function extra_actions(xhr) {
if(xhr.status == 200) {
profile_pic_hat.src = `/i/hats/${hat_name}.webp?h=7`
profile_pic_hat.classList.remove('d-none')
}
}
postToastSwitch(t, `/equip_hat/${hat_id}`, `equip-${hat_id}`, `unequip-${hat_id}`, `d-none`, extra_actions)
}
</script>
<script defer src="{{'js/hats.js' | asset}}"></script>
<div class="overflow-x-auto mt-1 mb-5">
<table class="table table-striped shop">

View File

@ -4,61 +4,45 @@
{%- endif -%}
<nav class="shadow-md fixed-top">
<style nonce="{{g.nonce}}">
body {padding-top: 83px !important}
@media (max-width: 767.98px) {
body {
padding-top: 63px !important
}
}
</style>
{% if not err %}
<div class="srd">
{% if SITE_NAME == 'rDrama' %}
{% if range(1,5) | random == 1 %}
{% include "journoid_banner.html" %}
{% else %}
{% if EVENT_VISITORS_HERE_FLAVOR %}
{%- set VISITORS_HERE_FLAVOR = EVENT_VISITORS_HERE_FLAVOR -%}
{% if not err %}
<div class="srd">
{% if SITE_NAME == 'rDrama' %}
{% if range(1,5) | random == 1 %}
{% include "journoid_banner.html" %}
{% else %}
{%- set VISITORS_HERE_FLAVOR = [
' incels currently stalking roasties',
' gooners currently edging to <img src="/e/marseycumjar3.webp" style="height: 1.5em;">',
' fanboys currently obsessing over Carp',
' NEETs currently LDARmaxxing',
' valid women currently dilating',
' negholes currently being pozzed',
' bussies currently on standby',
' gamers currently harassing women',
' dramanauts hurtling through Safe Space™',
' Soros shills currently plotting mayocide',
' furries currently yiffing',
' incels currently harassing women',
' chuds currently agendaposting',
' coomers currently gooning',
' bacons currently narwhaling',
' well-behaved rule-following goodthinkers',
' throwing shade right now',
]
-%}}
{% if EVENT_VISITORS_HERE_FLAVOR %}
{%- set VISITORS_HERE_FLAVOR = EVENT_VISITORS_HERE_FLAVOR -%}
{% else %}
{%- set VISITORS_HERE_FLAVOR = [
' incels currently stalking roasties',
' gooners currently edging to <img src="/e/marseycumjar3.webp" style="height: 1.5em;">',
' fanboys currently obsessing over Carp',
' NEETs currently LDARmaxxing',
' valid women currently dilating',
' negholes currently being pozzed',
' bussies currently on standby',
' gamers currently harassing women',
' dramanauts hurtling through Safe Space™',
' Soros shills currently plotting mayocide',
' furries currently yiffing',
' incels currently harassing women',
' chuds currently agendaposting',
' coomers currently gooning',
' bacons currently narwhaling',
' well-behaved rule-following goodthinkers',
' throwing shade right now',
]
-%}}
{% endif %}
{{loggedin_counter+loggedout_counter}} {{VISITORS_HERE_FLAVOR|random|safe}} ({{loggedin_counter}} logged in)
{% endif %}
{{loggedin_counter+loggedout_counter}} {{VISITORS_HERE_FLAVOR|random|safe}} ({{loggedin_counter}} logged in)
{% else %}
{{loggedin_counter+loggedout_counter}} people here now ({{loggedin_counter}} logged in)
{% endif %}
{% else %}
{{loggedin_counter+loggedout_counter}} people here now ({{loggedin_counter}} logged in)
{% endif %}
</div>
{% else %}
<style nonce="{{g.nonce}}">
body {padding-top: 54px !important}
@media (max-width: 767.98px) {
body {
padding-top: 44px !important
}
}
</style>
{% endif %}
</div>
{% else %}
<link rel="stylesheet" href="{{'css/err.css' | asset}}">
{% endif %}
<div class="navbar navbar-expand-md navbar-light" id="navbar">
<div class="container-fluid" style="padding:0;">
<a href="/" class="navbar-brand mr-auto {% if not has_logo and not sub %}flex-grow-1{% endif %}">
@ -75,24 +59,12 @@
{% if sub %}
<a id="sub-name" href="/h/{{sub}}" class="font-weight-bold ml-2 flex-grow-1 mt-1" {% if sub.name|length >= 17 %}style="font-size:max(10px,1.2vw)"{% else %}style="font-size:max(14px,1.2vw)"{% endif %}>{% if not HOLE_STYLE_FLAIR %}/h/{% endif %}{{sub}}</a>
{% elif has_logo %}
<style nonce="{{g.nonce}}">
{% if SITE_NAME == 'WPD' %}
@media (min-width: 1000px) {
{% else %}
@media (min-width: 380px) {
{% endif %}
#logo {
width: 100px;
margin-left: 0.5rem !important;
}
}
</style>
<div id="logo-container" class="flex-grow-1 logo-container">
<a href="/">
{% if SITE_NAME == 'WPD' %}{# Temporary event code, 2022-12-11 #}
<img class="ml-1" id="logo" alt="logo" src="{{'icons-event/2022-christmas-logo.webp' | asset_siteimg}}" width="70">
{% if SITE_NAME == 'WPD' and HOLIDAY_EVENT %}
<img class="ml-1" id="logo" alt="logo" src="{{'icons-event/2022-christmas-logo.webp' | asset_siteimg}}" width="70">
{% else %}
<img class="ml-1" id="logo" alt="logo" src="{{'logo.webp' | asset_siteimg}}" width="70">
<img class="ml-1" id="logo" alt="logo" src="{{'logo.webp' | asset_siteimg}}" width="70">
{% endif %}
</a>
</div>
@ -358,25 +330,8 @@
<div id="formkey" class="d-none">{{v|formkey}}</div>
{% endif %}
<script nonce="{{g.nonce}}">
IMAGE_FORMATS = {{IMAGE_FORMATS|safe}};
</script>
{% if not v %}
<style nonce="{{g.nonce}}">
.pad {
padding-bottom: 7.4px;
padding-top: 7.4px;
}
</style>
{% endif %}
{% if v and v.poor -%}
<style nonce="{{g.nonce}}">
* :not(img[src="/i/hand.webp"] + img, img.golden, img[g], img[glow], .live-circle) {
animation: unset !important;
}
</style>
<link rel="stylesheet" href="{{('css/poor.css') | asset}}">
{%- endif %}
<link rel="preload" as="image" href="/i/l.webp">

View File

@ -62,16 +62,8 @@
{% block navbar %}
<div class="d-flex align-items-center">
{% if SITE_NAME != 'WPD' and not sub %}
<style nonce="{{g.nonce}}">
@media (max-width: 427px) {
.smol-fp {
font-size: 2.7vw;
padding-left: 2.5vw;
padding-right: 2.1vw;
}
}
</style>
{% set hcolor = "primary" if holes else "secondary" %}
<link rel="stylesheet" href="{{('css/smolfp.css') | asset}}">
{% set hcolor = "primary" if holes else "secondary" %}
<a class="btn btn-{{hcolor}} text-{{hcolor}} mx-2 smol-fp" href="/toggle_holes"><i class="fas fas fa-manhole mr-2 "></i>Holes</a>
{% endif %}
@ -168,87 +160,21 @@
{% endif %}
{% if request.path == '/' and v %}
<script defer src="/assets/js/register_service_worker.js"></script>
<script nonce="{{g.nonce}}">
document.addEventListener('load', function () {
registerServiceWorker(
"/assets/js/service_worker.js",
"{{VAPID_PUBLIC_KEY}}",
"/push_subscribe")
});
</script>
<script defer src="{{'js/register_service_worker.js' | asset}}"></script>
<input hidden id="VAPID_PUBLIC_KEY" value="{{VAPID_PUBLIC_KEY}}">
{% endif %}
{% if request.path == '/' and g.browser != 'webview' and time.time() > session.get('tooltip_last_dismissed',0)+86400*30 %}
<style nonce="{{g.nonce}}">
.dismiss-beg {
color: #919191;
float: left;
font-size: 14px;
padding: 0.25rem 0.7rem 2rem 0.7rem;
}
</style>
<div id="mobile-prompt-container" class="fixed-top">
<div id="mobile-prompt" data-bs-toggle="tooltip" data-bs-container="#mobile-prompt-container" data-bs-placement="top" data-bs-trigger="click" data-bs-html="true" title="<i class='dismiss-beg fas fa-x'></i>Click me to install the {{SITE_NAME}} mobile app!"></div>
</div>
<script nonce="{{g.nonce}}">
if (!window.matchMedia('(display-mode: minimal-ui)')['matches']) {
if (window.innerWidth <= 737) {
document.addEventListener('load', function() {
const tt = bootstrap.Tooltip.getOrCreateInstance(document.getElementById('mobile-prompt'))
tt.show()
document.getElementsByClassName('tooltip')[0].onclick = function(e) {
tt.hide()
const xhr = new XMLHttpRequest();
xhr.withCredentials=true;
xhr.open("POST", '/dismiss_mobile_tip', true);
xhr.setRequestHeader('xhr', 'xhr');
xhr.send();
if (!e.target.classList.contains('dismiss-beg'))
location.href = "/app"
}
})
}
}
</script>
<style nonce="{{g.nonce}}">
#mobile-prompt + .bs-tooltip-bottom {
transform: None !important;
inset: 0px 0px auto auto !important;
}
</style>
<script defer src="{{'js/mobile_prompt.js' | asset}}"></script>
{% endif %}
{% if request.path == '/' and v and FP %}
{% if not v.fp %}
<script nonce="{{g.nonce}}">
function fp(fp) {
const xhr = new XMLHttpRequest();
xhr.open("POST", '/fp/'+fp);
xhr.setRequestHeader('xhr', 'xhr');
const form = new FormData()
form.append("formkey", formkey());
xhr.send(form);
};
const fpPromise = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.onload = resolve;
script.onerror = reject;
script.async = true;
script.src = "{{'js/vendor/fp.js' | asset}}";
document.head.appendChild(script);
})
.then(() => FingerprintJS.load({token: '{{FP}}'}));
fpPromise
.then(fp => fp.get())
.then(result => {if (result.visitorId != '{{v.fp}}') fp(result.visitorId);})
</script>
{% endif %}
{% if FP and request.path == '/' and v and not v.fp %}
<input hidden id="fp_token" value="{{FP}}">
<script defer src="{{'js/fp.js' | asset}}"></script>
{% endif %}
{% endblock %}

View File

@ -2,25 +2,17 @@
{% block pagetitle %}Moderation Log{% endblock %}
{% block content %}
{% if v %}
<style nonce="{{g.nonce}}">:root{--primary:#{{v.themecolor}}}</style>
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
{% if v.theme == 'classic_dark' %}
<link rel="stylesheet" href="{{('css/classic.css') | asset}}">
{% endif %}
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
{% if v.agendaposter %}
<style nonce="{{g.nonce}}">
html {
cursor:url('/i/dildo.webp?v=2000'), auto;
}
</style>
{% elif v.css %}
<style nonce="{{g.nonce}}">
{{v.css | safe}}
</style>
<link rel="stylesheet" href="{{('css/agendaposter.css') | asset}}">
{% elif v.css or v.background %}
<link rel="stylesheet" href="/{{v.id}}/css">
{% endif %}
{% else %}
<style nonce="{{g.nonce}}">:root{--primary:#{{DEFAULT_COLOR}}</style>
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
{% endif %}

View File

@ -23,7 +23,5 @@
<small><a href="/lost_2fa">Lost your 2FA device?</a></small>
<button type="submit" class="btn btn-primary login w-100 mt-3" id="login_button">Sign in</button>
</form>
<script nonce="{{g.nonce}}">
document.getElementById('2fa_token').focus()
</script>
<script defer src="{{'js/login_2fa.js' | asset}}"></script>
{% endblock %}

View File

@ -1,25 +1,5 @@
<div id="form" class="d-none"></div>
<div class="modal fade" id="emojiModal" tabindex="-1" role="dialog">
<style nonce="{{g.nonce}}">
#emojiTabs {height: 80%;}
@media (max-width: 650px) {
#emojiTabs {height: 100%;}
#emojiModalInternalDivIDK {margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 3rem !important; padding-bottom: 0 !important;}
#emoji-modal-tabs-container {
overflow-x: auto;
}
#emoji-modal-tabs {
white-space: nowrap;
flex-wrap: nowrap;
}
#emoji-modal-tabs li {
display: inline-block;
}
}
</style>
<div id="emojiModalInternalDivIDK" class="modal-dialog modal-dialog-scrollable modal-dialog-centered emoji-modal" role="document">
<div class="modal-content" id="emojiTabs">
<div class="modal-header">
@ -70,20 +50,6 @@
I've took the liberty to populate this tab with a selection of Anton's emojis 😽. Next time you'll find the ones you used the most in there 📚
</div>
<div id="tab-content" class="tab-content d-flex flex-wrap py-3 pl-2" hidden style="text-align:center;">
<style nonce="{{g.nonce}}">
.emoji2 {
/*background: None!important;*/
width:60px;
height: 85px;
overflow: hidden;
border: none
}
.emoji2 > img {
-o-object-fit: contain;
object-fit: contain;
}
</style>
<template id="emoji-button-template">
<button type="button" class="btn m-1 px-0 emoji2" data-bs-toggle="tooltip" delay:="0">
<img loading="lazy" width=60 height=85>

View File

@ -151,11 +151,6 @@
</ul>
</nav>
{% endif %}
<style nonce="{{g.nonce}}">
.comment {
margin-top: 0.3rem;
}
</style>
{% endblock %}
{% block GIFpicker %}{% endblock %}

View File

@ -38,7 +38,7 @@
<strong class="pop-coins text-black"></strong>
<span class="text-black">coins</span>
</span>
<a href="/" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} class="pop-viewmore ml-auto text-decoration-none">
<a href="/" {% if v and v.newtab %}data-target="t" target="_blank"{% endif %} class="pop-view_more ml-auto text-decoration-none">
<span class="ml-3">View</span>
<i class="fas fa-arrow-right fa-sm px-1"></i>
</a>

View File

@ -8,7 +8,7 @@
{%- import 'util/macros.html' as macros with context -%}
{%- import 'util/html_head.html' as html_head with context -%}
<!DOCTYPE html>
<html lang="en">
<html lang="en" style="--primary:#{{v.themecolor if v else DEFAULT_COLOR}}">
<head>
{% block head %}
<meta charset="utf-8">

View File

@ -42,13 +42,6 @@
</div>
</div>
<script nonce="{{g.nonce}}">
document.addEventListener('load', function() {
for (const x of ['css','profilecss']) {
const ta = document.getElementById(`${x}-textarea`);
autoExpand(ta);
}
})
</script>
<script defer src="{{'js/css.js' | asset}}"></script>
{% endblock %}

View File

@ -1,18 +1,6 @@
{% extends "settings.html" %}
{% block pagetitle %}Personal Settings{% endblock %}
{% block content %}
<style nonce="{{g.nonce}}">
.bg-image {
padding: 0.25rem;
width: 15rem;
height: 10rem;
object-fit: cover;
}
.bg-button {
margin: 0.25rem;
padding: 0;
}
</style>
<div class="row settings-page" id="settings-page-personal">
<div class="col col-lg-10">
<div class="settings">
@ -279,13 +267,7 @@
{% include "modals/gif.html" %}
{% if v.flairchanged %}
<script nonce="{{g.nonce}}">
document.addEventListener('load', function() {
const date = formatDate(new Date({{v.flairchanged}}*1000));
const text = ` - Your flair has been locked until ${date}`;
document.getElementById('flair-body').value += text;
});
</script>
<input hidden id="flairchanged" value="{{v.flairchanged}}">
{% endif %}
<script defer src="{{'js/settings_profile.js' | asset}}"></script>
@ -325,20 +307,4 @@
{% if v.profanityreplacer == 1 -%}
{{permanent_filter_modal('profanityreplacer', '/settings/personal', 'profanityreplacer', 'Profanity Replacer', 'Soapy-Mouthed Angel')}}
{%- endif %}
{% if FEATURES['USERS_PERMANENT_WORD_FILTERS'] -%}
<script nonce="{{g.nonce}}">
document.addEventListener("load", function (event) {
const sr_toggle = document.getElementById("slurreplacer");
const sr_link = document.getElementById('slurreplacer-perma-link');
const pr_toggle = document.getElementById("profanityreplacer");
const pr_link = document.getElementById('profanityreplacer-perma-link');
sr_toggle.addEventListener('change', function (event) {
sr_link.hidden = !sr_toggle.checked;
});
pr_toggle.addEventListener('change', function (event) {
pr_link.hidden = !pr_toggle.checked;
});
});
</script>
{%- endif %}
{% endblock %}

View File

@ -7,34 +7,6 @@
{% block pagetitle %}Shop{% endblock %}
{% block pagetype %}message{% endblock %}
{% block banner %}
<style nonce="{{g.nonce}}">
.shop-tabs {
padding-top: 50px;
}
@media (max-width: 768px) {
#shop-banner {
width: 80%;
}
.shop-tabs {
padding-top: 30px;
}
}
.shop-tab {
display: inline-flex;
max-width: 46.6%;
letter-spacing: 3px;
border-radius: 0;
}
.shop-tab.active {
background-color: var(--primary) !important;
pointer-events: none !important;
cursor: default !important;
}
</style>
<div class="container-fluid bg-white sticky shop-tabs" style="padding-bottom: 0 !important;">
<div class="row box-shadow-bottom">
<div class="col p-0">

View File

@ -2,15 +2,7 @@
{% block pagetitle %}/h/{{sub}} Mods{% endblock %}
{% block content %}
<script nonce="{{g.nonce}}">
function removeMod(e) {
sendFormXHR(e,
() => {
e.target.parentElement.parentElement.remove();
}
)
}
</script>
<script defer src="{{'js/remove_mod.js' | asset}}"></script>
<h5 class="mt-2">/h/{{sub}} Mods</h5>
<div class="overflow-x-auto mt-1"><table class="table table-striped mb-5">

View File

@ -8,12 +8,6 @@
{% endblock %}
{% block pagetype %}thread{% endblock %}
{% block head_final %}
<style nonce="{{g.nonce}}">
body > .container {
padding-left: 20px !important;
padding-right: 20px !important;
}
</style>
{% include "awards.html" %}
@ -73,7 +67,7 @@
<div class="row mb-3">
<div id="post-root" class="col-12">
<div id="post-root" class="col-12 {% if p.award_count('tilt', v) %}tilt{% endif %}">
<div class="card border-0 mt-3 {% if p.stickied %}stickied{% endif %} {% if voted==1 %}upvoted{% elif voted==-1 %} downvoted{% endif %}">
<div id="post-{{p.id}}" class="actual-post {% if p.ghost %}ghost-post{% endif %} {% if p.is_banned %}banned{% endif %} {% if p.deleted_utc %}deleted {% endif %} {% if p.award_count('tilt', v) %}p-3{% endif %} {% if p.award_count('glowie', v) %}glow{% endif %} d-flex flex-row-reverse flex-nowrap justify-content-end">
@ -350,39 +344,7 @@
</div>
{% if offset %}
<script nonce="{{g.nonce}}">
function viewmore(pid,sort,offset,ids) {
btn = document.getElementById("viewbtn");
btn.disabled = true;
btn.innerHTML = "Requesting...";
const form = new FormData();
const xhr = new XMLHttpRequest();
xhr.open("get", `/viewmore/${pid}/${sort}/${offset}?ids=${ids}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
if (xhr.status==200) {
let e = document.getElementById(`viewmore-${offset}`);
e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
bs_trigger(e)
comments = JSON.parse(localStorage.getItem("old-comment-counts")) || {}
lastCount = comments['{{p.id}}']
if (lastCount)
{
{% for c in p.comments %}
{% if not (v and v.id==c.author_id) and not c.voted %}
if ({{c.created_utc*1000}} > lastCount.t)
try {document.getElementById("comment-{{c.id}}-only").classList.add('unread')}
catch(e) {}
{% endif %}
{% endfor %}
}
}
btn.disabled = false;
}
xhr.send(form)
}
</script>
<script defer src="{{'js/view_more.js' | asset}}"></script>
{% endif %}
{% elif not p.replies and p.deleted_utc == 0 %}
<div class="comment-section no-replies" id="replies-of-{{p.fullname}}">
@ -408,58 +370,20 @@
{% endif %}
{% endif %}
{% if not v or v.highlightcomments %}
<script defer src="{{'js/highlightcomments.js' | asset}}"></script>
{% endif %}
<script defer src="{{'js/vendor/clipboard.js' | asset}}"></script>
{% if not p.replies %}{% include "comments.html" %}{% endif %}
{% if not v or v.highlightcomments %}
<script nonce="{{g.nonce}}">
document.addEventListener('load', function() {
showNewCommentCounts('{{p.id}}', {{p.comment_count}})
{% if "?context" not in request.full_path %}
localStorage.setItem("old-comment-counts", localStorage.getItem("comment-counts"))
const comments = JSON.parse(localStorage.getItem("comment-counts")) || {}
const newTotal = {{p.comment_count}} || ((comments['{{p.id}}'] || {c: 0}).c + 1)
comments['{{p.id}}'] = {c: newTotal, t: Date.now()}
localStorage.setItem("comment-counts", JSON.stringify(comments))
{% endif %}
})
</script>
{% endif %}
<input hidden class="twoattrs" value="{{p.id}},{{p.comment_count}}">
<script defer src="{{'js/new_comments.js' | asset}}"></script>
<script defer src="{{'js/submission.js' | asset}}"></script>
{% if success %}
<script nonce="{{g.nonce}}">
history.pushState(null, null, '{{p.permalink}}');
localStorage.setItem("post-title", "")
localStorage.setItem("post-text", "")
localStorage.setItem("post-url", "")
localStorage.setItem("sub", "")
localStorage.setItem("post-notify", true)
localStorage.setItem("post-new", false)
localStorage.setItem("post-nsfw", false)
localStorage.setItem("post-private", false)
localStorage.setItem("post-ghost", false)
</script>
<script defer src="{{'js/submission_success.js' | asset}}"></script>
{% endif %}
{% if fart and not (v and v.has_badge(128)) %}
<script nonce="{{g.nonce}}">
fart = Math.floor(Math.random() * 5) + 1
let audio = new Audio(`/assets/images/${fart}.webp`);
audio.play();
if (audio.paused) {
document.addEventListener('click', () => {
if (audio.paused) audio.play();
}, {once : true})
}
</script>
<script defer src="{{'js/fart.js' | asset}}"></script>
{% endif %}
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}

View File

@ -58,7 +58,7 @@
<div class="post-actions d-mob-none">
<ul class="list-inline text-left mb-2">
<li class="list-inline-item"><a href="{{p.permalink}}"><i
class="fas fa-comment-dots mr-2"></i>{{p.comment_count}} Comment{{'s' if p.comment_count != 1 else ''}}</a>
class="fas fa-comment-dots mr-2"></i><span class="comm-count">{{p.comment_count}}</span> Comment{{'s' if p.comment_count != 1 else ''}}</a>
</li>
</ul>
@ -75,39 +75,7 @@
</div>
{% if offset %}
<script nonce="{{g.nonce}}">
function viewmore(pid,sort,offset,ids) {
btn = document.getElementById("viewbtn");
btn.disabled = true;
btn.innerHTML = "Requesting...";
const form = new FormData();
const xhr = new XMLHttpRequest();
xhr.open("get", `/viewmore/${pid}/${sort}/${offset}?ids=${ids}`);
xhr.setRequestHeader('xhr', 'xhr');
xhr.onload=function(){
if (xhr.status==200) {
let e = document.getElementById(`viewmore-${offset}`);
e.innerHTML = xhr.response.replace(/data-src/g, 'src').replace(/data-cfsrc/g, 'src').replace(/style="display:none;visibility:hidden;"/g, '');
bs_trigger(e)
comments = JSON.parse(localStorage.getItem("old-comment-counts")) || {}
lastCount = comments['{{p.id}}']
if (lastCount)
{
{% for c in p.comments %}
{% if not (v and v.id==c.author_id) and not c.voted %}
if ({{c.created_utc*1000}} > lastCount.t)
try {document.getElementById("comment-{{c.id}}-only").classList.add('unread')}
catch(e) {}
{% endif %}
{% endfor %}
}
}
btn.disabled = false;
}
xhr.send(form)
}
</script>
<script defer src="{{'js/view_more.js' | asset}}"></script>
{% endif %}
{% endblock %}

View File

@ -4,10 +4,6 @@
{% include "modals/award.html" %}
{% endif %}
{% if not v or v.highlightcomments %}
<script defer src="{{'js/highlightcomments.js' | asset}}"></script>
{% endif %}
{% if v and v.admin_level > 1 %}
<script defer src="{{'js/pinpost.js' | asset}}"></script>
{% endif %}
@ -16,6 +12,8 @@
{% for p in listing if user_can_see(v, p) %}
<input hidden class="twoattrs" value="{{p.id}},{{p.comment_count}}">
{% set ups=p.upvotes %}
{% set downs=p.downvotes %}
{% set score=ups-downs %}
@ -214,15 +212,6 @@
</div>
{% endif %}
<script nonce="{{g.nonce}}">
{% if not v or v.highlightcomments %}
document.addEventListener('load', function() {
showNewCommentCounts({{p.id}}, {{p.comment_count}})
})
{% endif %}
</script>
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
{% include "post_admin_actions_mobile.html" %}
{% endif %}
@ -313,3 +302,5 @@
{% if v and v.admin_level >= PERMS['POST_COMMENT_MODERATION'] %}
<script defer src="{{'js/submission_admin.js' | asset}}"></script>
{% endif %}
<script defer src="{{'js/new_comments.js' | asset}}"></script>

View File

@ -104,14 +104,9 @@
</form>
</div>
{% endblock %}
{% if request.path == '/submit' %}
<script nonce="{{g.nonce}}">
let sub = document.getElementById('sub')
if (sub) sub.value = localStorage.getItem("sub")
</script>
{% endif %}
<script defer src="{{'js/vendor/marked.js' | asset}}"></script>
<script defer src="{{'js/markdown.js' | asset}}"></script>
<input hidden id="IMAGE_FORMATS" value="{{IMAGE_FORMATS}}">
<script defer src="{{'js/submit.js' | asset}}"></script>
{% include "modals/emoji.html" %}
{% include "modals/gif.html" %}

View File

@ -47,69 +47,9 @@
</div>
</div>
<script nonce="{{g.nonce}}">
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
<input hidden id="IMAGE_FORMATS" value="{{IMAGE_FORMATS}}">
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-hat').disabled = false;
}
})
function approve_hat(t, name) {
postToast(t, `/admin/approve/hat/${name}`,
{
"description": document.getElementById(`${name}-description`).value,
"name": document.getElementById(`${name}-name`).value,
"price": document.getElementById(`${name}-price`).value,
},
() => {
document.getElementById(`${name}-hat`).remove()
}
);
}
function remove_hat(t, name) {
postToast(t, `/remove/hat/${name}`,
{
},
() => {
document.getElementById(`${name}-hat`).remove()
}
);
}
</script>
<script defer src="{{'js/submit_hats.js' | asset}}"></script>
<h2 class="mt-5 mx-4">Pending Carp Approval</h2>
<div class="row mt-5 mx-4">

View File

@ -2,11 +2,6 @@
{% block pagetitle %}Submit Marseys{% endblock %}
{% block pagetype %}message{% endblock %}
{% block content %}
<style nonce="{{g.nonce}}">
input:not(.btn) {
text-transform: lowercase;
}
</style>
{% if error %}{{macros.alert(error, true)}}{% endif %}
{% if msg %}{{macros.alert(msg, false)}}{% endif %}
<div class="mx-4">
@ -47,68 +42,9 @@
</div>
</div>
<script nonce="{{g.nonce}}">
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
<input hidden id="IMAGE_FORMATS" value="{{IMAGE_FORMATS}}">
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-marsey').disabled = false;
}
})
function approve_marsey(t, name) {
postToast(t, `/admin/approve/marsey/${name}`,
{
"tags": document.getElementById(`${name}-tags`).value,
"name": document.getElementById(`${name}-name`).value,
},
() => {
document.getElementById(`${name}-marsey`).remove()
}
);
}
function remove_marsey(t, name) {
postToast(t, `/remove/marsey/${name}`,
{
},
() => {
document.getElementById(`${name}-marsey`).remove()
}
);
}
</script>
<script defer src="{{'js/submit_marseys.js' | asset}}"></script>
<h2 class="mt-5 mx-4">Pending Carp Approval</h2>
<div class="row mt-5 mx-4">

View File

@ -40,45 +40,8 @@
</div>
</div>
</div>
<input hidden id="IMAGE_FORMATS" value="{{IMAGE_FORMATS}}">
<script nonce="{{g.nonce}}">
document.onpaste = function(event) {
files = structuredClone(event.clipboardData.files);
filename = files[0]
if (filename)
{
filename = filename.name.toLowerCase()
f=document.getElementById('file-upload');
f.files = files;
document.getElementById('filename-show').textContent = filename;
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
}
}
}
document.getElementById('file-upload').addEventListener('change', function(){
f=document.getElementById('file-upload');
document.getElementById('filename-show').textContent = document.getElementById('file-upload').files[0].name.substr(0, 20);
filename = f.files[0].name.toLowerCase()
if (IMAGE_FORMATS.some(s => filename.endsWith(s)))
{
const fileReader = new FileReader();
fileReader.readAsDataURL(f.files[0]);
fileReader.addEventListener("load", function () {
document.getElementById('image-preview').setAttribute('src', this.result);
document.getElementById('image-preview').classList.remove('d-none');
});
document.getElementById('submit-asset').disabled = false;
}
})
</script>
<script defer src="{{'js/admin/update_assets.js' | asset}}"></script>
{% endblock %}

View File

@ -7,13 +7,8 @@
{% if not HOLIDAY_EVENT %}
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
{% endif %}
<style nonce="{{g.nonce}}">
body {
background-image: url('{{u.profile_background}}') !important;
}
</style>
{% endif %}
{% if u and u.profilecss and not request.values.get('nocss') %}
{% if u and (u.profilecss or u.profile_background) and not request.values.get('nocss') %}
<link rel="stylesheet" href="/{{u.id}}/profilecss">
{% endif %}
{% endblock %}

View File

@ -9,15 +9,6 @@
{% macro javascript() %}
<script defer src="{{'js/vendor/bootstrap.js' | asset}}"></script>
<script defer src="{{'js/core.js' | asset}}"></script>
<script nonce="{{g.nonce}}">
if (window.matchMedia('(display-mode: minimal-ui)')['matches']) {
const links = document.querySelectorAll('a[data-target="t"]');
for (const link of links) {
link.removeAttribute("target");
}
}
</script>
{% endmacro %}
{% macro page_meta(title=none) %}
@ -106,36 +97,25 @@
<link rel="stylesheet" href="{{'css/main.css' | asset}}">
<link id="favicon" rel="icon" type="image/webp" href="/icon.webp?v=1">
{% if v %}
<style nonce="{{g.nonce}}">:root{--primary:#{{v.themecolor}}}</style>
{% if v.agendaposter %}
<style nonce="{{g.nonce}}">
html {
cursor:url('/i/dildo.webp?v=2000'), auto;
}
</style>
<link rel="stylesheet" href="{{('css/agendaposter.css') | asset}}">
{% endif %}
{% if include_user_css and not EVENT_STYLES %}
{% if v.theme == 'classic_dark' %}
<link rel="stylesheet" href="{{('css/classic.css') | asset}}">
{% endif %}
<link rel="stylesheet" href="{{('css/'~v.theme~'.css') | asset}}">
{% if v.css and not request.path.startswith('/settings') %}
<style nonce="{{g.nonce}}">
{{v.css | safe}}
</style>
{% if (v.css or v.background) and not request.path.startswith('/settings') %}
<link rel="stylesheet" href="/{{v.id}}/css">
{% endif %}
{% if v.themecolor == '30409f' %}
<style nonce="{{g.nonce}}">
p a {
color: #2a96f3;
}
</style>
<link rel="stylesheet" href="{{('css/30409f.css') | asset}}">
{% endif %}
{% else %}
{{default_theme()}}
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
{% endif %}
{% else %}
{{default_theme()}}
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
{% endif %}
<link rel="stylesheet" href="{{'css/awards.css' | asset}}">
@ -144,17 +124,6 @@
<link rel="stylesheet" href="/h/{{sub}}/css" type="text/css">
{% endif %}
{% if SITE_NAME == 'rDrama' %}
<style nonce="{{g.nonce}}">
.mod:before {
content: '(((';
}
.mod:after {
content: ')))';
}
</style>
{% endif %}
{% if EVENT_STYLES %}
{% set EVENT_STYLES = 'event/css/'+EVENT_STYLES %}
<link rel="stylesheet" href="{{EVENT_STYLES | asset}}">
@ -188,24 +157,10 @@
{% if not HOLIDAY_EVENT %}
<link rel="stylesheet" href="{{('css/transparent.css') | asset}}">
{% endif %}
<style nonce="{{g.nonce}}">
body {
background:url("{{background}}") center center fixed;
background-color: rgb(var(--background));
{% if 'anime/' not in background and not background.startswith('/images/') -%}
background-size: cover;
{%- endif %}
}
</style>
{% endif %}
{% endif %}
{% endmacro %}
{% macro default_theme() %}
<style nonce="{{g.nonce}}">:root{--primary:#{{DEFAULT_COLOR}}}</style>
<link rel="stylesheet" href="{{('css/'~DEFAULT_THEME~'.css') | asset}}">
{% endmacro %}
{% macro seo() %}
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-touch-fullscreen" content="yes">

View File

@ -72,7 +72,7 @@
{% if p.active_flags(v) %}<button type="button" class="btn btn-primary" style="padding:1px 5px; font-size:10px" onclick="document.getElementById('flaggers-{{p.id}}').classList.toggle('d-none')">{{p.active_flags(v)}} Report{{plural(p.active_flags(v))}}</button>{% endif %}
{% if p.ghost %}
<span {% if p.distinguish_level %}class="mod"{% endif %}>👻</span>
<span {% if p.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>👻</span>
{% else %}
{% if FEATURES['PATRON_ICONS'] and p.author.patron %}
<img loading="lazy" src="/i/{{SITE_NAME}}/badges/2{{p.author.patron}}.webp?v=1" height="20" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{p.author.patron_tooltip}}" alt="{{p.author.patron_tooltip}}">
@ -91,7 +91,7 @@
<img class="profile-pic-30-hat hat" loading="lazy" src="{{p.author.hat_active(v)[0]}}?h=7" data-bs-toggle="tooltip" data-bs-placement="bottom" title="{{p.author.hat_active(v)[1]}}">
{%- endif %}
</div>
<span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.name_color}};"{% elif p.distinguish_level %}class="mod"{% endif %}>{{p.author_name}}</span>
<span {% if p.author.patron and not p.distinguish_level %}class="patron" style="background-color:#{{p.author.name_color}};"{% elif p.distinguish_level %}class="mod {% if SITE_NAME == 'rDrama' %}mod-rdrama{% endif %}"{% endif %}>{{p.author_name}}</span>
</a>
{% if FEATURES['PRONOUNS'] %}
<span class="pronouns" style="color:#{{p.author.titlecolor}};border-color:#{{p.author.titlecolor}}">{{p.author.pronouns}}</span>

View File

@ -997,7 +997,6 @@ CREATE TABLE public.users (
verified character varying(100),
cardview boolean NOT NULL,
received_award_count integer DEFAULT 0 NOT NULL,
highlightcomments boolean DEFAULT true NOT NULL,
nitter boolean,
truescore integer DEFAULT 0 NOT NULL,
frontsize integer DEFAULT 25 NOT NULL,
@ -2818,4 +2817,3 @@ ALTER TABLE ONLY public.comments
--
-- PostgreSQL database dump complete
--