Add Fishbowl archive #41
|
@ -14,3 +14,4 @@ adminmailer/config.go
|
|||
adminmailer/adminmailer
|
||||
local/backups
|
||||
/tmp
|
||||
*.exe
|
||||
|
|
|
@ -0,0 +1,624 @@
|
|||
.fishbowl {
|
||||
background-color: #36393e;
|
||||
color: #dcddde;
|
||||
font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl a {
|
||||
color: #00aff4;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fishbowl a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.fishbowl img {
|
||||
object-fit: contain;
|
||||
image-rendering: high-quality;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
|
||||
.fishbowl .preamble {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
max-width: 100%;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.fishbowl .preamble__guild-icon-container {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
.fishbowl .preamble__guild-icon {
|
||||
max-width: 88px;
|
||||
max-height: 88px;
|
||||
}
|
||||
|
||||
.fishbowl .preamble__entries-container {
|
||||
grid-column: 2;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.fishbowl .preamble__entry {
|
||||
margin-bottom: 0.15rem;
|
||||
color: #ffffff;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.fishbowl .preamble__entry--small {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog {
|
||||
padding: 1rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-container {
|
||||
background-color: transparent;
|
||||
transition: background-color 1s ease;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-container--highlighted {
|
||||
background-color: rgba(114, 137, 218, 0.2);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-container--pinned {
|
||||
background-color: rgba(249, 168, 37, 0.05);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
padding: 0.15rem 0;
|
||||
direction: ltr;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message:hover {
|
||||
background-color: #32353b;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message:hover .chatlog__short-timestamp {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-aside {
|
||||
grid-column: 1;
|
||||
width: 72px;
|
||||
padding: 0.15rem 0.15rem 0 0.15rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-symbol {
|
||||
height: 10px;
|
||||
margin: 6px 4px 4px 36px;
|
||||
border-left: 2px solid #4f545c;
|
||||
border-top: 2px solid #4f545c;
|
||||
border-radius: 8px 0 0 0;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__short-timestamp {
|
||||
display: none;
|
||||
color: #a3a6aa;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
direction: ltr;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__message-primary {
|
||||
grid-column: 2;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference {
|
||||
display: flex;
|
||||
margin-bottom: 0.15rem;
|
||||
align-items: center;
|
||||
color: #b5b6b8;
|
||||
font-size: 0.875rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-avatar {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 0.25rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-author {
|
||||
margin-right: 0.3rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-content {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-link {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-link * {
|
||||
display: inline;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-link .hljs {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-link:hover {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler) {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reference-edited-timestamp {
|
||||
margin-left: 0.25rem;
|
||||
color: #a3a6aa;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
direction: ltr;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__header {
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__author {
|
||||
font-weight: 500;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__bot-label {
|
||||
position: relative;
|
||||
top: -0.1rem;
|
||||
margin-left: 0.3rem;
|
||||
padding: 0.05rem 0.3rem;
|
||||
border-radius: 3px;
|
||||
background-color: #5865F2;
|
||||
color: #ffffff;
|
||||
font-size: 0.625rem;
|
||||
font-weight: 500;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__timestamp {
|
||||
margin-left: 0.3rem;
|
||||
color: #a3a6aa;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
direction: ltr;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__content {
|
||||
padding-right: 1rem;
|
||||
font-size: 0.95rem;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__edited-timestamp {
|
||||
margin-left: 0.15rem;
|
||||
color: #a3a6aa;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
margin-top: 0.3rem;
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden {
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-spoiler-caption {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
z-index: 999;
|
||||
padding: 0.4rem 0.8rem;
|
||||
border-radius: 20px;
|
||||
transform: translate(-50%, -50%);
|
||||
background-color: rgba(0, 0, 0, 0.9);
|
||||
color: #dcddde;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.05rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-spoiler-caption {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden:hover .chatlog__attachment-spoiler-caption {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-media {
|
||||
max-width: 45vw;
|
||||
max-height: 500px;
|
||||
vertical-align: top;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-media {
|
||||
filter: blur(44px);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-generic {
|
||||
max-width: 520px;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 10px;
|
||||
border: 1px solid #292b2f;
|
||||
border-radius: 3px;
|
||||
background-color: #2f3136;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment--hidden .chatlog__attachment-generic {
|
||||
filter: blur(44px);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-generic-icon {
|
||||
float: left;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-generic-size {
|
||||
color: #72767d;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__attachment-generic-name {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed {
|
||||
display: flex;
|
||||
margin-top: 0.3rem;
|
||||
max-width: 520px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-color-pill {
|
||||
flex-shrink: 0;
|
||||
width: 0.25rem;
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-color-pill--default {
|
||||
background-color: #202225;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-content-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0.5rem 0.6rem;
|
||||
border: 1px solid rgba(46, 48, 54, 0.6);
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
background-color: rgba(46, 48, 54, 0.3);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-content {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-author-container {
|
||||
display: flex;
|
||||
margin-bottom: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-author-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 0.5rem;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-author {
|
||||
color: #ffffff;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
direction: ltr;
|
||||
unicode-bidi: bidi-override;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-author-link {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-title {
|
||||
margin-bottom: 0.5rem;
|
||||
color: #ffffff;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-description {
|
||||
color: #dcddde;
|
||||
font-weight: 500;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-fields {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0 0.5rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-field {
|
||||
flex: 0;
|
||||
min-width: 100%;
|
||||
max-width: 506px;
|
||||
padding-top: 0.6rem;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-field--inline {
|
||||
flex: 1;
|
||||
flex-basis: auto;
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-field-name {
|
||||
margin-bottom: 0.2rem;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-field-value {
|
||||
color: #dcddde;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-thumbnail {
|
||||
flex: 0;
|
||||
max-width: 80px;
|
||||
max-height: 80px;
|
||||
margin-left: 1.2rem;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-image-container {
|
||||
margin-top: 0.6rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-image {
|
||||
max-width: 500px;
|
||||
max-height: 400px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-footer {
|
||||
margin-top: 0.6rem;
|
||||
color: #dcddde;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-footer-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 0.2rem;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-footer-text {
|
||||
vertical-align: middle;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-plainimage {
|
||||
max-width: 45vw;
|
||||
max-height: 500px;
|
||||
vertical-align: top;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-spotify {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-youtube-container {
|
||||
margin-top: 0.6rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__embed-youtube {
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__sticker {
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__sticker--media {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reactions {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reaction {
|
||||
display: flex;
|
||||
margin: 0.35rem 0.1rem 0.1rem 0;
|
||||
padding: 0.125rem 0.375rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 8px;
|
||||
background-color: #2f3136;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reaction:hover {
|
||||
border: 1px solid hsla(0,0%,100%,.2);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reaction-count {
|
||||
min-width: 9px;
|
||||
margin-left: 0.35rem;
|
||||
color: #b9bbbe;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__reaction:hover .chatlog__reaction-count {
|
||||
color: #dcddde;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown {
|
||||
max-width: 100%;
|
||||
line-height: 1.3;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-preserve {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-spoiler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-spoiler--hidden {
|
||||
cursor: pointer;
|
||||
background-color: #202225;
|
||||
color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-spoiler--hidden:hover {
|
||||
background-color: rgba(32, 34, 37, 0.8);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-spoiler--hidden::selection {
|
||||
color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-quote {
|
||||
display: flex;
|
||||
margin: 0.05rem 0;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-quote-border {
|
||||
margin-right: 0.5rem;
|
||||
border: 2px solid #4f545c;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-pre {
|
||||
background-color: #2f3136;
|
||||
font-family: "Consolas", "Courier New", Courier, monospace;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-pre--multiline {
|
||||
margin-top: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
border: 2px solid #282b30;
|
||||
border-radius: 5px;
|
||||
color: #b9bbbe;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-pre--multiline.hljs {
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-pre--inline {
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-mention {
|
||||
border-radius: 3px;
|
||||
padding: 0 2px;
|
||||
background-color: rgba(88, 101, 242, .3);
|
||||
color: #dee0fc;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-mention:hover {
|
||||
background-color: #5865f2;
|
||||
color: #ffffff
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__markdown-timestamp {
|
||||
border-radius: 3px;
|
||||
padding: 0 2px;
|
||||
color: #a3a6aa;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__emoji {
|
||||
width: 1.325rem;
|
||||
height: 1.325rem;
|
||||
margin: 0 0.06rem;
|
||||
vertical-align: -0.4rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__emoji--small {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.fishbowl .chatlog__emoji--large {
|
||||
width: 2.8rem;
|
||||
height: 2.8rem;
|
||||
}
|
||||
|
||||
.fishbowl .postamble {
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
.fishbowl .postamble__entry {
|
||||
color: #ffffff;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
@font-face {
|
||||
src: url(whitney-300-1FE35.woff);
|
||||
font-family: Whitney;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
src: url(whitney-400-83E7B.woff);
|
||||
font-family: Whitney;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
src: url(whitney-500-47E37.woff);
|
||||
font-family: Whitney;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
src: url(whitney-600-9EC09.woff);
|
||||
font-family: Whitney;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
src: url(whitney-700-A7A71.woff);
|
||||
font-family: Whitney;
|
||||
font-weight: 700;
|
||||
}
|
|
@ -5,7 +5,7 @@ import "runtime"
|
|||
// See this file for a good color reference:
|
||||
// https://github.com/fatih/color/blob/master/color.go
|
||||
|
||||
var Reset = "\033[0m"
|
||||
var Reset = "\033[0m" // BgBlack is here because Windows just does not care about you at all.
|
||||
var Bold = "\033[1m"
|
||||
var Faint = "\033[2m"
|
||||
var Italic = "\033[3m"
|
||||
|
@ -36,14 +36,6 @@ var BgWhite = "\033[47m"
|
|||
|
||||
func init() {
|
||||
if runtime.GOOS == "windows" {
|
||||
Reset = ""
|
||||
Red = ""
|
||||
Green = ""
|
||||
Yellow = ""
|
||||
Blue = ""
|
||||
Purple = ""
|
||||
Cyan = ""
|
||||
Gray = ""
|
||||
White = ""
|
||||
Reset = BgBlack + Reset
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,15 @@ func TestPodcastRSS(t *testing.T) {
|
|||
AssertRegexMatch(t, BuildPodcastRSS(), RegexPodcastRSS, nil)
|
||||
}
|
||||
|
||||
func TestFishbowlIndex(t *testing.T) {
|
||||
AssertRegexMatch(t, BuildFishbowlIndex(), RegexFishbowlIndex, nil)
|
||||
}
|
||||
|
||||
func TestFishbowl(t *testing.T) {
|
||||
AssertRegexMatch(t, BuildFishbowl("oop"), RegexFishbowl, nil)
|
||||
bvisness marked this conversation as resolved
Outdated
|
||||
AssertRegexNoMatch(t, BuildFishbowl("oop")+"/otherfiles/whatever", RegexFishbowl)
|
||||
}
|
||||
|
||||
func TestForum(t *testing.T) {
|
||||
AssertRegexMatch(t, hmn.BuildForum(nil, 1), RegexForum, nil)
|
||||
AssertRegexMatch(t, hmn.BuildForum([]string{"wip"}, 2), RegexForum, map[string]string{"subforums": "wip", "page": "2"})
|
||||
|
|
|
@ -365,6 +365,26 @@ func BuildPodcastEpisodeFile(filename string) string {
|
|||
return BuildUserFile(fmt.Sprintf("podcast/%s/%s", models.HMNProjectSlug, filename))
|
||||
}
|
||||
|
||||
/*
|
||||
* Fishbowls
|
||||
*/
|
||||
|
||||
var RegexFishbowlIndex = regexp.MustCompile(`^/fishbowl$`)
|
||||
|
||||
func BuildFishbowlIndex() string {
|
||||
defer CatchPanic()
|
||||
return Url("/fishbowl", nil)
|
||||
}
|
||||
|
||||
var RegexFishbowl = regexp.MustCompile(`^/fishbowl/(?P<name>[^/]+)$`)
|
||||
|
||||
func BuildFishbowl(name string) string {
|
||||
defer CatchPanic()
|
||||
return Url(fmt.Sprintf("/fishbowl/%s", name), nil)
|
||||
}
|
||||
|
||||
var RegexFishbowlFiles = regexp.MustCompile(`^/fishbowl/(?P<name>[^/]+)(?P<path>/.+)$`)
|
||||
|
||||
/*
|
||||
* Forums
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "extrahead" }}
|
||||
<link rel="stylesheet" href="{{ static "fonts/whitney/whitney.css" }}">
|
||||
<link rel="stylesheet" href="{{ static "fishbowl.css" }}">
|
||||
|
||||
<script>
|
||||
function scrollToMessage(event, id) {
|
||||
var element = document.getElementById('chatlog__message-container-' + id);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
event.preventDefault();
|
||||
element.classList.add('chatlog__message-container--highlighted');
|
||||
|
||||
window.scrollTo({
|
||||
top: element.getBoundingClientRect().top - document.body.getBoundingClientRect().top - (window.innerHeight / 2),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
|
||||
window.setTimeout(function() {
|
||||
element.classList.remove('chatlog__message-container--highlighted');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
function showSpoiler(event, element) {
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
if (element.classList.contains('chatlog__attachment--hidden')) {
|
||||
event.preventDefault();
|
||||
element.classList.remove('chatlog__attachment--hidden');
|
||||
}
|
||||
|
||||
if (element.classList.contains('chatlog__markdown-spoiler--hidden')) {
|
||||
event.preventDefault();
|
||||
element.classList.remove('chatlog__markdown-spoiler--hidden');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<div class="fishbowl">
|
||||
{{- .Contents -}}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -0,0 +1,7 @@
|
|||
{{ template "base.html" . }}
|
||||
|
||||
{{ define "content" }}
|
||||
<ul>
|
||||
<li><a href="oop">What, if anything, is OOP?</a></li>
|
||||
</ul>
|
||||
{{ end }}
|
|
@ -0,0 +1,5 @@
|
|||
# Folder structure
|
||||
|
||||
One folder per fishbowl. It will look for an index.html file to be dumped directly into the page. All other files / directories are to be served as static files.
|
||||
|
||||
The fishbowl folder name will be used as the URL slug. This is important because the folder name is used for routing to static files.
|
After Width: | Height: | Size: 89 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#31373D" d="M32 5H4C1.791 5 0 6.791 0 9v18c0 2.209 1.791 4 4 4h28c2.209 0 4-1.791 4-4V9c0-2.209-1.791-4-4-4z"/><circle fill="#31373D" cx="15.5" cy="12.5" r="1.5"/><circle fill="#31373D" cx="20.5" cy="12.5" r="1.5"/><ellipse fill="#292F33" cx="18" cy="15.5" rx="1" ry=".5"/><path fill="#E6E7E8" d="M29.021 24.883c-.52-.189-1.093.078-1.282.598L20.923 23l6.816-2.48c.189.52.762.786 1.281.598.52-.19.787-.762.598-1.281-.188-.519-.762-.787-1.281-.599.519-.189.787-.762.598-1.281-.19-.52-.762-.787-1.281-.598-.519.188-.787.763-.598 1.282L18 21.937l-9.056-3.296c.189-.52-.078-1.094-.598-1.282-.52-.19-1.092.078-1.281.598-.189.519.078 1.093.598 1.281-.52-.189-1.093.079-1.281.599-.189.52.078 1.092.598 1.281.52.188 1.092-.078 1.281-.598L15.077 23l-6.815 2.48c-.189-.52-.763-.787-1.282-.598-.519.189-.786.762-.598 1.281.189.519.763.787 1.282.598-.52.19-.787.763-.598 1.282.188.52.763.786 1.281.598.519-.189.787-.763.598-1.282L18 24.065l9.055 3.295c-.19.52.079 1.093.598 1.282.519.188 1.093-.078 1.281-.598.189-.519-.078-1.093-.598-1.282.52.19 1.093-.078 1.282-.598.189-.519-.079-1.093-.597-1.281z"/><path fill="#E6E7E8" d="M18 7c-4 0-6 3.239-6 6 0 1.394.827 2.399 2 3.054V18c0 .553.448 1 1 1s1-.447 1-1v-1.216c.33.072.665.127 1 .162V18c0 .553.448 1 1 1s1-.447 1-1v-1.054c.335-.036.67-.09 1-.162V18c0 .553.447 1 1 1s1-.447 1-1v-1.946c1.173-.654 2-1.659 2-3.054 0-2.761-2-6-6-6zm-2.5 7c-.829 0-1.5 0-1.5-1.5 0-.829.671-1.5 1.5-1.5 1.5 0 1.5.671 1.5 1.5s-.671 1.5-1.5 1.5zm2.5 2c-.552 0-1-.224-1-.5s.448-.5 1-.5 1 .224 1 .5-.448.5-1 .5zm2.5-2c-.828 0-1.5-.671-1.5-1.5s0-1.5 1.5-1.5c.828 0 1.5.671 1.5 1.5 0 1.5-.672 1.5-1.5 1.5z"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFDB5E" d="M34.956 17.916c0-.503-.12-.975-.321-1.404-1.341-4.326-7.619-4.01-16.549-4.221-1.493-.035-.639-1.798-.115-5.668.341-2.517-1.282-6.382-4.01-6.382-4.498 0-.171 3.548-4.148 12.322-2.125 4.688-6.875 2.062-6.875 6.771v10.719c0 1.833.18 3.595 2.758 3.885C8.195 34.219 7.633 36 11.238 36h18.044c1.838 0 3.333-1.496 3.333-3.334 0-.762-.267-1.456-.698-2.018 1.02-.571 1.72-1.649 1.72-2.899 0-.76-.266-1.454-.696-2.015 1.023-.57 1.725-1.649 1.725-2.901 0-.909-.368-1.733-.961-2.336.757-.611 1.251-1.535 1.251-2.581z"/><path fill="#EE9547" d="M23.02 21.249h8.604c1.17 0 2.268-.626 2.866-1.633.246-.415.109-.952-.307-1.199-.415-.247-.952-.108-1.199.307-.283.479-.806.775-1.361.775h-8.81c-.873 0-1.583-.71-1.583-1.583s.71-1.583 1.583-1.583H28.7c.483 0 .875-.392.875-.875s-.392-.875-.875-.875h-5.888c-1.838 0-3.333 1.495-3.333 3.333 0 1.025.475 1.932 1.205 2.544-.615.605-.998 1.445-.998 2.373 0 1.028.478 1.938 1.212 2.549-.611.604-.99 1.441-.99 2.367 0 1.12.559 2.108 1.409 2.713-.524.589-.852 1.356-.852 2.204 0 1.838 1.495 3.333 3.333 3.333h5.484c1.17 0 2.269-.625 2.867-1.632.247-.415.11-.952-.305-1.199-.416-.245-.953-.11-1.199.305-.285.479-.808.776-1.363.776h-5.484c-.873 0-1.583-.71-1.583-1.583s.71-1.583 1.583-1.583h6.506c1.17 0 2.27-.626 2.867-1.633.247-.416.11-.953-.305-1.199-.419-.251-.954-.11-1.199.305-.289.487-.799.777-1.363.777h-7.063c-.873 0-1.583-.711-1.583-1.584s.71-1.583 1.583-1.583h8.091c1.17 0 2.269-.625 2.867-1.632.247-.415.11-.952-.305-1.199-.417-.246-.953-.11-1.199.305-.289.486-.799.776-1.363.776H23.02c-.873 0-1.583-.71-1.583-1.583s.709-1.584 1.583-1.584z"/></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFD983" d="M29 11.06c0 6.439-5 7.439-5 13.44 0 3.098-3.123 3.359-5.5 3.359-2.053 0-6.586-.779-6.586-3.361C11.914 18.5 7 17.5 7 11.06 7 5.029 12.285.14 18.083.14 23.883.14 29 5.029 29 11.06z"/><path fill="#CCD6DD" d="M22.167 32.5c0 .828-2.234 2.5-4.167 2.5-1.933 0-4.167-1.672-4.167-2.5 0-.828 2.233-.5 4.167-.5 1.933 0 4.167-.328 4.167.5z"/><path fill="#FFCC4D" d="M22.707 10.293c-.391-.391-1.023-.391-1.414 0L18 13.586l-3.293-3.293c-.391-.391-1.023-.391-1.414 0s-.391 1.023 0 1.414L17 15.414V26c0 .553.448 1 1 1s1-.447 1-1V15.414l3.707-3.707c.391-.391.391-1.023 0-1.414z"/><path fill="#99AAB5" d="M24 31c0 1.104-.896 2-2 2h-8c-1.104 0-2-.896-2-2v-6h12v6z"/><path fill="#CCD6DD" d="M11.999 32c-.48 0-.904-.347-.985-.836-.091-.544.277-1.06.822-1.15l12-2c.544-.098 1.06.277 1.15.822.091.544-.277 1.06-.822 1.15l-12 2c-.055.01-.111.014-.165.014zm0-4c-.48 0-.904-.347-.985-.836-.091-.544.277-1.06.822-1.15l12-2c.544-.097 1.06.277 1.15.822.091.544-.277 1.06-.822 1.15l-12 2c-.055.01-.111.014-.165.014z"/></svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#BB1A34" d="M22 0l-4 8.028-5-5.018v7.024L3 8.028l8 8.028-11 6.02h12L6 34.118l12-8.028 11 10.035-3-14.049h10l-8-6.021 8-9.031-12 3.01L22 0z"/><path fill="#FCAB40" d="M22.914 12.924l1.86-.467L30 11.146l-3.381 3.816-1.319 1.49 1.59 1.195 2.925 2.202h-5.918l.473 2.218 1.551 7.26-5.845-5.332-1.056-.964-1.188.795-5.24 3.506 2.406-4.828 1.322-2.655H9.564l3.759-2.059 2.145-1.172-1.727-1.735-3.044-3.053 3.221.646 2.186.439V8.686l1.45 1.455 1.794 1.799 1.133-2.276 1.273-2.556"/><path fill="#F5F8FA" d="M21.512 14.301l.767-.193 2.158-.541-1.396 1.576-.545.615.656.493 1.208.909h-2.443l.195.916.641 2.997-2.413-2.201-.437-.398-.49.328-2.163 1.448.993-1.994.546-1.096H16l1.553-.85.885-.484-.713-.716-1.257-1.261 1.329.267.903.181v-1.745l.599.6.74.743.468-.939.525-1.056"/></svg>
|
After Width: | Height: | Size: 842 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#BB1A34" d="M1.728 21c-.617 0-.953-.256-1.127-.471-.171-.211-.348-.585-.225-1.165L3.104 6.658l-1.714.097h-.013c-.517 0-.892-.168-1.127-.459-.22-.272-.299-.621-.221-.98.15-.702.883-1.286 1.667-1.329l4.008-.227c.078-.005.15-.008.217-.008.147 0 .536 0 .783.306.252.312.167.709.139.839L3.719 19.454c-.187.884-.919 1.489-1.866 1.542L1.728 21zm10.743-2c-1.439 0-2.635-.539-3.459-1.559-1.163-1.439-1.467-3.651-.878-6.397 1.032-4.812 4.208-8.186 7.902-8.395 1.59-.089 2.906.452 3.793 1.549 1.163 1.439 1.467 3.651.878 6.397-1.032 4.81-4.208 8.184-7.904 8.394-.112.008-.223.011-.332.011zm3.414-13.746l-.137.004c-1.94.111-3.555 2.304-4.32 5.866-.478 2.228-.381 3.899.272 4.707.297.368.717.555 1.249.555l.14-.004c1.94-.109 3.554-2.301 4.318-5.864.478-2.228.382-3.9-.27-4.708-.296-.369-.718-.556-1.252-.556zm11.591 12.107c-1.439 0-2.637-.539-3.462-1.56-1.163-1.439-1.467-3.651-.878-6.397 1.033-4.813 4.209-8.186 7.903-8.394 1.603-.09 2.903.453 3.79 1.549 1.163 1.439 1.467 3.651.878 6.396-1.031 4.809-4.206 8.183-7.902 8.396-.112.008-.221.01-.329.01zm3.411-13.747l-.136.004c-1.941.111-3.556 2.304-4.32 5.865-.478 2.229-.381 3.901.272 4.708.297.368.719.555 1.251.555l.14-.004c1.939-.109 3.554-2.302 4.318-5.864.479-2.227.383-3.899-.27-4.707-.298-.37-.72-.557-1.255-.557zM11 35.001c-.81 0-1.572-.496-1.873-1.299-.388-1.034.136-2.187 1.17-2.575.337-.126 8.399-3.108 20.536-4.12 1.101-.096 2.067.727 2.159 1.827.092 1.101-.727 2.067-1.827 2.159-11.59.966-19.386 3.851-19.464 3.88-.23.086-.468.128-.701.128zM2.001 29c-.804 0-1.563-.488-1.868-1.283-.396-1.031.118-2.188 1.149-2.583.542-.209 13.516-5.126 32.612-6.131 1.113-.069 2.045.789 2.103 1.892.059 1.103-.789 2.045-1.892 2.103-18.423.97-31.261 5.821-31.389 5.87-.235.089-.477.132-.715.132z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#66757F" d="M4 5s0-1 1-1h6s1 0 1 1v2H4V5z"/><path fill="#31373D" d="M0 10s0-4 4-4h28s4 0 4 4v18s0 4-4 4H4s-4 0-4-4V10z"/><circle fill="#CCD6DD" cx="21" cy="19" r="10"/><circle fill="#31373D" cx="21" cy="19" r="8"/><circle fill="#3B88C3" cx="21" cy="19" r="5"/><circle fill="#FFF" cx="32.5" cy="9.5" r="1.5"/><path fill="#F5F8FA" d="M12 9.5c0 .829-.671 1.5-1.5 1.5h-5C4.671 11 4 10.329 4 9.5S4.671 8 5.5 8h5c.829 0 1.5.671 1.5 1.5z"/></svg>
|
After Width: | Height: | Size: 511 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#9AAAB4" d="M23.378 19.029C22.67 19.736 16.305 31.757.75 36c1.414-1.415 19.54-21.691 19.54-21.691l3.088 4.72z"/><path fill="#CCD6DD" d="M17.72 13.371C17.013 14.078 4.992 20.444.75 36l21.213-21.214-4.243-1.415z"/><path fill="#D99E82" d="M20.549 11.957c-.781.781-.655 2.174.283 3.112l.848.849c.938.937 2.33 1.063 3.112.282l7.778-7.778c.781-.781.654-2.174-.283-3.111l-.848-.848c-.938-.938-2.331-1.064-3.111-.283l-7.779 7.777z"/><path d="M28.892 12.1l-7.071-1.414-1.271 1.271c-.133.133-.23.288-.311.452l6.954 1.391 1.699-1.7zm-7.212 3.818c.938.938 2.331 1.063 3.112.282l.826-.826-5.328-1.065c.131.27.312.529.543.76l.847.849zm8.911-5.518l1.7-1.699-7.071-1.414-1.7 1.699zm2.423-3.793c-.107-.46-.346-.916-.727-1.297l-.848-.848c-.103-.103-.213-.192-.325-.275l-2.11-.422c-.252.084-.483.22-.676.414l-1.242 1.242 5.928 1.186z" fill="#BF6952"/><circle fill="#8A4633" cx="31.858" cy="4.896" r="4"/><path fill="#FFAC33" d="M16.306 9.836c.586-.586 1.536-.586 2.121 0l8.839 8.839c.586.586.586 1.536 0 2.121-.586.586-1.535.586-2.121 0l-8.839-8.839c-.586-.584-.586-1.535 0-2.121z"/><circle fill="#FFAC33" cx="27.266" cy="20.796" r="2.5"/><circle fill="#FFAC33" cx="16.306" cy="9.836" r="2.5"/><circle fill="#FFCC4D" cx="27.266" cy="20.796" r="1.5"/><circle fill="#FFCC4D" cx="16.306" cy="9.836" r="1.5"/><path fill="#FFAC33" d="M26.566 3.803c.417-.417 1.093-.417 1.509 0l4.865 4.866c.417.417.417 1.092 0 1.509-.417.417-1.092.417-1.509 0l-4.865-4.866c-.417-.416-.417-1.092 0-1.509z"/></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M36 18c0 9.941-8.059 18-18 18-9.94 0-18-8.059-18-18C0 8.06 8.06 0 18 0c9.941 0 18 8.06 18 18"/><path fill="#664500" d="M28.457 17.797c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.145.591.175.142.426.147.61.014.012-.009 1.262-.902 3.702-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.177-.142.238-.386.145-.594zm-12 0c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.144.591.176.142.427.147.61.014.013-.009 1.262-.902 3.703-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.178-.142.237-.386.145-.594zM31 16c-.396 0-.772-.238-.929-.629-1.778-4.445-6.223-5.381-6.268-5.391-.541-.108-.893-.635-.784-1.177.108-.542.635-.891 1.177-.784.226.045 5.556 1.168 7.732 6.608.205.513-.045 1.095-.558 1.3-.12.05-.246.073-.37.073zM5 16c-.124 0-.249-.023-.371-.072-.513-.205-.762-.787-.557-1.3 2.176-5.44 7.506-6.563 7.732-6.608.543-.106 1.068.243 1.177.784.108.54-.242 1.066-.781 1.176-.185.038-4.506.98-6.271 5.391-.157.391-.533.629-.929.629zm13 6c-3.623 0-6.027-.422-9-1-.679-.131-2 0-2 2 0 4 4.595 9 11 9 6.404 0 11-5 11-9 0-2-1.321-2.132-2-2-2.973.578-5.377 1-9 1z"/><path fill="#FFF" d="M9 23s3 1 9 1 9-1 9-1-2 4-9 4-9-4-9-4z"/><path fill="#5DADEC" d="M10.847 28.229c-.68 2.677-3.4 4.295-6.077 3.615-2.676-.679-4.295-3.399-3.616-6.076.679-2.677 6.337-8.708 7.307-8.462.97.247 3.065 8.247 2.386 10.923zm14.286 0c.68 2.677 3.4 4.295 6.077 3.615 2.677-.679 4.296-3.399 3.616-6.076-.68-2.677-6.338-8.708-7.308-8.462-.968.247-3.064 8.247-2.385 10.923z"/></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M36 18c0 9.941-8.059 18-18 18-9.94 0-18-8.059-18-18C0 8.06 8.06 0 18 0c9.941 0 18 8.06 18 18"/><path fill="#664500" d="M28.457 17.797c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.145.591.175.142.426.147.61.014.012-.009 1.262-.902 3.702-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.177-.142.238-.386.145-.594zm-12 0c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.144.591.176.142.427.147.61.014.013-.009 1.262-.902 3.703-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.178-.142.237-.386.145-.594zM18 22c-3.623 0-6.027-.422-9-1-.679-.131-2 0-2 2 0 4 4.595 9 11 9 6.404 0 11-5 11-9 0-2-1.321-2.132-2-2-2.973.578-5.377 1-9 1z"/><path fill="#FFF" d="M9 23s3 1 9 1 9-1 9-1-2 4-9 4-9-4-9-4z"/></svg>
|
After Width: | Height: | Size: 920 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#FFCB4C" cx="18" cy="17.018" r="17"/><path fill="#65471B" d="M14.524 21.036c-.145-.116-.258-.274-.312-.464-.134-.46.13-.918.59-1.021 4.528-1.021 7.577 1.363 7.706 1.465.384.306.459.845.173 1.205-.286.358-.828.401-1.211.097-.11-.084-2.523-1.923-6.182-1.098-.274.061-.554-.016-.764-.184z"/><ellipse fill="#65471B" cx="13.119" cy="11.174" rx="2.125" ry="2.656"/><ellipse fill="#65471B" cx="24.375" cy="12.236" rx="2.125" ry="2.656"/><path fill="#F19020" d="M17.276 35.149s1.265-.411 1.429-1.352c.173-.972-.624-1.167-.624-1.167s1.041-.208 1.172-1.376c.123-1.101-.861-1.363-.861-1.363s.97-.4 1.016-1.539c.038-.959-.995-1.428-.995-1.428s5.038-1.221 5.556-1.341c.516-.12 1.32-.615 1.069-1.694-.249-1.08-1.204-1.118-1.697-1.003-.494.115-6.744 1.566-8.9 2.068l-1.439.334c-.54.127-.785-.11-.404-.512.508-.536.833-1.129.946-2.113.119-1.035-.232-2.313-.433-2.809-.374-.921-1.005-1.649-1.734-1.899-1.137-.39-1.945.321-1.542 1.561.604 1.854.208 3.375-.833 4.293-2.449 2.157-3.588 3.695-2.83 6.973.828 3.575 4.377 5.876 7.952 5.048l3.152-.681z"/><path fill="#65471B" d="M9.296 6.351c-.164-.088-.303-.224-.391-.399-.216-.428-.04-.927.393-1.112 4.266-1.831 7.699-.043 7.843.034.433.231.608.747.391 1.154-.216.405-.74.546-1.173.318-.123-.063-2.832-1.432-6.278.047-.257.109-.547.085-.785-.042zm12.135 3.75c-.156-.098-.286-.243-.362-.424-.187-.442.023-.927.468-1.084 4.381-1.536 7.685.48 7.823.567.415.26.555.787.312 1.178-.242.39-.776.495-1.191.238-.12-.072-2.727-1.621-6.267-.379-.266.091-.553.046-.783-.096z"/></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#EF9645" d="M26.992 19.016c-.255-.255-.799-.611-1.44-.962l-1.911-2-2.113 2h-.58l-2.509-3.634c-1.379.01-2.497 1.136-2.487 2.515l-3.556-2.112c-.817.364-1.389 1.18-1.389 2.133v.96l-4 4.168.016 2.185 9.984 10.729S27.525 19.71 27.55 19.74c-.129-.223-.513-.702-.558-.724z"/><g fill="#FFDC5D"><path d="M25.552 5.81c0-1.107-.906-2.013-2.013-2.013-1.107 0-2.013.906-2.013 2.013v12.245h4.025V5.81zm-4.605 12.244V16.01c-.008-1.103-.909-1.991-2.012-1.983-1.103.008-1.991.909-1.983 2.012l.012 2.016h3.983zM8.916 16h.168c1.059 0 1.916.858 1.916 1.917v4.166C11 23.142 10.143 24 9.084 24h-.168C7.857 24 7 23.142 7 22.083v-4.166C7 16.858 7.857 16 8.916 16zm6.918 2.96l-.056.062C15.304 19.551 15 20.233 15 21c0 .063.013.123.018.185.044.678.308 1.292.728 1.774-.071.129-.163.243-.259.353-.366.417-.89.688-1.487.688-1.104 0-2-.896-2-2v-6c0-.441.147-.845.389-1.176.364-.497.947-.824 1.611-.824 1.104 0 2 .896 2 2v2.778c-.061.055-.109.123-.166.182z"/><path d="M9.062 25c1.024 0 1.925-.526 2.45-1.322.123.183.271.346.431.497 1.185 1.115 3.034 1.044 4.167-.086.152-.152.303-.305.419-.488l-.003-.003C16.727 23.713 17 24 18 24h2.537c-.37.279-.708.623-1.024 1-1.228 1.467-2.013 3.606-2.013 6 0 .276.224.5.5.5s.5-.224.5-.5c0-2.548.956-4.775 2.377-6 .732-.631 1.584-1 2.498-1 .713.079.847-1 .125-1H18c-1.104 0-2-.896-2-2s.896-2 2-2h8c.858 0 1.66.596 1.913 1.415L29 24c.103.335.479 1.871.411 2.191C29.411 31 24.715 36 19 36c-6.537 0-11.844-5.231-11.986-11.734l.014.01c.515.445 1.176.724 1.91.724h.124z"/></g></svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#31373D" cx="18" cy="18" r="18"/></svg>
|
After Width: | Height: | Size: 113 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#BE1931" cx="18" cy="32" r="3"/><path fill="#BE1931" d="M21 24c0 1.657-1.344 3-3 3-1.657 0-3-1.343-3-3V5c0-1.657 1.343-3 3-3 1.656 0 3 1.343 3 3v19z"/></svg>
|
After Width: | Height: | Size: 231 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#DD2E44" d="M35.885 11.833c0-5.45-4.418-9.868-9.867-9.868-3.308 0-6.227 1.633-8.018 4.129-1.791-2.496-4.71-4.129-8.017-4.129-5.45 0-9.868 4.417-9.868 9.868 0 .772.098 1.52.266 2.241C1.751 22.587 11.216 31.568 18 34.034c6.783-2.466 16.249-11.447 17.617-19.959.17-.721.268-1.469.268-2.242z"/></svg>
|
After Width: | Height: | Size: 368 B |
After Width: | Height: | Size: 415 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 194 KiB |
After Width: | Height: | Size: 465 KiB |
|
@ -0,0 +1 @@
|
|||
.hljs{display:block;overflow-x:auto;padding:.5em;background:#002b36;color:#839496}.hljs-comment,.hljs-quote{color:#586e75}.hljs-keyword,.hljs-selector-tag,.hljs-addition{color:#859900}.hljs-number,.hljs-string,.hljs-meta .hljs-meta-string,.hljs-literal,.hljs-doctag,.hljs-regexp{color:#2aa198}.hljs-title,.hljs-section,.hljs-name,.hljs-selector-id,.hljs-selector-class{color:#268bd2}.hljs-attribute,.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-class .hljs-title,.hljs-type{color:#b58900}.hljs-symbol,.hljs-bullet,.hljs-subst,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-link{color:#cb4b16}.hljs-built_in,.hljs-deletion{color:#dc322f}.hljs-formula{background:#073642}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFDB5E" d="M34.956 17.916c0-.503-.12-.975-.321-1.404-1.341-4.326-7.619-4.01-16.549-4.221-1.493-.035-.639-1.798-.115-5.668.341-2.517-1.282-6.382-4.01-6.382-4.498 0-.171 3.548-4.148 12.322-2.125 4.688-6.875 2.062-6.875 6.771v10.719c0 1.833.18 3.595 2.758 3.885C8.195 34.219 7.633 36 11.238 36h18.044c1.838 0 3.333-1.496 3.333-3.334 0-.762-.267-1.456-.698-2.018 1.02-.571 1.72-1.649 1.72-2.899 0-.76-.266-1.454-.696-2.015 1.023-.57 1.725-1.649 1.725-2.901 0-.909-.368-1.733-.961-2.336.757-.611 1.251-1.535 1.251-2.581z"/><path fill="#EE9547" d="M23.02 21.249h8.604c1.17 0 2.268-.626 2.866-1.633.246-.415.109-.952-.307-1.199-.415-.247-.952-.108-1.199.307-.283.479-.806.775-1.361.775h-8.81c-.873 0-1.583-.71-1.583-1.583s.71-1.583 1.583-1.583H28.7c.483 0 .875-.392.875-.875s-.392-.875-.875-.875h-5.888c-1.838 0-3.333 1.495-3.333 3.333 0 1.025.475 1.932 1.205 2.544-.615.605-.998 1.445-.998 2.373 0 1.028.478 1.938 1.212 2.549-.611.604-.99 1.441-.99 2.367 0 1.12.559 2.108 1.409 2.713-.524.589-.852 1.356-.852 2.204 0 1.838 1.495 3.333 3.333 3.333h5.484c1.17 0 2.269-.625 2.867-1.632.247-.415.11-.952-.305-1.199-.416-.245-.953-.11-1.199.305-.285.479-.808.776-1.363.776h-5.484c-.873 0-1.583-.71-1.583-1.583s.71-1.583 1.583-1.583h6.506c1.17 0 2.27-.626 2.867-1.633.247-.416.11-.953-.305-1.199-.419-.251-.954-.11-1.199.305-.289.487-.799.777-1.363.777h-7.063c-.873 0-1.583-.711-1.583-1.584s.71-1.583 1.583-1.583h8.091c1.17 0 2.269-.625 2.867-1.632.247-.415.11-.952-.305-1.199-.417-.246-.953-.11-1.199.305-.289.486-.799.776-1.363.776H23.02c-.873 0-1.583-.71-1.583-1.583s.709-1.584 1.583-1.584z"/></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#BB1A34" d="M1.728 21c-.617 0-.953-.256-1.127-.471-.171-.211-.348-.585-.225-1.165L3.104 6.658l-1.714.097h-.013c-.517 0-.892-.168-1.127-.459-.22-.272-.299-.621-.221-.98.15-.702.883-1.286 1.667-1.329l4.008-.227c.078-.005.15-.008.217-.008.147 0 .536 0 .783.306.252.312.167.709.139.839L3.719 19.454c-.187.884-.919 1.489-1.866 1.542L1.728 21zm10.743-2c-1.439 0-2.635-.539-3.459-1.559-1.163-1.439-1.467-3.651-.878-6.397 1.032-4.812 4.208-8.186 7.902-8.395 1.59-.089 2.906.452 3.793 1.549 1.163 1.439 1.467 3.651.878 6.397-1.032 4.81-4.208 8.184-7.904 8.394-.112.008-.223.011-.332.011zm3.414-13.746l-.137.004c-1.94.111-3.555 2.304-4.32 5.866-.478 2.228-.381 3.899.272 4.707.297.368.717.555 1.249.555l.14-.004c1.94-.109 3.554-2.301 4.318-5.864.478-2.228.382-3.9-.27-4.708-.296-.369-.718-.556-1.252-.556zm11.591 12.107c-1.439 0-2.637-.539-3.462-1.56-1.163-1.439-1.467-3.651-.878-6.397 1.033-4.813 4.209-8.186 7.903-8.394 1.603-.09 2.903.453 3.79 1.549 1.163 1.439 1.467 3.651.878 6.396-1.031 4.809-4.206 8.183-7.902 8.396-.112.008-.221.01-.329.01zm3.411-13.747l-.136.004c-1.941.111-3.556 2.304-4.32 5.865-.478 2.229-.381 3.901.272 4.708.297.368.719.555 1.251.555l.14-.004c1.939-.109 3.554-2.302 4.318-5.864.479-2.227.383-3.899-.27-4.707-.298-.37-.72-.557-1.255-.557zM11 35.001c-.81 0-1.572-.496-1.873-1.299-.388-1.034.136-2.187 1.17-2.575.337-.126 8.399-3.108 20.536-4.12 1.101-.096 2.067.727 2.159 1.827.092 1.101-.727 2.067-1.827 2.159-11.59.966-19.386 3.851-19.464 3.88-.23.086-.468.128-.701.128zM2.001 29c-.804 0-1.563-.488-1.868-1.283-.396-1.031.118-2.188 1.149-2.583.542-.209 13.516-5.126 32.612-6.131 1.113-.069 2.045.789 2.103 1.892.059 1.103-.789 2.045-1.892 2.103-18.423.97-31.261 5.821-31.389 5.87-.235.089-.477.132-.715.132z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M36 18c0 9.941-8.059 18-18 18-9.94 0-18-8.059-18-18C0 8.06 8.06 0 18 0c9.941 0 18 8.06 18 18"/><path fill="#664500" d="M28.457 17.797c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.145.591.175.142.426.147.61.014.012-.009 1.262-.902 3.702-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.177-.142.238-.386.145-.594zm-12 0c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.144.591.176.142.427.147.61.014.013-.009 1.262-.902 3.703-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.178-.142.237-.386.145-.594zM18 22c-3.623 0-6.027-.422-9-1-.679-.131-2 0-2 2 0 4 4.595 9 11 9 6.404 0 11-5 11-9 0-2-1.321-2.132-2-2-2.973.578-5.377 1-9 1z"/><path fill="#FFF" d="M9 23s3 1 9 1 9-1 9-1-2 4-9 4-9-4-9-4z"/></svg>
|
After Width: | Height: | Size: 920 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M36 18c0 9.941-8.059 18-18 18-9.94 0-18-8.059-18-18C0 8.06 8.06 0 18 0c9.941 0 18 8.06 18 18"/><path fill="#664500" d="M28.457 17.797c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.145.591.175.142.426.147.61.014.012-.009 1.262-.902 3.702-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.177-.142.238-.386.145-.594zm-12 0c-.06-.135-1.499-3.297-4.457-3.297-2.957 0-4.397 3.162-4.457 3.297-.092.207-.032.449.144.591.176.142.427.147.61.014.013-.009 1.262-.902 3.703-.902 2.426 0 3.674.881 3.702.901.088.066.194.099.298.099.11 0 .221-.037.312-.109.178-.142.237-.386.145-.594zM18 22c-3.623 0-6.027-.422-9-1-.679-.131-2 0-2 2 0 4 4.595 9 11 9 6.404 0 11-5 11-9 0-2-1.321-2.132-2-2-2.973.578-5.377 1-9 1z"/><path fill="#FFF" d="M9 23s3 1 9 1 9-1 9-1-2 4-9 4-9-4-9-4z"/><path fill="#5DADEC" d="M35 11c0 2.762-2.238 5-5 5s-5-2.238-5-5 4-10 5-10 5 7.238 5 10z"/></svg>
|
After Width: | Height: | Size: 1010 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#AA8DD8" cx="18" cy="18" r="18"/><path fill="#AA8DD8" d="M10 4C7.42 4 4.369 1.534 3.414.586 2.843.014 1.981-.157 1.235.153.487.462 0 1.191 0 2c0 3.459 1.672 10 8 10 .757 0 1.45-.428 1.789-1.106l2-4c.31-.62.277-1.356-.088-1.946C11.337 4.359 10.693 4 10 4zM34.766.153c-.75-.311-1.607-.139-2.18.434C31.7 1.472 28.589 4 26 4c-.693 0-1.337.359-1.701.949-.364.589-.397 1.326-.088 1.946l2 4C26.55 11.572 27.242 12 28 12c6.328 0 8-6.541 8-10 0-.809-.487-1.538-1.234-1.847z"/><path fill="#553986" d="M27.335 25.629c-.178-.161-.444-.171-.635-.029-.039.029-3.922 2.9-8.7 2.9-4.766 0-8.662-2.871-8.7-2.9-.191-.142-.457-.13-.635.029-.177.16-.217.424-.094.628C8.7 26.472 11.788 31.5 18 31.5s9.301-5.028 9.429-5.243c.123-.205.084-.468-.094-.628zm-11.628-7.336C12.452 15.038 7.221 15 7 15c-.552 0-.999.447-.999.998-.001.552.446 1.001.998 1.002.029 0 1.925.022 3.983.737-.593.64-.982 1.634-.982 2.763 0 1.934 1.119 3.5 2.5 3.5s2.5-1.566 2.5-3.5c0-.174-.019-.34-.037-.507.013 0 .025.007.037.007.256 0 .512-.098.707-.293.391-.391.391-1.023 0-1.414zM29 15c-.221 0-5.451.038-8.707 3.293-.391.391-.391 1.023 0 1.414.195.195.451.293.707.293.013 0 .024-.007.036-.007-.016.167-.036.333-.036.507 0 1.934 1.119 3.5 2.5 3.5s2.5-1.566 2.5-3.5c0-1.129-.389-2.123-.982-2.763 2.058-.715 3.954-.737 3.984-.737.551-.001.998-.45.997-1.002-.001-.551-.447-.998-.999-.998z"/></svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M36 18c0 9.941-8.059 18-18 18-9.94 0-18-8.059-18-18C0 8.06 8.06 0 18 0c9.941 0 18 8.06 18 18"/><ellipse fill="#66471B" cx="11.5" cy="14.5" rx="2.5" ry="3.5"/><ellipse fill="#66471B" cx="24.5" cy="14.5" rx="2.5" ry="3.5"/><path fill="#66471B" d="M7 21.262c0 3.964 4.596 9 11 9s11-5 11-9c0 0-10.333 2.756-22 0z"/><path fill="#E8596E" d="M18.545 23.604l-1.091-.005c-3.216-.074-5.454-.596-5.454-.596v6.961c0 3 2 6 6 6s6-3 6-6v-6.92c-1.922.394-3.787.542-5.455.56z"/><path fill="#DD2F45" d="M18 31.843c.301 0 .545-.244.545-.545v-7.694l-1.091-.005v7.699c.001.301.245.545.546.545z"/></svg>
|
After Width: | Height: | Size: 665 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#FFCC4D" cx="18" cy="18" r="18"/><path fill="#664500" d="M10.515 23.621C10.56 23.8 11.683 28 18 28c6.318 0 7.44-4.2 7.485-4.379.055-.217-.043-.442-.237-.554-.195-.111-.439-.078-.6.077C24.629 23.163 22.694 25 18 25s-6.63-1.837-6.648-1.855C11.256 23.05 11.128 23 11 23c-.084 0-.169.021-.246.064-.196.112-.294.339-.239.557z"/><ellipse fill="#664500" cx="12" cy="13.5" rx="2.5" ry="3.5"/><ellipse fill="#664500" cx="24" cy="13.5" rx="2.5" ry="3.5"/></svg>
|
After Width: | Height: | Size: 525 B |
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#FFCB4C" cx="18" cy="17.018" r="17"/><path fill="#65471B" d="M14.524 21.036c-.145-.116-.258-.274-.312-.464-.134-.46.13-.918.59-1.021 4.528-1.021 7.577 1.363 7.706 1.465.384.306.459.845.173 1.205-.286.358-.828.401-1.211.097-.11-.084-2.523-1.923-6.182-1.098-.274.061-.554-.016-.764-.184z"/><ellipse fill="#65471B" cx="13.119" cy="11.174" rx="2.125" ry="2.656"/><ellipse fill="#65471B" cx="24.375" cy="12.236" rx="2.125" ry="2.656"/><path fill="#F19020" d="M17.276 35.149s1.265-.411 1.429-1.352c.173-.972-.624-1.167-.624-1.167s1.041-.208 1.172-1.376c.123-1.101-.861-1.363-.861-1.363s.97-.4 1.016-1.539c.038-.959-.995-1.428-.995-1.428s5.038-1.221 5.556-1.341c.516-.12 1.32-.615 1.069-1.694-.249-1.08-1.204-1.118-1.697-1.003-.494.115-6.744 1.566-8.9 2.068l-1.439.334c-.54.127-.785-.11-.404-.512.508-.536.833-1.129.946-2.113.119-1.035-.232-2.313-.433-2.809-.374-.921-1.005-1.649-1.734-1.899-1.137-.39-1.945.321-1.542 1.561.604 1.854.208 3.375-.833 4.293-2.449 2.157-3.588 3.695-2.83 6.973.828 3.575 4.377 5.876 7.952 5.048l3.152-.681z"/><path fill="#65471B" d="M9.296 6.351c-.164-.088-.303-.224-.391-.399-.216-.428-.04-.927.393-1.112 4.266-1.831 7.699-.043 7.843.034.433.231.608.747.391 1.154-.216.405-.74.546-1.173.318-.123-.063-2.832-1.432-6.278.047-.257.109-.547.085-.785-.042zm12.135 3.75c-.156-.098-.286-.243-.362-.424-.187-.442.023-.927.468-1.084 4.381-1.536 7.685.48 7.823.567.415.26.555.787.312 1.178-.242.39-.776.495-1.191.238-.12-.072-2.727-1.621-6.267-.379-.266.091-.553.046-.783-.096z"/></svg>
|
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 100 B |
|
@ -73,6 +73,7 @@
|
|||
<a>Media <div class="dib svgicon ml1">{{ svg "chevron-down-thick" }}</div></a>
|
||||
<div class="submenu b--theme-dark">
|
||||
<a href="{{ .Header.PodcastUrl }}">Podcast</a>
|
||||
<a href="{{ .Header.FishbowlUrl }}">Fishbowls</a>
|
||||
<a href="https://handmadedev.show/" target="_blank">Handmade Dev Show</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"git.handmade.network/hmn/hmn/src/auth"
|
||||
"git.handmade.network/hmn/hmn/src/hmnurl"
|
||||
"git.handmade.network/hmn/hmn/src/logging"
|
||||
"git.handmade.network/hmn/hmn/src/utils"
|
||||
"github.com/Masterminds/sprig"
|
||||
"github.com/google/uuid"
|
||||
"github.com/teacat/noire"
|
||||
|
@ -26,10 +27,13 @@ const (
|
|||
var templateFs embed.FS
|
||||
var Templates map[string]*template.Template
|
||||
|
||||
//go:embed src/fishbowls
|
||||
var FishbowlFS embed.FS
|
||||
|
||||
func Init() {
|
||||
Templates = make(map[string]*template.Template)
|
||||
|
||||
files, _ := templateFs.ReadDir("src")
|
||||
files := utils.Must1(templateFs.ReadDir("src"))
|
||||
for _, f := range files {
|
||||
if hasSuffix(f.Name(), ".html") {
|
||||
t := template.New(f.Name())
|
||||
|
|
|
@ -49,6 +49,7 @@ type Header struct {
|
|||
HMNHomepageUrl string
|
||||
ProjectIndexUrl string
|
||||
PodcastUrl string
|
||||
FishbowlUrl string
|
||||
ForumsUrl string
|
||||
LibraryUrl string
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ func getBaseData(c *RequestContext, title string, breadcrumbs []templates.Breadc
|
|||
HMNHomepageUrl: hmnurl.BuildHomepage(),
|
||||
ProjectIndexUrl: hmnurl.BuildProjectIndex(1),
|
||||
PodcastUrl: hmnurl.BuildPodcast(),
|
||||
FishbowlUrl: hmnurl.BuildFishbowlIndex(),
|
||||
ForumsUrl: hmnurl.HMNProjectContext.BuildForum(nil, 1),
|
||||
LibraryUrl: hmnurl.BuildLibrary(),
|
||||
},
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package website
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"git.handmade.network/hmn/hmn/src/oops"
|
||||
"git.handmade.network/hmn/hmn/src/templates"
|
||||
"git.handmade.network/hmn/hmn/src/utils"
|
||||
)
|
||||
|
||||
func FishbowlIndex(c *RequestContext) ResponseData {
|
||||
var res ResponseData
|
||||
err := res.WriteTemplate("fishbowl_index.html", getBaseData(c, "Fishbowls", nil), c.Perf)
|
||||
if err != nil {
|
||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render fishbowl index page"))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Fishbowl(c *RequestContext) ResponseData {
|
||||
// Only serve up valid fishbowls
|
||||
if _, err := fs.Stat(fishbowlFS, c.PathParams["name"]); errors.Is(err, fs.ErrNotExist) {
|
||||
return FourOhFour(c)
|
||||
}
|
||||
|
||||
// Ensure trailing slash (it matters for relative URLs in the HTML)
|
||||
if !strings.HasSuffix(c.URL().Path, "/") {
|
||||
return c.Redirect(c.URL().Path+"/", http.StatusFound)
|
||||
}
|
||||
|
||||
type FishbowlData struct {
|
||||
templates.BaseData
|
||||
Contents template.HTML
|
||||
}
|
||||
|
||||
indexFile := utils.Must1(fishbowlFS.Open(path.Join(c.PathParams["name"], "index.html")))
|
||||
|
||||
tmpl := FishbowlData{
|
||||
BaseData: getBaseData(c, "TODOOP", nil),
|
||||
Contents: template.HTML(utils.Must1(io.ReadAll(indexFile))),
|
||||
}
|
||||
|
||||
var res ResponseData
|
||||
err := res.WriteTemplate("fishbowl.html", tmpl, c.Perf)
|
||||
if err != nil {
|
||||
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to render fishbowl index page"))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// This will skip the common path prefix for fishbowl files.
|
||||
// We unfortunately need to do this because we want to use http.FileServer,
|
||||
// but _that_ needs an http.FS, but _that_ needs an fs.FS, and embed.FS
|
||||
// doesn't import fs.SubFS, which _would_ do what we want, so here we are. >:(
|
||||
var fishbowlFS = utils.Must1(fs.Sub(templates.FishbowlFS, "src/fishbowls"))
|
||||
var fishbowlHTTPFS = http.StripPrefix("/fishbowl", http.FileServer(http.FS(fishbowlFS)))
|
||||
|
||||
func FishbowlFiles(c *RequestContext) ResponseData {
|
||||
var res ResponseData
|
||||
fishbowlHTTPFS.ServeHTTP(&res, c.Req)
|
||||
AddCORSHeaders(c, &res)
|
||||
return res
|
||||
}
|
|
@ -222,6 +222,10 @@ func NewWebsiteRoutes(longRequestContext context.Context, conn *pgxpool.Pool) ht
|
|||
hmnOnly.GET(hmnurl.RegexPodcastEpisode, PodcastEpisode)
|
||||
hmnOnly.GET(hmnurl.RegexPodcastRSS, PodcastRSS)
|
||||
|
||||
hmnOnly.GET(hmnurl.RegexFishbowlIndex, FishbowlIndex)
|
||||
hmnOnly.GET(hmnurl.RegexFishbowl, Fishbowl)
|
||||
hmnOnly.GET(hmnurl.RegexFishbowlFiles, FishbowlFiles)
|
||||
|
||||
hmnOnly.POST(hmnurl.RegexAPICheckUsername, csrfMiddleware(APICheckUsername))
|
||||
|
||||
hmnOnly.GET(hmnurl.RegexLibraryAny, LibraryNotPortedYet)
|
||||
|
|
You can verify that you got the slug.