1
0
mirror of https://github.com/osmarks/website synced 2025-10-18 15:37:39 +00:00

initial commit

This commit is contained in:
2020-03-08 17:13:14 +00:00
commit ccd4f72d2d
54 changed files with 4730 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
---
title: Arbitrary Points
description: Collect Arbitrary Points and achievements by doing things on this website! See how many you have! Do nothing with them because you can't! This is the final form of gamification.
slug: points
---
<div id="app">
<noscript>You need JS on for this to work. I really don't know what you expected at this point.</noscript>
</div>
<div class="smallinfo">All Arbitrary Points data is stored and processed only on your device.
There is no serverside component whatsoever.
If you don't like this regardless, you can bug me to implement an off switch, attempt to ignore it, or use Internet Explorer 6.
Ideas for features and achievements and whatever else wanted and may be accepted.
This is very easy to meddle with using the browser console, as I haven't tried to prevent that, but if you cheat all the time you may ruin any fun this might have brought.
</div>
<script src="/assets/js/mithril.js"></script>
<script>
if (!("Promise" in window)) {
document.getElementById("app").innerHTML = "Your browser is seemingly too outdated for this to work. Sorry! Try installing/updating Firefox."
}
</script>
<script defer src="./index.js">
</script>
<style>
button {
border: 1px solid black;
background: lightgray;
border-radius: 0;
padding: 0.5em;
}
.metricname {
padding-right: 1em;
}
</style>

110
experiments/points/index.js Normal file
View File

@@ -0,0 +1,110 @@
const round = x => Math.round(x * 1e10) / 1e10
const prefixes = ["", "kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "yotta"]
const siPrefix = (value, unit) => {
let i = 0
let b = value
while (b > 1000) {
b /= 1000
i++
}
return `${round(b).toString()} ${prefixes[i]}${unit}${value !== 1 ? "s" : ""}`
}
const metricDisplayInfo = {
pagesVisited: { name: "Pages visited", units: "page" },
timeSpent: { name: "Time spent", units: "second" },
achievements: { name: "Achievements" },
foesVanquished: { name: "Foes vanquished", units: "foe" },
deaths: { name: "Deaths", units: "death" },
loremParagraphs: { name: "Lorem Ipsum paragraphs seen", units: "paragraph" },
commentsPosted: { name: "Comments posted", units: "comment" },
greatestInfipage: { name: "Largest infipage visited" }
}
const displayMetric = metric => {
let name = metric[0]
let value = metric[1]
const displayInfo = metricDisplayInfo[name]
if (displayInfo) {
name = displayInfo.name
if (displayInfo.units) {
value = siPrefix(value, displayInfo.units)
}
}
return m("tr", m("td.metricname", name), m("td.metricvalue", value))
}
const Metrics = {
metrics: null,
load: async () => {
Metrics.metrics = await points.readAllMetrics()
m.redraw()
},
view: () => m("p", Metrics.metrics === null ? "Loading..." : m("table.metrics", Array.from(Metrics.metrics.entries()).map(displayMetric)))
}
const zfill = (num, z) => num.toString().padStart(z, "0")
const formatDate = x => `${zfill(x.getHours(), 2)}:${zfill(x.getMinutes(), 2)}:${zfill(x.getSeconds(), 2)} ${zfill(x.getDate(), 2)}/${zfill(x.getMonth() + 1, 2)}/${zfill(x.getFullYear(), 4)}`
const renderAchievement = a =>
m(".achievement", { style: `background-color: ${colHash(a.title)}` }, [
a.timestamp && m(".title", { title: a.id }, `Achievement achieved at ${formatDate(new Date(a.timestamp))}`),
m(".title", a.title),
m(".description", a.description),
m(".conditions", `Unlocked by: ${a.conditions}`),
a.points && m(".points", `${a.points} points`)
])
const Achievements = {
achievements: [],
load: async () => {
const raw = await points.getAchievements()
Achievements.achievements = raw.map(ach => {
const info = points.achievementInfo[ach.id]
const out = {
title: ach.id || "???",
description: `Unrecognized achievement ${ach.id}.`,
conditions: "???",
...ach
}
if (info) { Object.assign(out, info) }
m.redraw()
return out
})
Achievements.achievements.sort((a, b) => a.timestamp < b.timestamp)
},
view: () => m(".achievements-listing", Achievements.achievements.map(renderAchievement))
}
const reset = async () => {
if (prompt(`This will reset your points, achievements and metrics. If you are sure, please type "yes I am definitely sure".`) === "yes I am definitely sure") {
if (confirm("Are you really very sure?")) {
await points.reset()
window.location.reload()
}
}
}
let pointsCount = "[loading...]"
const reloadPoints = async () => { pointsCount = await points.getPoints() }
const App = {
view: () => m("div", [
m("h2", `Points: ${pointsCount}`),
m("button", { onclick: reset }, "Reset"),
m(Metrics),
m(Achievements)
])
}
m.mount(document.getElementById("app"), App)
Metrics.load()
reloadPoints()
Achievements.load()
points.unlockAchievement("visitArbitraryPoints")
document.addEventListener("points-update", () => { reloadPoints(); Achievements.load() })