From 10ed08795a1107f713e11ffcad33fba4312babfc Mon Sep 17 00:00:00 2001 From: Bingus_Violet Date: Sun, 18 Feb 2024 08:01:58 -0600 Subject: [PATCH] Activities are back! --- config.json | 4 +- index.js | 40 ++------ overcomplicatedStatuses.js | 195 +++++++++++++++++++++++++++++++++++++ pageUpdater.js | 71 +++++++++----- static/imgs/notFound.png | Bin 0 -> 27691 bytes static/index.html | 20 ++-- static/root.css | 88 ++++++++++++++++- static/socials/index.html | 29 +++--- static/style.css | 14 +-- 9 files changed, 368 insertions(+), 93 deletions(-) create mode 100644 overcomplicatedStatuses.js create mode 100644 static/imgs/notFound.png diff --git a/config.json b/config.json index d5b46f1..59aa117 100644 --- a/config.json +++ b/config.json @@ -75,6 +75,8 @@ "Github": "gray", "Steam": "lightgray", "Univerter": "rgb(200, 175, 255)", - "Ko-fi": "rgb(255, 150, 150)" + "Ko-fi": "rgb(255, 150, 150)", + "Revolt": "rgb(255, 50, 50)", + "Discord": "rgb(150, 150, 255)" } } \ No newline at end of file diff --git a/index.js b/index.js index 2361b03..5f38520 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,6 @@ const PORT = process.env.PORT || 8080 const staticpath = path.join(__dirname, 'static') var mostRecentVideo = undefined -var lanyardData = undefined var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json'))) @@ -39,38 +38,17 @@ app.listen(PORT, () => { console.log("Violet's Purgatory is now listening on port: " + PORT) }) -if (!fs.existsSync(path.join(staticpath, 'cached'))) { - fs.mkdirSync(path.join(staticpath, 'cached')) -} +var cachePath = path.join(staticpath, 'cached') +var imgPath = path.join(staticpath, 'imgs') -var randomQuotes = config.quotes - -var commitCount = "300+" - -function timeFormatter(seconds) { - seconds = Math.ceil(seconds) - var minutes = Math.floor(seconds / 60) - - if (seconds % 60 < 10) { - return `${minutes}:0${seconds % 60}` - } else { - return `${minutes}:${seconds % 60}` +if (!fs.existsSync(cachePath)) { + fs.mkdirSync(cachePath) +} else { + var files = fs.readdirSync(cachePath) + for (let index = 0; index < files.length; index++) { + const file = files[index]; + fs.rmSync(path.join(cachePath, file)) } - -} - -function gameTimeFormatter(seconds) { - seconds = Math.ceil(seconds) - var minutes = Math.ceil(seconds / 60) - var hours = Math.floor(minutes / 60) - if (seconds <= 60) { - return 'about ' + seconds + ' seconds' - } else if (minutes < 60) { - return `${minutes} Minutes` - } - - return `${hours} hours and ${minutes % 60} minutes` - } app.use(pageUpdater.middleWare) \ No newline at end of file diff --git a/overcomplicatedStatuses.js b/overcomplicatedStatuses.js new file mode 100644 index 0000000..b9a57d1 --- /dev/null +++ b/overcomplicatedStatuses.js @@ -0,0 +1,195 @@ +const path = require("path") + +function get_img_url(activity, size = "large_image") { + + if ("assets" in activity) { + var image = activity.assets[size] + + if (image) { + if (image.includes("https/")) { + return decodeURIComponent('https://' + image.substr(image.indexOf('https/') + 6, image.length)) + } else if (image.includes("spotify")) { + return decodeURIComponent('https://i.scdn.co/image/' + image.substr(image.indexOf('spotify:') + 8, image.length)) + } else { + return decodeURIComponent(`https://cdn.discordapp.com/app-assets/${activity.application_id}/${image}.png`) + } + } + } + + if (!image) { + if (activity.name in activityImages) { + return decodeURIComponent(activityImages[activity.name]) + } else { + return null + } + } +} + + +function timeFormatter(seconds) { + seconds = Math.ceil(seconds) + var minutes = Math.floor(seconds / 60) + + if (seconds % 60 < 10) { + return `${minutes}:0${seconds % 60}` + } else { + return `${minutes}:${seconds % 60}` + } + +} + +function gameTimeFormatter(seconds) { + seconds = Math.ceil(seconds) + var minutes = Math.ceil(seconds / 60) + var hours = Math.floor(minutes / 60) + if (seconds <= 60) { + return 'about ' + seconds + ' seconds' + } else if (minutes < 60) { + return `${minutes} Minutes` + } + + return `${hours} hours and ${minutes % 60} minutes` + +} + +module.exports = { + activitiesToHTML: (lanyardData, cachedImages) => { + var debounce = false + var addedHTML = "" + + 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 += `


What I'm up to:

` + 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(__dirname, 'static/cached', fn) + } else { + return 'imgs/notFound.png' + } + + return '/cached/' + fn + } + + function songStats() { + var html = `` + + if (activity.assets && activity.assets.large_text != activity.details) { + html += ` +
Album: ${activity.assets.large_text || " "} +
Artist: ${activity.state || " "} + ` + } else { + html += `
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 += ` +
+ +

+ Listening to ${activity.name} +
Song: ${activity.details || " "} + ${songStats()} +
+ + ${timeFormatter((activity.timestamps.end - activity.timestamps.start) / 1000)} +

+
+ + ` + } 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 `` + } + return "" + } + + + addedHTML += ` +
+ + ${smch()} +

+ Playing ${activity.name} +
${(activity.details || activity.assets.large_text || " ")} +
${(activity.state || activity.assets.small_text || " ")} +
${gameTimeFormatter((Date.now() - time) / 1000)} +

+
+ ` + } 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 += ` +
+ +

+ ${activity.name} +
${(activity.details || activity.assets.large_text || " ")} +
${(activity.state || activity.assets.small_text || " ")} +
${gameTimeFormatter((Date.now() - time) / 1000)} +

+
+ ` + } + } + } + return addedHTML + "
" + } +} \ No newline at end of file diff --git a/pageUpdater.js b/pageUpdater.js index 3ec5451..2f91687 100644 --- a/pageUpdater.js +++ b/pageUpdater.js @@ -1,7 +1,8 @@ const path = require('path'), fs = require('fs'), WebSocket = require('ws'), - minify = require('minify-html') + minify = require('minify-html'), + activityToHTML = require("./overcomplicatedStatuses.js") var config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json'))) @@ -16,30 +17,6 @@ var lanyardData = undefined var uptime = Date.now() function converter(html) { - if (lanyardData) { - var statusData = config.discStatuses[lanyardData.discord_status] - } else { - var statusData = config.discStatuses.offline - } - var replacers = { - "COMMIT_COUNT": commitCount, - "RANDOM_QUOTE": quotes[Math.floor(Math.random() * quotes.length)], - "QUOTE_COUNT": quotes.length, - "RANDOM_TITLE": titles[Math.floor(Math.random() * titles.length)], - "DISCORD_STATUS": - `${statusData.text}` + - ``, - "UPTIME": uptime, - "TOPBAR": `

Socials

` - } - - var rpTable = Object.keys(replacers) - - for (let index = 0; index < rpTable.length; index++) { - const text = rpTable[index]; - html = html.replaceAll(`{${text}}`, replacers[text]) - } - while (html.includes("{PATH_")) { var pagePath = html.substring(html.indexOf("{PATH_")) pagePath = pagePath.substring(6, pagePath.indexOf('}')) @@ -52,6 +29,42 @@ function converter(html) { html = html.replace(stringIndex, pageHTML) } + var statusText = "" + + if (lanyardData) { + var statusData = config.discStatuses[lanyardData.discord_status] + var username = lanyardData.discord_user.username + + if (lanyardData.activities[0] && lanyardData.activities[0].type == 4) { + var statusText = `

${lanyardData.activities[0].state}

` + } + } else { + var statusData = config.discStatuses.offline + var username = "bingus_violet" + } + + var replacers = { + "COMMIT_COUNT": commitCount, + "RANDOM_QUOTE": quotes[Math.floor(Math.random() * quotes.length)], + "QUOTE_COUNT": quotes.length, + "RANDOM_TITLE": titles[Math.floor(Math.random() * titles.length)], + "DISCORD_STATUS": + `${statusData.text}` + + ``, + "UPTIME": uptime, + "TOPBAR": `

Socials

`, + "DISCORD_USER": username, + "CUSTOM_STATUS": statusText, + "ACTIVITIES": activityToHTML.activitiesToHTML(lanyardData, cachedImages) + } + + var rpTable = Object.keys(replacers) + + for (let index = 0; index < rpTable.length; index++) { + const text = rpTable[index]; + html = html.replaceAll(`{${text}}`, replacers[text]) + } + var bodyHTML = html.substring(html.indexOf("") + 6, html.lastIndexOf("")) var highTable = Object.keys(highlightedWords) for (let index = 0; index < highTable.length; index++) { @@ -73,6 +86,14 @@ module.exports = { var filePath = (req.baseUrl + req.path).trim() + if (filePath.includes("cached") || filePath.includes("imgs")) { + filePath = path.join(__dirname, 'static', filePath) + console.log(filePath) + res.send(fs.readFileSync(filePath)) + + return + } + if (filePath.includes(".")) { } else { diff --git a/static/imgs/notFound.png b/static/imgs/notFound.png new file mode 100644 index 0000000000000000000000000000000000000000..a75008064bb0e95018f5587ea05bc6a6450f1274 GIT binary patch literal 27691 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

{RANDOM_QUOTE}

-

Violet

+

{Violet}

@@ -34,23 +34,19 @@

{DISCORD_STATUS}

- Donate (Ko-fi) -
-

Hi! I'm Violet, a 15 year old web and game developer.
I aspire to make fast and Javascript free websites! I'm currently learning the Godot Engine, and have been becoming quite fluent in NodeJS.

+
+
+

Hi! I'm Violet, a 15 year old web and game developer.
I aspire to make fast and Javascript free websites! I'm currently learning the Godot Engine, but most of my time recently has been spent learning NodeJS.

Beta site Blog Clipdump + {CUSTOM_STATUS}
+ {ACTIVITIES} -
-

Main Projects

- Univerter - {Steam}RPC - -
- -

Socials

+
+

Socials

{PATH_SOCIALS} diff --git a/static/root.css b/static/root.css index c17de76..a1bf430 100644 --- a/static/root.css +++ b/static/root.css @@ -11,8 +11,8 @@ } #card { - background-color: rgb(75, 25, 100); - padding: 15px; + background-color: rgb(25, 5, 80); + padding: 15px 5px; border: 2px white solid; margin: 20px auto; width: 95%; @@ -43,6 +43,90 @@ border-radius: 50%; } +.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; + padding: 5px; + justify-content: center; +} + +.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); +} + +img:not(.project-inner > div > img) { + width: 100%; + max-width: 135px; + transition: all 2s cubic-bezier(0.075, 0.82, 0.165, 1); +} + +@media screen and (min-width: 750px) { + .activity-container { + display: grid; + grid-template-columns: 1fr 1fr; + grid-gap: 10px; + } + + .activity { + margin: auto; + width: 100%; + align-content: center; + /* border: 2px white solid; */ + } +} + +.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; +} + + @keyframes mainText { 0% { transform: translateY(calc(50vh - 6rem)) scale(1.5); diff --git a/static/socials/index.html b/static/socials/index.html index 39cb3d9..aca6bdb 100644 --- a/static/socials/index.html +++ b/static/socials/index.html @@ -23,44 +23,41 @@

Socials

+

Here's most of the sites you can find me on- if you needed that for some reason?

+
+

Please note I am extremely unhinged and gay on Fedi, I don't use Github, and I barely understand Docker.

diff --git a/static/style.css b/static/style.css index 94631c4..de88965 100644 --- a/static/style.css +++ b/static/style.css @@ -40,7 +40,7 @@ transform: scale(1.05); } -#topbar > * { +#topbar>* { display: inline-block; font-size: 1.5rem; } @@ -83,7 +83,7 @@ h3 { grid-template-columns: 1fr 1fr; grid-gap: 10px; } - + .grid-child { margin: auto; align-content: center; @@ -91,8 +91,6 @@ h3 { } } - - .chip { position: relative; z-index: 3; @@ -129,8 +127,12 @@ h3 { } hr { - border: 2px gray solid; - margin: 20px; + color: white; + border: white solid; + opacity: 0.25; + border-width: 2px; + margin: 15px 10%; + /* background-color: none; */ } p {