Skip to content

Commit a99f95b

Browse files
committed
feat: add ability to change code lang
1 parent d25e1d4 commit a99f95b

File tree

9 files changed

+191
-137
lines changed

9 files changed

+191
-137
lines changed

Sources/App/Middlewares/SiteMiddleware.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct SiteMiddleware<Context: RequestContext>: RouterController {
3131
URLRoutingMiddleware(self.siteRouter) { req, ctx, route in
3232
try withDependencies {
3333
$0.currentRoute = route
34+
$0.currentCodeLang = .swift
3435
} operation: {
3536
switch route {
3637
case .robots:

Sources/EnvVars/Environment+.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ public extension DependencyValues {
2626
get { self[EnvironmentKey.self] }
2727
set { self[EnvironmentKey.self] = newValue }
2828
}
29-
}
29+
}

Sources/Models/Project.swift

Lines changed: 0 additions & 24 deletions
This file was deleted.

Sources/Pages/Components/HeaderView.swift

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,41 +42,45 @@ private struct CodeSelector: HTML {
4242
code { "</>" }
4343
}
4444
.inlineStyle("font-weight", "bold")
45-
.inlineStyle("font-size", "0.7em")
45+
.inlineStyle("font-size", "0.8em")
4646
.inlineStyle("background", "unset")
4747
.inlineStyle("border", "1.16px solid #444")
4848
.inlineStyle("border-radius", "0.3rem")
4949
.inlineStyle("padding", "0.28rem 0.4rem")
5050
.inlineStyle("color", "#AAA")
51-
.inlineStyle("pointer", "cursor")
51+
.inlineStyle("cursor", "pointer")
5252

5353
ul(.hidden, .v.bind(attrOrProp: "hidden", !visible)) {
5454
for code in CodeLang.allCases {
5555
li {
5656
button(
5757
.v.on(.click, selected.assign(Expression(code))),
58-
.v.on(.click, modifiers: .prevent, visible.assign(!visible))
58+
.v.on(.click, modifiers: .prevent, visible.assign(!visible)),
59+
.v.bind(attrOrProp: "style", Expression(rawValue: "{ background: \(selected) == \(Expression(code)) ? '#3A3A3A' : undefined }")),
60+
.style("border-radius: 0.75rem")
5961
) {
60-
code.title
62+
p {
63+
code.title
64+
}
65+
.inlineStyle("width", "100%")
66+
.inlineStyle("padding", "0.5rem")
6167
}
6268
.inlineStyle("all", "unset")
63-
.inlineStyle("display", "inline-block")
69+
.inlineStyle("display", "block")
6470
.inlineStyle("width", "100%")
65-
.inlineStyle("padding", "0.5rem")
6671
.inlineStyle("cursor", "pointer")
67-
// TODO: Add background highlight
68-
// .inlineStyle("background", "#2A2A2A", pseudo: .hover)
6972
}
7073
.inlineStyle("overflow", "hidden")
7174
}
7275
}
7376
.inlineStyle("position", "absolute")
7477
.inlineStyle("right", "0")
7578
.inlineStyle("list-style", "none")
76-
.inlineStyle("padding", "0")
79+
.inlineStyle("padding", "0.4rem")
7780
.inlineStyle("margin-top", "0.25rem")
78-
.inlineStyle("background", "#383838")
79-
.inlineStyle("border-radius", "0.75rem")
81+
.inlineStyle("background", "#2A2A2A")
82+
.inlineStyle("border-radius", "1rem")
83+
.inlineStyle("font-size", "1.125em")
8084
}
8185
.inlineStyle("position", "relative")
8286
}

Sources/Pages/Components/Page.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ extension Page {
7777
}
7878
/// Xcode Styling
7979
style {
80-
".xml .hljs-meta{color:#6C7986}.hljs-comment,.hljs-quote{color:#6C7986}.hljs-tag,.hljs-attribute,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-name{color:#FC5FA3}.hljs-variable,.hljs-template-variable{color:#FC5FA3}.hljs-code,.hljs-string,.hljs-meta-string{color:#FC6A5D}.hljs-regexp,.hljs-link{color:#5482FF}.hljs-title,.hljs-symbol,.hljs-bullet,.hljs-number{color:#41A1C0}.hljs-section,.hljs-meta{color:#FC5FA3}.hljs-class .hljs-title,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-params{color:#D0A8FF}.hljs-attr{color:#BF8555}.hljs-subst{color:#FFF}.hljs-formula{font-style:italic}.hljs-selector-id,.hljs-selector-class{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}"
80+
".xml .hljs-meta{color:#6C7986}.hljs-comment,.hljs-quote{color:#6C7986}.hljs-tag,.hljs-attribute,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-name{color:#FC5FA3}.hljs-template-variable{color:#FC5FA3}.hljs-code,.hljs-string,.hljs-meta-string{color:#FC6A5D}.hljs-regexp,.hljs-link{color:#5482FF}.hljs-title,.hljs-symbol,.hljs-bullet,.hljs-number{color:#41A1C0}.hljs-section,.hljs-meta{color:#FC5FA3}.hljs-class .hljs-title,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-params{color:#D0A8FF}.hljs-attr{color:#BF8555}.hljs-subst{color:#FFF}.hljs-formula{font-style:italic}.hljs-selector-id,.hljs-selector-class{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}"
8181
}
8282
script(
8383
.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"),
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import HTML
2+
import Models
3+
import Dependencies
4+
5+
struct SectionView<Content: HTML>: HTML {
6+
@Dependency(\.currentCodeLang) var currentCodeLang
7+
8+
let id: String
9+
let codeHeader: @Sendable (CodeLang) -> String
10+
@HTMLBuilder let content: @Sendable () -> Content
11+
12+
var body: some HTML {
13+
let allCodeLangs = CodeLang.allCases.sorted(initial: currentCodeLang)
14+
section(.id(self.id)) {
15+
div {
16+
header {
17+
pre {
18+
a(.href("#\(self.id)")) {
19+
for (idx, lang) in allCodeLangs.enumerated() {
20+
code {
21+
slugToFileName(lang)
22+
}
23+
.attribute("v-cloak", value: idx == allCodeLangs.startIndex ? nil : "")
24+
.attribute("v-if", value: idx == allCodeLangs.startIndex ? "selected == '\(lang.rawValue)'" : nil)
25+
.attribute("v-else-if", value: allCodeLangs.startIndex < idx && idx < allCodeLangs.index(before: allCodeLangs.endIndex) ? "selected == '\(lang.rawValue)'" : nil)
26+
.attribute("v-else", value: idx == allCodeLangs.index(before: allCodeLangs.endIndex) ? "" : nil)
27+
}
28+
}
29+
.inlineStyle("color", "#777")
30+
}
31+
.inlineStyle("font-size", "0.75em")
32+
.inlineStyle("font-weight", "500")
33+
.inlineStyle("text-align", "end")
34+
.inlineStyle("padding", "1.5rem 1.5rem 0")
35+
36+
pre {
37+
for (idx, lang) in allCodeLangs.enumerated() {
38+
code(.class("hljs language-\(lang.rawValue)")) {
39+
"""
40+
// \(slugToFileName(lang))
41+
// Portfolio
42+
\(codeHeader(lang))
43+
"""
44+
}
45+
.attribute("v-cloak", value: idx == allCodeLangs.startIndex ? nil : "")
46+
.attribute("v-if", value: idx == allCodeLangs.startIndex ? "selected == '\(lang.rawValue)'" : nil)
47+
.attribute("v-else-if", value: allCodeLangs.startIndex < idx && idx < allCodeLangs.index(before: allCodeLangs.endIndex) ? "selected == '\(lang.rawValue)'" : nil)
48+
.attribute("v-else", value: idx == allCodeLangs.index(before: allCodeLangs.endIndex) ? "" : nil)
49+
}
50+
}
51+
.inlineStyle("padding", "0.75rem 1.5rem 1.5rem")
52+
}
53+
// .inlineStyle("background-image", "radial-gradient(#2A2A2A 1px, transparent 0)")
54+
// .inlineStyle("background-size", "12px 12px")
55+
56+
self.content()
57+
}
58+
.containerStyling()
59+
}
60+
.wrappedStyling()
61+
}
62+
63+
private func slugToFileName(_ lang: CodeLang) -> String {
64+
let fileName = switch lang {
65+
case .swift:
66+
self.id.components(separatedBy: "-")
67+
.map { component -> String in
68+
if let first = component.first {
69+
first.uppercased().appending(component.dropFirst())
70+
} else {
71+
component
72+
}
73+
}
74+
.joined()
75+
case .rust: self.id
76+
case .typescript:
77+
self.id.components(separatedBy: "-")
78+
.enumerated()
79+
.map { (idx, component) -> String in
80+
if idx == 0 {
81+
component
82+
} else if let first = component.first {
83+
first.uppercased().appending(component.dropFirst())
84+
} else {
85+
component
86+
}
87+
}
88+
.joined()
89+
}
90+
return fileName + "." + lang.ext
91+
}
92+
}
93+
94+
extension [CodeLang] {
95+
func sorted(initial lang: CodeLang) -> Self {
96+
[lang] + self.filter { $0 != lang }
97+
}
98+
}

Sources/Pages/HomePage.swift

Lines changed: 49 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ import ActivityClient
22
import Dependencies
33
import Foundation
44
import HTML
5+
import Models
56
import Vue
67

78
public struct HomePage: Page {
8-
struct State: Encodable, Sendable {
9-
let codeStyle = 0
10-
let selection: Int? = nil
11-
}
12-
139
public let title = "Erik Bautista Santibanez | Portfolio"
1410
public let lang = "en"
1511

@@ -33,74 +29,6 @@ public struct HomePage: Page {
3329
}
3430
}
3531

36-
private struct SectionView<Content: HTML>: HTML {
37-
let codeTag: String
38-
let codeHeader: String
39-
@HTMLBuilder let content: @Sendable () -> Content
40-
41-
private var id: String {
42-
codeTag.enumerated().flatMap { idx, char in
43-
[
44-
char.isUppercase && idx > 0 ? "-" : nil,
45-
String(char).lowercased(),
46-
]
47-
.compactMap(\.self)
48-
}
49-
.joined()
50-
}
51-
52-
var body: some HTML {
53-
section(.id(self.id)) {
54-
div {
55-
header {
56-
CodeTag(id: self.id, codeTag: self.codeTag)
57-
CodeHeader(codeTag: self.codeTag, codeHeader: self.codeHeader)
58-
}
59-
60-
self.content()
61-
}
62-
.containerStyling()
63-
}
64-
.wrappedStyling()
65-
}
66-
67-
struct CodeTag: HTML {
68-
let id: String
69-
let codeTag: String
70-
71-
var body: some HTML {
72-
pre {
73-
a(.href("#\(self.id)")) {
74-
code { "\(self.codeTag).swift" }
75-
}
76-
.inlineStyle("color", "#777")
77-
}
78-
.inlineStyle("font-size", "0.75em")
79-
.inlineStyle("font-weight", "500")
80-
.inlineStyle("text-align", "end")
81-
.inlineStyle("padding", "1.5rem 1.5rem 0")
82-
}
83-
}
84-
85-
struct CodeHeader: HTML {
86-
let codeTag: String
87-
let codeHeader: String
88-
89-
var body: some HTML {
90-
pre {
91-
code(.class("hljs language-swift")) {
92-
"""
93-
/// \(self.codeTag).swift
94-
/// Portfolio
95-
\(self.codeHeader)
96-
"""
97-
}
98-
}
99-
.inlineStyle("padding", "0.75rem 1.5rem 1.5rem")
100-
}
101-
}
102-
}
103-
10432
private struct UserView: HTML {
10533
@Dependency(\.activityClient) private var activityClient
10634

@@ -120,21 +48,41 @@ private struct UserView: HTML {
12048
return [location.city, location.state, location.region == "United States" ? nil : location.region]
12149
.compactMap(\.self)
12250
.joined(separator: ", ")
123-
12451
}
12552

53+
@HTMLBuilder
12654
var body: some HTML {
127-
SectionView(
128-
codeTag: "User",
129-
codeHeader: """
130-
struct User: Portfolio {
131-
let name = "Erik Bautista Santibanez"
132-
let role = "Mobile & Web Developer"
133-
let home = "\(residency ?? .default)"\
134-
\(currentLocation.flatMap { "\n let location = \"Currently in \($0)\"" } ?? "")
55+
SectionView(id: "user") { lang in
56+
switch lang {
57+
case .swift:
58+
"""
59+
let user = User(
60+
name: "Erik Bautista Santibanez",
61+
role: "Mobile & Web Developer",
62+
home: "\(residency ?? .default)"\
63+
\(currentLocation.flatMap { ",\n location: \"Currently in \($0)\"" } ?? "")
64+
)
65+
"""
66+
case .typescript:
67+
"""
68+
const user = {
69+
name: "Erik Bautista Santibanez",
70+
role: "Mobile & Web Developer",
71+
home: "\(residency ?? .default)"\
72+
\(currentLocation.flatMap { ",\n location: \"Currently in \($0)\"" } ?? "")
73+
};
74+
"""
75+
case .rust:
76+
"""
77+
let user = Portfolio {
78+
name: "Erik Bautista Santibanez",
79+
role: "Mobile & Web Developer",
80+
home: "\(residency ?? .default)"\
81+
\(currentLocation.flatMap { ",\n location: \"Currently in \($0)\"" } ?? "")
82+
}
83+
"""
13584
}
136-
"""
137-
) {
85+
} content: {
13886
EmptyHTML()
13987
}
14088
}
@@ -156,13 +104,22 @@ private struct UserView: HTML {
156104

157105
private struct PostsView: HTML {
158106
var body: some HTML {
159-
// TODO: Allow changing `fetch(.all)` based on filter.
160-
SectionView(
161-
codeTag: "DevLogs",
162-
codeHeader: """
163-
var logs: [DevLog] = await fetch(.all)
164-
"""
165-
) {
107+
SectionView(id: "dev-logs") { lang in
108+
switch lang {
109+
case .swift:
110+
"""
111+
let logs: [DevLog] = await fetch(.all)
112+
"""
113+
case .typescript:
114+
"""
115+
const logs = await fetch(Filter.All)
116+
"""
117+
case .rust:
118+
"""
119+
let logs = fetch(Filter::All).await
120+
"""
121+
}
122+
} content: {
166123
for (num, post) in Post.allCases.enumerated().reversed() {
167124
PostView(number: num, post: post)
168125
}
@@ -290,8 +247,7 @@ private struct PostsView: HTML {
290247
struct PostLinkView: HTML {
291248
let link: Post.Link
292249

293-
@HTMLBuilder
294-
var body: some HTML {
250+
@HTMLBuilder var body: some HTML {
295251
a(
296252
.href(self.link.href),
297253
.target(.blank),

0 commit comments

Comments
 (0)