Beta development start

This commit is contained in:
Violet 2024-02-08 18:30:38 +00:00 committed by GitHub
parent 9a7684c048
commit 2b615282af
22 changed files with 102 additions and 825 deletions

2
.gitignore vendored
View file

@ -131,6 +131,4 @@ dist
.pnp.*
# Violet's Purgatory
static/index.html
static/cached
static/style.css

View file

@ -62,6 +62,7 @@
"highlightedWords": {
"birds": "yellow",
"Pissing": "yellow",
"Starwalker": "yellow"
"Starwalker": "yellow",
"word highlighting": "yellow"
}
}

296
index.js
View file

@ -2,7 +2,8 @@ const express = require('express'),
path = require('path'),
fs = require('fs'),
WebSocket = require('ws'),
minify = require('minify-html')
minify = require('minify-html'),
pageUpdater = require('./pageUpdater.js')
var app = express()
@ -98,287 +99,7 @@ function gameTimeFormatter(seconds) {
}
async function pageUpdate() {
var genStart = Date.now()
var statuses = {
"online": {
"text": "Online",
"color": "rgb(100, 255, 100)"
},
"dnd": {
"text": "DND",
"color": "rgb(255, 100, 100)"
},
"idle": {
"text": "Idle",
"color": "rgb(255, 255, 75)"
},
"offline": {
"text": "",
"color": "rgb(255, 255, 255)"
}
}
var html = fs.readFileSync(mainpage).toString()
var addedHTML = ""
if (lanyardData) {
var statusData = statuses[lanyardData.discord_status]
addedHTML += `<p style="color: ${statusData.color}">${statusData.text}</p>`
addedHTML += `<style>.pfp { border-color: ${statusData.color} !important }</style>`
}
html = html.replace("{LANYARD_STATUS}", addedHTML)
addedHTML = ""
if (lanyardData && lanyardData.activities.length > 0) {
if (lanyardData.activities[0].type == 4) {
var status = lanyardData.activities[0]
addedHTML += "<hr><p>"
if (status.emoji) {
if (status.emoji.id) {
addedHTML += `<img class="emoji" src="${getThumbor()}/https://cdn.discordapp.com/emojis/${status.emoji.id}.webp?size=32&quality=lossless"/> `
} else {
addedHTML += status.emoji.name
}
}
if (status.state) {
addedHTML += `<em><span style="color: lightgray; white-space: pre-wrap">"`
// addedHTML += (status.state || "")
var splitStatus = status.state.split(' ')
for (let index = 0; index < splitStatus.length; index++) {
const text = splitStatus[index];
if (highlight[text]) {
addedHTML += `<span style="color: ${highlight[text]}">${text}</span>`
} else {
addedHTML += text
}
addedHTML += ' '
}
addedHTML = addedHTML.trim()
addedHTML += `"</span>`
}
addedHTML += ` - ${lanyardData.discord_user.display_name} ${new Date(Date.now()).getFullYear()}</em></p>`
}
}
html = html.replace("{LANYARD_QUOTE}", addedHTML)
addedHTML = ""
var debounce = false
if (lanyardData && lanyardData.activities.length > 0) {
for (let index = 0; index < lanyardData.activities.length; index++) {
const activity = lanyardData.activities[index];
var found = false
for (let index = 0; index < lanyardData.activities.length; index++) {
const act = lanyardData.activities[index]
if (act.name == activity.name) {
if (Object.keys(act).length > Object.keys(activity).length) {
found = true
}
}
}
if (found) {
continue
}
if (!debounce && activity.type != 4) {
addedHTML += `<h2><hr>What I'm up to:</h2><div class="container-fluid row" style="margin: 0; padding: 0; display: flex;">`
debounce = true
}
function get_img(activity, size = "large_image") {
if (cachedImages[get_img_url(activity, size)]) {
var fn = cachedImages[get_img_url(activity, size)]
var fp = path.join(staticpath, 'cached', fn)
} else {
return 'imgs/notFound.png'
}
return '/cached/' + fn
}
function songStats() {
var html = ``
if (activity.assets && activity.assets.large_text != activity.details) {
html += `
<br> Album: ${activity.assets.large_text || " "}
<br> Artist: ${activity.state || " "}
`
} else {
html += `<br> Artist: ${activity.state || " "}`
}
return html
}
if (activity.type == 2) {
var timeLeft = Math.round((activity.timestamps.end - Date.now()) / 1000)
var currentPercent = (Date.now() - activity.timestamps.start) / (activity.timestamps.end - activity.timestamps.start) * 100
addedHTML += `
<div class="chip activity col-md-6 testing">
<img src="${get_img(activity)}" title="${activity.assets.large_text || activity.assets.small_text || activity.state || ""}">
<p>
Listening to <span style="color: limegreen;">${activity.name}</span>
<br> Song: ${activity.details || " "}
${songStats()}
<br>
<span class="lengthBar lengthBar${index}"><span></span></span>
${timeFormatter((activity.timestamps.end - activity.timestamps.start) / 1000)}
</p>
</div>
<style>
.lengthBar${index} > span {
animation-name: songSlider${index};
animation-duration: ${timeLeft}s;
animation-timing-function: linear;
}
@keyframes songSlider${index} {
0% {
width: ${currentPercent}%;
}
100% {
width: 100%;
}
}
</style>
`
} else if (activity.type == 0) {
var time = activity.created_at
if (activity.timestamps) {
time = activity.timestamps.start
}
if (!activity.assets) {
activity.assets = { "large_text": " ", "small_text": " " }
}
function smch() {
if (get_img_url(activity, "small_image")) {
return `<img class="smallimg" src="${get_img(activity, "small_image")}" title="${activity.assets.small_text}">`
}
return ""
}
addedHTML += `
<div class="chip activity col-md-6 testing">
<img src="${get_img(activity)}" title="${activity.assets.large_text}">
${smch()}
<p>
Playing <span style="color: rgb(255, 100, 150);">${activity.name}</span>
<br> ${(activity.details || activity.assets.large_text || " ")}
<br> ${(activity.state || activity.assets.small_text || " ")}
<br> ${gameTimeFormatter((Date.now() - time) / 1000)}
</p>
</div>
`
} else if (activity.type != 4) {
var time = activity.created_at
if (activity.timestamps) {
time = activity.timestamps.start
}
if (!activity.assets) {
activity.assets = { "large_text": " ", "small_text": " " }
}
addedHTML += `
<div class="chip activity col-md-6 testing">
<img src="${get_img(activity)}" title="${activity.assets.large_text || activity.assets.small_text}">
<p>
<span style="color: rgb(225, 200, 255);">${activity.name}</span>
<br> ${(activity.details || activity.assets.large_text || " ")}
<br> ${(activity.state || activity.assets.small_text || " ")}
<br> ${gameTimeFormatter((Date.now() - time) / 1000)}
</p>
</div>
`
}
}
}
if (addedHTML) {
addedHTML += "</div>"
}
html = html.replace("{LANYARD_FULL}", addedHTML)
addedHTML = ""
var socialsHTML = fs.readFileSync(path.join(__dirname, 'static/socials/index.html')).toString()
// socialsHTML = socialsHTML.substring(0, socialsHTML.lastIndexOf("</div>"))
addedHTML += "<h2><hr>Socials</h2>"
addedHTML += socialsHTML.substring(socialsHTML.indexOf("<div"), socialsHTML.lastIndexOf("</div>") + 6)
html = html.replace("{SOCIALS}", addedHTML)
var now = new Date()
currentMonth = now.getMonth() + 1
if ([11, 12].includes(currentMonth)) { // The Below HTML is copy and pasted from that one site :>
html = html.replace("{SEASONAL_EFFECT}", fs.readFileSync(path.join(__dirname, 'static/snow.html')))
} else {
html = html.replace("{SEASONAL_EFFECT}", "")
}
var quote = randomQuotes[Math.floor(Math.random() * randomQuotes.length)]
var splitQuote = quote.split(' ')
var finalQuote = ''
for (let index = 0; index < splitQuote.length; index++) {
const text = splitQuote[index];
if (highlight[text]) {
finalQuote += `<span style="color: ${highlight[text]}">${text}</span>`
} else {
finalQuote += text
}
finalQuote += ' '
}
quote = finalQuote.trim()
quote = quote.replace("{QUOTE_COUNT}", randomQuotes.length)
html = html.replace("{RANDOM_QUOTE}", quote)
if (process.env.BRANCH == "dev") {
html = html.replace("{OPPOSITE_URL}", "www")
html = html.replace("{OPPOSITE_BRANCH}", "Main")
} else {
html = html.replace("{OPPOSITE_URL}", "beta")
html = html.replace("{OPPOSITE_BRANCH}", "Beta")
}
html = html.replace("{COMMIT_COUNT}", commitCount)
html = html.replace("{UPTIME}", gameTimeFormatter((Date.now() - uptime) / 1000))
html = html.replace("{LAST_LANYARD}", gameTimeFormatter((Date.now() - lastLanyardUpdate) / 1000) + ' ago')
html = html.replace("{QUOTE_COUNT}", randomQuotes.length)
html = html.replace("{CACHED_IMAGES}", fs.readdirSync(path.join(staticpath, 'cached')).length)
html = html.replace("{GENERATION_TIME}", Math.ceil(Date.now() - genStart).toString() + 'ms')
//fs.writeFileSync(path.join(__dirname, 'static/index.html'), html)
return html
}
app.use(pageUpdater.middleWare)
// Lanyard Stuffs
@ -447,12 +168,11 @@ function socketeer() {
socketeer()
app.get('/', async (req, res) => {
var html = await (pageUpdate())
res.send(minify.minify(html).toString('utf-8'))
})
app.use(express.static(staticpath))
// app.get('/index.html', async (req, res) => {
// console.log(req.params[0])
// var html = await (pageUpdate(req.params[0]))
// res.send(minify.minify(html))
// })
app.use((req, res, next) => {
res.status(404).send(`

34
pageUpdater.js Normal file
View file

@ -0,0 +1,34 @@
const path = require('path'),
fs = require('fs')
var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json')))
var highlightedWords = config.highlightedWords
function converter(html) {
var highTable = Object.keys(highlightedWords)
for (let index = 0; index < highTable.length; index++) {
var term = highTable[index];
var replacement = `<span style="color: ${highlightedWords[term]}">${term}</span>`
html = html.replaceAll(term, replacement)
}
return html
}
module.exports = { middleWare: function(req, res, next) {
var filePath = req.baseUrl + req.path
if (filePath.trim() == "/") {
filePath = "/index.html"
}
filePath = path.join(__dirname, 'static', filePath || 'index.html')
var data = fs.readFileSync(filePath).toString()
if (req.path.includes("style.css")) {
res.setHeader("Content-Type", "text/css")
res.send(data)
} else {
data = converter(data)
res.send(data)
}
}
}

View file

@ -1,100 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="./style.css">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Welcome to Violet's Purgatory" property="og:title" />
<meta content="Hi, I'm Violet, a 15 year old web developer with strong ambitions. You can find more info on my site!" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<!-- To any who dare read this code! I stole the code above off of stack overflow :P-->
</head>
<body>
<h1>Welcome to Violet's Purgatory</h1>
<p style="white-space: pre-wrap;">{RANDOM_QUOTE}</p>
<p>{COMMIT_COUNT} Commits</p>
<div class="fadediv">
<div class="container-fluid row" id="card">
<h2>Violet</h2>
<div style="display: flex; justify-content: center; align-items: center;">
<img src="https://api.violets-purgatory.dev/v1/pfp" class="pfp">
<div>
<p><a href="pronouns">They/Them</a></p>
<p>Developer</p>
{LANYARD_STATUS}
</div>
</div>
<div>
<hr>
<!-- <span style="white-space: nowrap;"> -->
<!-- <p class="chip"><a href="https://status.violets-purgatory.dev">Status</a></p> -->
<p class="chip"><a href="https://fs.violets-purgatory.dev">FileShare</a></p>
<p class="chip"><a href="./socials">Socials</a></p>
<p class="chip"><a href="./projects">Projects</a></p>
<p class="chip"><a href="https://ko-fi.com/bingus_violet" style="color: rgb(255, 100, 100);">Donate</a></p>
<!-- </span> -->
<!-- <p class="chip"><a href="./extras">Extras</a></p> -->
<br>
<!-- <span style="white-space: nowrap;"> -->
<p class="chip"><a href="https://blog.violets-purgatory.dev">Blog</a></p>
<p class="chip"><a href="./faq">FAQ</a></p>
<p class="chip"><a href="https://{OPPOSITE_URL}.violets-purgatory.dev">{OPPOSITE_BRANCH}</a></p>
<!-- </span> -->
{LANYARD_QUOTE}
</div>
</div>
<noscript>
<p style="font-size: 0.9rem;">Fun fact: This website uses no Javascript! Everything dynamic (E.G. The
discord status) is done
server-side, so enjoy :D</p>
</noscript>
<p>Check out the source code on <a href="https://codeberg.org/Bingus_Violet/Violets-Purgatory">Codeberg</a></p>
{LANYARD_FULL}
<h2><hr>Announcement!</h2>
<p>Soon enough, I will begin work on a complete rewrite for Violet's Purgatory. This rework will be done in hopes of:<br>
</p>
<ul>
<li>Spicing up the website's visuals</li>
<li>Optimizing the site</li>
<li>Making the codebase more readable</li>
<li>Reducing the amount of code</li>
<li>Making the site more easily scalable</li>
</ul>
<p>
The codeberg repository for this site was made 6 months ago, not counting all the contributions I had done before then. Thats alot of time, and i've learnt so much since then! This was even my first project to do Dynamic HTML!<br>
It has been an absolutely wonderful journey, but as per usual, its about time we do some reworking!<br>
I may still keep this version of the website up for archival sake (And, worst comes to worst, I'll still have it on archive.org)<br>
This rewrite will take time, so from now on, updates to Violet's Purgatory will be slow or nonexistant.<br>
And if you're curious, you can always check the beta branch to see how progress is going!<br>
Thank you for your time and encouragement, It's been a fun year on violets-purgatory.dev :)
</p>
<p class="note">P.S.: As my final gift, CSS is now minified!!! woohoo!!!</p>
{SOCIALS}
<h2><hr>Silly Stats:</h2>
<p>Just some funny stats for the site :3</p>
<ul>
<li>Uptime: {UPTIME}</li>
<li>Last Lanyard Update: {LAST_LANYARD}</li>
<li>Quotes: {QUOTE_COUNT}</li>
<li>Images Cached: {CACHED_IMAGES}</li>
<li>Page Generation Time: {GENERATION_TIME}</li>
</ul>
{SEASONAL_EFFECT}
</div>
</body>
</html>

View file

@ -1,45 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../../style.css">
<meta content="Discord Status - Violet's Purgatory" property="og:title" />
<meta content="The answers to all your not-so-frequently-asked questions!" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<title>Discord Status - Violet's Purgatory</title>
</head>
<body>
<a class="chip" href="../../">Home</a>
<div class="fadediv">
<noscript><h2>Sorry! This page requires javascript... The rest of this site doesn't, though!</h2></noscript>
<h1>Discord Status (W.I.P)</h1>
<p>This is a more fleshed out version of the main discord status on my site, issue being, it requires Javascript. So, I choose not to use it, though it coulda been cool...</p>
<p>I still am tempted to add something like it to the main page, and just make it compatible without javascript, but I worry that'd upset people.</p>
<div class="container-fluid row" id="card">
<h2>Violet</h2>
<div style="display: flex; justify-content: center; align-items: center;">
<img src="https://thumbor-production-0e82.up.railway.app/unsafe/https://api.lanyard.rest/534132311781015564.png" class="pfp">
<div>
<p>Developer</p>
<p id="discStatus" style="transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1);">Offline</p>
</div>
</div>
<div>
<p id="discQuote"></p>
</div>
</div>
</div>
</body>
<script src="./index.js"></script>
</html>

View file

@ -1,74 +0,0 @@
var lanyard = new WebSocket('wss://api.lanyard.rest/socket')
var statuses = {
"online": {
"text": "Online",
"color": "rgb(100, 255, 100)"
},
"dnd": {
"text": "DND",
"color": "rgb(255, 100, 100)"
},
"idle": {
"text": "Idle",
"color": "rgb(255, 255, 75)"
},
"offline": {
"text": "Offline",
"color": "rgb(125, 125, 125)"
}
}
function beat(dur) {
lanyard.send(JSON.stringify({
op: 3
}))
setTimeout(() => {
beat(dur)
}, dur);
}
lanyard.addEventListener("message", (res) => {
var data = JSON.parse(res.data)
if (data.op == 1) {
beat(data.d.heartbeat_interval)
lanyard.send(JSON.stringify({
op: 2,
d: {
subscribe_to_id: "534132311781015564"
}
}))
} else if (data.op == 0) {
var lanyardData = data.d
// $("*").text(JSON.stringify(lanyardData))
var statusData = statuses[lanyardData.discord_status]
$("#discStatus").text(statusData.text)
$("#discStatus").css("color", statusData.color)
$(".pfp").css("border-color", statusData.color)
if (lanyardData) {
$("#discQuote").html("")
for (let index = 0; index < lanyardData.activities.length; index++) {
const activity = lanyardData.activities[index];
var status = lanyardData.activities[0]
var addedHTML = ""
addedHTML += "<hr>"
if (activity.type == 4) {
if (status.emoji) {
if (status.emoji.id) {
addedHTML += `<img class="emoji" src="https://cdn.discordapp.com/emojis/${status.emoji.id}.webp?size=32&quality=lossless"/> `
} else {
addedHTML += status.emoji.name
}
}
addedHTML += `<em><span style="color: lightgray">"${lanyardData.activities[0].state}"</span> - ${lanyardData.discord_user.display_name} ${new Date(Date.now()).getFullYear()}</em>`
$("#discQuote").html(addedHTML)
}
}
}
}
})

View file

@ -1,27 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="FAQ - Violet's Purgatory" property="og:title" />
<meta content="The answers to all your not-so-frequently-asked questions!" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>Extras - Violet's Purgatory</title>
</head>
<h1>Extras</h1>
<p>Just some fun things that really don't have use on the main page but exist anyway!</p>
<div class="fadediv container-fluid ">
<p class="chip"><a href="./discord">Dynamic Discord Status (Javascript, W.I.P)</a></p>
<p class="chip"><a href="../pronouns">Pronouns (here bc it's hard to find on main page)</a></p>
</div>
<a class="chip" href="../">Home</a>
</body>
</html>

View file

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="FAQ - Violet's Purgatory" property="og:title" />
<meta content="The answers to all your not-so-frequently-asked questions!" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>FAQ - Violet's Purgatory</title>
</head>
<body>
<h1>FAQ</h1>
<p>Some questions that, nobody has ever <em>actually</em> asked, but I'm gonna act like they have because its fun!</p>
<div class="row container-fluid fadediv" style="margin: auto;">
<h2><hr>How?</h2>
<p>Well, believe it or not, there's no javascript involved!!!! :D<br><span style="color: darkgray; font-size: 0.9rem;">Or well no client side javascript anyway...</span></p>
<p>Using a wonderful program <a>called lanyard</a>, my website is connected to a websocket that sends a signal every time my discord updates (E.G. My status changes... or I open a game...)</p>
<p>Then, it uses the new info to dynamically generate the main page!<br>The more technically advanced of you can check it out on Codeberg, but be warned, it's coded <b>TERRIBLY.</b> I didn't really wanna use a library so i coded it all myself, and there's no actual system, just pure chaos :/</p>
<h2><hr>Why?</h2>
<p>Actually, i'm not really sure<br>
Originally I think this site started out because I saw people had these cool "carrd" sites and stuff
in their bio and wanted to make something close to carrd but made by myself.</p>
<p>Nowadays, though, this site is used more as a learning opportunity!
I try to do new, experimental, wacky things here, and use them in projects later.</p>
<p>For example, my Youtube Converter, Univerter, I was only able to make because I already learnt how to make
dynamically generated HTML. (Univerter, as I am writing this, has no dynamically generated HTML, but it used to!)
</p>
<h2><hr>How does it update?</h2>
<p>
I use a site called railway for hosting, which connects to a github repository, which is synced with a codeberg repository. The github repo is only there because, <em>annoyingly</em>, Railway only supports docker and Github.
<br>
The main site (violets-purgatory.dev) updates with the origin branch, while the beta site (beta.violets-purgatory.dev) updates with the dev branch. I originally wanted to use dev as the subdomain for the sake of consistancy, but, dev.violets-purgatory.dev just doesn't really roll off the tongue...
</p>
<h2><hr>Why do you (hate/never use) Javascript?</h2>
<p>Because its more fun :D Inevitably, I would put something more informative here, like "for the sake of compatibility" which, don't get me wrong, a huge part of it is so that people who disable javascript can use my site, but also, if you've seen my CSS it should be clear I don't try to be the <em>most</em> backwards compatible.</p>
</div>
<a class="chip" href="../">Home</a>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

29
static/index.html Normal file
View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Welcome to Violet's Purgatory" property="og:title" />
<meta content="Hi, I'm Violet, a 15 year old web developer with strong ambitions. You can find more info on my site!" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<!-- To any who dare read this code! I stole the code above off of stack overflow :P-->
</head>
<body>
<h1>Welcome to Violet's Purgatory</h1>
<p>Currently i'm working on the new system for word highlighting!</p>
<p>You can see that it is pretty much the same as before, outside of the code being a little bit shorter and more dispersed (I didn't know until recently that "replaceAll" was a function...)</p>
<p>The big difference, is unlike the original site, this can <a href="./test.html">apply to all pages!</a></p>
</body>
</html>

View file

@ -1,88 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="Projects - Violet's Purgatory" property="og:title" />
<meta content="All my silly lil projects in one, concise(?) page. To be updated over time!" property="og:description"/>
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>Projects - Violet's Purgatory</title>
</head>
<body>
<h1>Projects</h1>
<p>All my silly lil projects in one, concise(?) page. To be updated over time!</p>
<div class="fadediv">
<div class="project">
<h1>Violet's Purgatory</h1>
<div class="project-inner container-fluid row">
<div class="col-lg-6">
<img src="/imgs/violets-purgatory-screenshot.png">
</div>
<div class="col-lg-6">
<p>Nothing much to be said- its the site you're using right now! I've made many variations of it over the years, and it's been on 3 different domains. First it was "violets-puragtory.github.io", then moved to "violets-puragtory.com", and lastly (now) to violets-purgatory.dev! My first time coding any HTML on my own, and technically the first iteration of this site, was a css animation of the "homophobic dog" meme sliding on screen accompanied by the role sound effect from amongus. I was like 13 don't judge me I thought it was funny.</p>
</div>
</div>
</div>
<div class="project">
<h1>Univerter</h1>
<div class="project-inner container-fluid row">
<div class="col-lg-6">
<img src="/imgs/univerter-screenshot.png">
</div>
<div class="col-lg-6">
<p>Univerter is my Javascriptless Youtube video downloader! I tend to call it a "converter" rather than a downloader, because unlike many other youtube downloaders, mine actually converts to more formats than youtube supports! I've been working on Univerter for a long time, and i hope to support more sites soon :>. It also comes with a (experimental) standalone video converter! Please, check it out at <a href="https://yt.violets-purgatory.dev">yt.violets-purgatory.dev</a> and report any issues or feature requests!</p>
</div>
</div>
</div>
<div class="project">
<h1>Violet's Limbo</h1>
<div class="project-inner container-fluid row">
<div class="col-lg-6">
<img src="/imgs/violets-limbo-screenshot.png">
</div>
<div class="col-lg-6">
<p>Don't get it confused with Violet's Purgatory! I know, me and my stupid naming schemes T^T. Violet's Limbo is the name for my blog site, where i just kinda post unimportant game rants! Currently it's very early in development, and much of it's code is sorta "Make now fix later"... But despite its rushed development, i love posting blogs on there! Currently there isn't much, but feel free to check it out at <a href="https://blog.violets-purgatory.dev">blog.violets-purgatory.dev</a>!</p>
</div>
</div>
</div>
<div class="project">
<h1>Simpletube</h1>
<div class="project-inner container-fluid row">
<div class="col-lg-6">
<img src="/imgs/Simpletube-screenshot.png">
</div>
<div class="col-lg-6">
<p>Simpletube is my work in progress Javascriptless Youtube Frontend! It's not quite done, but it does support many features, and i'm quite happy with how it's going so far! Sadly, it currently isn't hosted anywhere, but the code can be found <a href="https://codeberg.org/Bingus_Violet/SimpleTube">here</a>! I hope to re-continue development on it soon, and finally find somewhere to host it!</p>
</div>
</div>
</div>
<div class="project">
<h1>SteamRPC</h1>
<div class="project-inner container-fluid row">
<div class="col-lg-6">
<img src="/imgs/steamrpc-screenshot.png">
</div>
<div class="col-lg-6">
<p>When playing games like Gunfire Reborn, I was annoyed that they'd only support Rich presence on Steam but not Discord. I was also having issues at the time with getting games under proton to show up on discord in general. As a solution, i made a (Linux only, sadly) software called SteamRPC, which converts the presence of any Steam game onto Discord using a Rich presence bot. It certainly needs optimization, but it's a project im proud of, and one of my few projects I use all the time! Find it <a href="https://codeberg.org/Bingus_Violet/SteamRPC">here!</a></p>
</div>
</div>
</div>
<p>There are, of course, a few more projects (E.G. Discord Embedder) but I feel they're too early in development for me to want to put them here.</p>
<a class="chip" href="../">Home</a>
</div>
</body>
</html>

View file

@ -1,66 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="Pronouns - Violet's Purgatory" property="og:title" />
<meta content="Check out this page to see more about my preffered pronouns :P" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>Pronouns - Violet's Purgatory</title>
</head>
<body>
<!-- Yet again I would like to apologize for the absolutely atrocious code !! -->
<h1>Pronouns</h1>
<div class="fadediv row container-fluid">
<div class="col-sm-12">
<p class="chip love">Love</p>
<p class="chip like">Like</p>
<p class="chip silly">Fine if used Silly/Jokingly</p>
<p class="chip fine">Neutral</p>
<p class="chip hate">Hate</p>
</div>
<div class="col-sm-6">
<hr>
<h2>Names</h2>
<p class="chip love">Violet, Vivi, Vi, V</p>
<p class="chip like">Purple</p>
<p class="chip silly">Purple guy</p>
</div>
<div class="col-sm-6">
<hr>
<h2>Pronouns</h2>
<p class="chip love">They/Them</p>
<p class="chip fine">She/Her, etc...</p>
<p class="chip hate">He/Him</p>
</div>
<div class="col-sm-6">
<hr>
<h2>Honorifics</h2>
<p class="chip like">Mrs/Ms, Miss, Ma'am</p>
<p class="chip silly">Sir, Mr</p>
<p class="chip fine">Mx</p>
</div>
<div class="col-sm-6">
<hr>
<h2>Other words</h2>
<p class="chip love">Any silly Enby/Slime/Moth related terms</p>
<p class="chip like">Dude, Partner, Bro</p>
<p class="chip silly">Guy, Pardner</p>
</div>
</div>
<hr>
<p>If there's any more confusion, or a section you'd want me to add, please put an issue on codeberg :D</p>
<a class="chip" href="../">Home</a>
</body>
</html>

View file

@ -1,57 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="Socials - Violet's Purgatory" property="og:title" />
<meta content="On this page, you can find all my social media, such as fedi, matrix, and more." />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>Socials - Violet's Purgatory</title>
</head>
<body>
<h1>Socials</h1>
<div class="row container-fluid fadediv" style="margin: auto;">
<p>Here's where you can find me most... if you wanted to do that for some reason?</p>
<div class="col-sm-6">
<hr>
<h3>Chat Applications:</h3>
<p class="chip" style="color: limegreen;">Matrix: <a href="https://matrix.to/#/@bingus_violet:catgirl.cloud" rel="me">@bingus_violet&ZeroWidthSpace;:catgirl.cloud</a></p>
<p class="chip"><span style="color: red;">Revolt:</span> BingusViolet#5573</p>
<p class="chip"><span style="color: rgb(125, 150, 225)">Discord:</span> bingus_violet</p>
</div>
<div class="col-sm-6">
<hr>
<h3>Social media:</h3>
<p class="chip" style="color: rgb(200, 175, 255);">Fedi: <a href="https://void.lgbt/bingus_violet" rel="me">@Bingus_Violet&ZeroWidthSpace;@void.lgbt</a></p>
<p class="chip" style="color: rgb(255, 80, 80)">Youtube: <a href="https://www.youtube.com/channel/UChcrBJNJLZucy3TPyGyAY2g">Violet's Fiasco</a></p>
</div>
<div class="col-sm-6">
<hr>
<h3>Coding sites:</h3>
<p class="chip" style="color: aqua">Codeberg: <a href="https://codeberg.org/Bingus_Violet">Bingus_Violet</a>
<p class="chip" style="color: rgb(100, 100, 255)">Docker: <a href="https://hub.docker.com/u/bingusviolet">bingusviolet</a>
<p class="chip">Github: <a href="https://github.com/Violets-puragtory">Violets-puragtory</a></p>
</p>
</div>
<div class="col-sm-6">
<hr>
<h3>Game sites:</h3>
<p class="chip" style="color: darkgrey">Steam: <a href="https://steamcommunity.com/id/Violet-The-Thigh-high-obtainer/">Violet</a></p>
</div>
</div>
<a class="chip" href="../">Home</a>
</body>
</html>

1
static/style.css Normal file
View file

@ -0,0 +1 @@
@import url('./bootstrap.css');@font-face {font-display: swap;font-family: 'Rubik';font-style: normal;font-weight: 400;src: url('./fonts/rubik-v28-latin-regular.woff2') format('woff2');}* {font-family: 'Rubik', Verdana, Geneva, Tahoma, sans-serif;padding: 0;text-align: center;}h1 {color: rgb(225, 215, 255);font-size: 2.5rem;}h2 {font-size: 2rem;color: rgb(225, 215, 255)}h3 {font-size: 1.65rem}h3,li {color: white;}ul, ol {display: inline-block}li {font-size: 1.2rem;text-align: left;}body,html {overflow-x: hidden;margin: auto;background-color: rgb(15, 4, 45);background: linear-gradient(rgb(20, 4, 55), black);width: 100vw;height: 100vh;margin: 0;padding: 0;background-attachment: local;}body {padding: 2.5%;}.fadediv {animation-name: fade-in;animation-duration: .75s;animation-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);margin: auto;max-width: 1000px;}a {color: rgb(175, 225, 255);display: inline-block;transition: 1.5s all cubic-bezier(0.075, 0.82, 0.165, 1);}.chip {position: relative;z-index: 3;font-size: 1.3rem;border: 2px gray solid;border-radius: 6px;background-color: black;padding: 8px;margin: 3px;display: inline-block;transform: scale(0.95);transition: transform 1.25s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 2s cubic-bezier(0.075, 0.82, 0.165, 1);}.chip,.chip>* {text-decoration: none;}.chip:hover {background-color: rgb(10, 0, 25);transform: scale(1);/* font-size: 1.35rem; */border-color: white;transition: transform 0.75s cubic-bezier(0.075, 0.82, 0.165, 1), background-color 3s cubic-bezier(0.075, 0.82, 0.165, 1);}.chip:hover > .smallimg {background-color: rgb(10, 0, 25);}.activity {border-width: 3px;border-radius: 10px;overflow: hidden;margin: auto;padding: 0;display: flex;position: relative;z-index: 3;}.activity>p {width: 100%;overflow-wrap: break-word;}.activity>img {width: 128px;aspect-ratio: 1/1;object-fit: cover;}.activity>.smallimg {width: 64px;height: 64px;position: absolute;bottom: 0px;left: 72px;border-radius: 50px;background: black;padding: 5px;/* border: 2px gray solid; */transform: scale(0.9);}.activity>.smallimg:hover {transform: scale(1);}a:hover {color: white;transition: 0.5s all cubic-bezier(0.075, 0.82, 0.165, 1);}p {color: white;font-size: 1.2rem;padding: 0;margin: 10px;}img:not(.project-inner > div > img) {width: 100%;max-width: 135px;transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1);}.pfp {border-radius: 15px;border: darkgray 4px solid;width: 60%;aspect-ratio: 1/1;transform: scale(0.9);border-radius: 50%;}.pfp:hover {transform: scale(1);border-color: rgb(255, 200, 255);object-fit: cover;}.emoji {width: 32px;border-radius: 10%;/* border: 1px gray solid; */}hr {color: white;opacity: 0.25;border-width: 2px;margin: 15px 10%;}#card {background-color: rgb(15, 5, 80);padding: 15px;border: 2px white solid;margin: 20px auto;width: 95%;max-width: 800px;z-index: 3;position: relative;}.me {border-color: limegreen;}.project {background-color: rgba(35, 35, 35, 0.8);padding: 15px;border: 2px gray solid;margin: 20px 0px;border-radius: 15px;}.project-inner {overflow: hidden;padding: 0;margin: auto;z-index: 3;}.project-inner>div>img {object-fit: cover;border: 2px white solid;width: 80%;max-width: 500px;margin: auto;border-radius: 10px;}.project>p {display: inline-block;}/* I am so sorry about this code,,, */.love::before {content: "<3 ";color: rgb(255, 100, 150);}.like::before {content: ":) ";color: limegreen;}.silly::before {content: ":P ";color: aqua;}.fine::before {content: ":/ ";color: yellow;}.hate::before {content: ">:( ";color: red;}.love {border-color: rgb(255, 100, 150);}.like {border-color: limegreen;}.silly {border-color: aqua;}.fine {border-color: yellow;}.hate {border-color: red;}.up {border-color: limegreen;}.mid {border-color: yellow;}.down {border-color: red;}.post {background-color: rgba(85, 50, 150, 0.3);border: 2px gray solid;display: inline-block;/* border-radius: 15px; */padding: 10px;margin: 8px;}.minipfp {width: 70px;display: inline-block;margin-right: 10px;border: 2px lightgray solid;border-radius: 5px;}.lengthBar {background-color: rgb(50, 40, 60);display: inline-block;width: 80%;height: 10px;padding: 0;overflow: hidden;border-radius: 5px;margin-right: 1.9%;}.lengthBar>span {margin: 0;padding: 0;width: 100%;background-color: rgb(200, 200, 230);height: 20px;display: block;position: relative;}.note {font-size: 0.95rem;color: lightgray;}@keyframes fade-in {0% {opacity: 0;transform: translateY(50vh);}100% {opacity: 1;transform: none;}}

27
static/test.html Normal file
View file

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/style.css">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Violet's Purgatory</title>
<meta name="darkreader-lock">
<meta content="Welcome to Violet's Purgatory" property="og:title" />
<meta content="Hi, I'm Violet, a 15 year old web developer with strong ambitions. You can find more info on my site!" property="og:description" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<!-- To any who dare read this code! I stole the code above off of stack overflow :P-->
</head>
<body>
<h1>Starwalker</h1>
<p>See? I told you!</p>
</body>
</html>

View file

@ -1,29 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../style.css">
<meta content="Games - Violet's Purgatory" property="og:title" />
<meta content="Check out information about the games I develop- and even play them in the web!" />
<meta content="https://api.violets-purgatory.dev/v1/pfp" property="og:image" />
<meta content="#a200ff" data-react-helmet="true" name="theme-color" />
<title>Todo - Violet's Purgatory</title>
</head>
<body>
<h1>To-do</h1>
<div class="fadediv">
<p>Not only does this page list things that are currently being worked on, but also links to those things. Keep in mind that most of these, though, might not even have development started on them, so please be patient</p>
<h2>To-do:</h2>
<ul>
<li>Reduce bloated CSS by splitting file into multiple.</li>
</ul>
</div>
</body>
</html>