tangled
alpha
login
or
join now
fuwn.net
/
mayu
1
fork
atom
⭐ Moe-Counter Compatible Website Hit Counter Written in Gleam
mayu.due.moe
hit-counter
svg
moe
1
fork
atom
overview
issues
pulls
pipelines
feat: simple index page
fuwn.net
2 years ago
978a22a5
075cf1f0
verified
This commit was signed with the committer's
known signature
.
fuwn.net
SSH Key Fingerprint:
SHA256:VPdFPyPbd6JkoMyWUdZ/kkTcIAt3sxjXD2XSAZ7FYC4=
+174
3 changed files
expand all
collapse all
unified
split
Earthfile
index.html
src
request.gleam
+1
Earthfile
···
10
10
11
11
COPY +build/erlang-shipment/ /mayu/erlang-shipment/
12
12
COPY themes/ /mayu/themes/
13
13
+
COPY index.html /mayu/
13
14
14
15
WORKDIR /mayu/
15
16
+166
index.html
···
1
1
+
<!DOCTYPE html>
2
2
+
<html lang="en">
3
3
+
<head>
4
4
+
<meta charset="UTF-8" />
5
5
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
+
<title>Mayu</title>
7
7
+
</head>
8
8
+
9
9
+
<body>
10
10
+
<style>
11
11
+
@import url("https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,100..900;1,100..900&display=swap");
12
12
+
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap");
13
13
+
14
14
+
body {
15
15
+
background-color: #0b1622;
16
16
+
color: rgb(159, 173, 189);
17
17
+
font-family: Roboto, -apple-system, BlinkMacSystemFont, Segoe UI, Oxygen,
18
18
+
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
19
19
+
}
20
20
+
21
21
+
main {
22
22
+
background-color: #151f2e;
23
23
+
padding: 20px 35.4px;
24
24
+
border-radius: 4px;
25
25
+
display: flex;
26
26
+
gap: 80px;
27
27
+
max-width: 100%;
28
28
+
position: absolute;
29
29
+
top: 50%;
30
30
+
left: 50%;
31
31
+
transform: translate(-50%, -50%);
32
32
+
box-shadow: 0 0 8px -2px rgba(0, 0, 0, 0.1),
33
33
+
0 6px 20px -3px rgba(0, 0, 0, 0.2);
34
34
+
}
35
35
+
36
36
+
@media (max-width: 768px) {
37
37
+
main {
38
38
+
flex-direction: column;
39
39
+
}
40
40
+
}
41
41
+
42
42
+
img {
43
43
+
display: block;
44
44
+
margin: 10px 0;
45
45
+
width: 100%;
46
46
+
border-radius: 3px;
47
47
+
}
48
48
+
49
49
+
h2 {
50
50
+
font-size: 1rem;
51
51
+
font-weight: 500;
52
52
+
margin-bottom: 15px;
53
53
+
}
54
54
+
55
55
+
input {
56
56
+
background-color: rgb(11, 22, 34);
57
57
+
color: rgb(159, 173, 189);
58
58
+
border-radius: 4px;
59
59
+
border: 0;
60
60
+
height: 40px;
61
61
+
padding: 0 15px;
62
62
+
line-height: 40px;
63
63
+
display: inline-block;
64
64
+
font-size: 0.9rem;
65
65
+
}
66
66
+
67
67
+
input:focus {
68
68
+
outline: none;
69
69
+
}
70
70
+
71
71
+
.label {
72
72
+
margin-top: -10px;
73
73
+
padding-bottom: 0px;
74
74
+
font-size: 0.9rem;
75
75
+
color: rgb(114, 138, 161);
76
76
+
font-weight: normal;
77
77
+
}
78
78
+
79
79
+
pre {
80
80
+
font-family: monospace;
81
81
+
}
82
82
+
83
83
+
.copy-codes {
84
84
+
background-color: #0f1926;
85
85
+
padding: 10px;
86
86
+
border-radius: 4px;
87
87
+
color: #9fadbd;
88
88
+
font-size: 0.9rem;
89
89
+
overflow-x: auto;
90
90
+
white-space: pre-wrap;
91
91
+
word-wrap: break-word;
92
92
+
max-width: 100%;
93
93
+
margin-top: 40px;
94
94
+
}
95
95
+
96
96
+
a {
97
97
+
color: rgb(61, 180, 242);
98
98
+
text-decoration: none;
99
99
+
}
100
100
+
101
101
+
p {
102
102
+
font-size: 0.9rem;
103
103
+
color: #9fadbd;
104
104
+
line-height: 1.4;
105
105
+
}
106
106
+
107
107
+
.attribution {
108
108
+
position: absolute;
109
109
+
bottom: 20px;
110
110
+
left: 35.4px;
111
111
+
}
112
112
+
</style>
113
113
+
114
114
+
<main>
115
115
+
<div>
116
116
+
<h2>Username</h2>
117
117
+
118
118
+
<p class="label">
119
119
+
Enter the username you'd like to use as the ID of your counter.
120
120
+
</p>
121
121
+
122
122
+
<input type="text" id="inputField" placeholder="@demo" />
123
123
+
124
124
+
<p class="attribution">
125
125
+
Written by
126
126
+
<a href="https://anilist.co/user/fuwn/" target="_blank">@Fuwn</a>
127
127
+
128
128
+
<br />
129
129
+
130
130
+
Source code available on
131
131
+
<a href="https://github.com/Fuwn/mayu" target="_blank">GitHub</a>
132
132
+
</p>
133
133
+
</div>
134
134
+
135
135
+
<div class="counter">
136
136
+
<img
137
137
+
id="example"
138
138
+
src="https://counter.due.moe/get/@demo"
139
139
+
alt="Example counter"
140
140
+
/>
141
141
+
142
142
+
<pre id="copy-codes" class="copy-codes">hi</pre>
143
143
+
</div>
144
144
+
</main>
145
145
+
146
146
+
<script>
147
147
+
let inputTimeout;
148
148
+
const idInput = document.getElementById("inputField");
149
149
+
const image = document.getElementById("example");
150
150
+
const copyCodesInput = document.getElementById("copy-codes");
151
151
+
let inputValue = "demo";
152
152
+
153
153
+
copyCodesInput.innerText = `\n\n<img src="https://counter.due.moe/get/@${inputValue}" alt="${inputValue}" />`;
154
154
+
155
155
+
idInput.addEventListener("input", () => {
156
156
+
clearTimeout(inputTimeout);
157
157
+
158
158
+
inputTimeout = setTimeout(() => {
159
159
+
inputValue = idInput.value;
160
160
+
image.src = `https://counter.due.moe/get/@${inputValue}`;
161
161
+
copyCodesInput.innerText = `\n\n<img src="https://counter.due.moe/get/@${inputValue}" alt="${inputValue}" />`;
162
162
+
}, 500);
163
163
+
});
164
164
+
</script>
165
165
+
</body>
166
166
+
</html>
+7
src/request.gleam
···
1
1
import database
2
2
import gleam/json
3
3
import gleam/string_builder
4
4
+
import simplifile
4
5
import svg
5
6
import wisp
6
7
···
18
19
use _ <- middleware(request)
19
20
20
21
case wisp.path_segments(request) {
22
22
+
[] ->
23
23
+
case simplifile.read("index.html") {
24
24
+
Ok(content) ->
25
25
+
wisp.html_response(string_builder.from_string(content), 200)
26
26
+
Error(_) -> wisp.not_found()
27
27
+
}
21
28
["heart-beat"] ->
22
29
wisp.html_response(string_builder.from_string("alive"), 200)
23
30
["get", "@" <> name] -> {