Add Fishbowl archive (#41)

Refs #33

Co-authored-by: Ben Visness <bvisness@gmail.com>
Co-authored-by: ilidemi <belk94@gmail.com>
Reviewed-on: #41
pull/43/head
bvisness 4 months ago
parent 1cfb9e4033
commit d1e63f745b
  1. 1
      .gitignore
  2. 618
      public/fishbowl-dark.css
  3. 619
      public/fishbowl-light.css
  4. 7
      public/waterline.svg
  5. 10
      src/ansicolor/ansicolor.go
  6. 15
      src/hmndata/user_helper.go
  7. 9
      src/hmnurl/hmnurl_test.go
  8. 20
      src/hmnurl/urls.go
  9. 1
      src/models/user.go
  10. 89
      src/templates/src/fishbowl.html
  11. 33
      src/templates/src/fishbowl_index.html
  12. 1
      src/templates/src/fishbowls/README.md
  13. 12127
      src/templates/src/fishbowls/oop/OOP.html
  14. BIN
      src/templates/src/fishbowls/oop/files/1963eacbf364164efce1c597dc66aeab-E6901.png
  15. 1
      src/templates/src/fishbowls/oop/files/1f3f4-200d-2620-6E400.svg
  16. 1
      src/templates/src/fishbowls/oop/files/1f44d-B3F5F.svg
  17. 1
      src/templates/src/fishbowls/oop/files/1f4a1-26401.svg
  18. 1
      src/templates/src/fishbowls/oop/files/1f4a5-61C11.svg
  19. 1
      src/templates/src/fishbowls/oop/files/1f4af-2188D.svg
  20. 1
      src/templates/src/fishbowls/oop/files/1f4f7-B9213.svg
  21. 1
      src/templates/src/fishbowls/oop/files/1f5e1-9D0D3.svg
  22. 1
      src/templates/src/fishbowls/oop/files/1f602-20224.svg
  23. 1
      src/templates/src/fishbowls/oop/files/1f604-6061B.svg
  24. 1
      src/templates/src/fishbowls/oop/files/1f914-54FF1.svg
  25. 1
      src/templates/src/fishbowls/oop/files/261d-3A498.svg
  26. 1
      src/templates/src/fishbowls/oop/files/26ab-FC554.svg
  27. 1
      src/templates/src/fishbowls/oop/files/2757-5311E.svg
  28. 1
      src/templates/src/fishbowls/oop/files/2764-02CD4.svg
  29. BIN
      src/templates/src/fishbowls/oop/files/3bf987dc7a33d0b2f989878615544d6a-D4B96.png
  30. BIN
      src/templates/src/fishbowls/oop/files/418ec586b1074c5304d2bdfde2d725c9-F2143.png
  31. BIN
      src/templates/src/fishbowls/oop/files/487994603568496650-3FA2C.png
  32. BIN
      src/templates/src/fishbowls/oop/files/597863487032786944-538BB.png
  33. BIN
      src/templates/src/fishbowls/oop/files/62e486caf24d352ab938701a8d972730-5ADCF.png
  34. BIN
      src/templates/src/fishbowls/oop/files/777941313546092555-41FE8.png
  35. BIN
      src/templates/src/fishbowls/oop/files/798990517714419714-A5156.png
  36. BIN
      src/templates/src/fishbowls/oop/files/851646609917476884-15D55.png
  37. BIN
      src/templates/src/fishbowls/oop/files/89747c254631bcfd05c5c3e7141389aa-A1FB9.png
  38. BIN
      src/templates/src/fishbowls/oop/files/db36a06d98bf0e98017ec3559150c05c-F4AEF.png
  39. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f44d.svg
  40. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f4af.svg
  41. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f604.svg
  42. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f605.svg
  43. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f608.svg
  44. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f61b.svg
  45. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f642.svg
  46. 1
      src/templates/src/fishbowls/oop/files/twemoji_1f914.svg
  47. BIN
      src/templates/src/fishbowls/oop/files/y18-27627.gif
  48. 3
      src/templates/src/include/header.html
  49. 4
      src/templates/src/landing.html
  50. 4
      src/templates/src/wheeljam_index.html
  51. 6
      src/templates/templates.go
  52. 2
      src/templates/types.go
  53. 1
      src/website/base_data.go
  54. 247
      src/website/fishbowl.go
  55. 4
      src/website/routes.go

1
.gitignore vendored

@ -14,3 +14,4 @@ adminmailer/config.go
adminmailer/adminmailer
local/backups
/tmp
*.exe

@ -0,0 +1,618 @@
.fishbowl {
background-color: #36393e;
color: #dcddde;
}
.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.7em;
line-height: 1.4em;
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.85em;
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;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__content {
padding-right: 1rem;
word-wrap: break-word;
}
.fishbowl .chatlog__edited-timestamp {
margin-left: 0.15rem;
color: #a3a6aa;
font-size: 0.7em;
}
.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;
background-color: #4f545c;
}
.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,619 @@
.fishbowl {
background-color: #ffffff;
color: #23262a;
border: 1px solid #ddd;
}
.fishbowl a {
color: #0068e0;
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: #2f3136;
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: #fafafa;
}
.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 #c7ccd1;
border-top: 2px solid #c7ccd1;
border-radius: 8px 0 0 0;
}
.fishbowl .chatlog__avatar {
width: 40px;
height: 40px;
border-radius: 50%;
}
.fishbowl .chatlog__short-timestamp {
display: none;
color: #5e6772;
font-size: 0.7em;
line-height: 1.4em;
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: #5f5f60;
font-size: 0.85em;
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: #2f3136;
}
.fishbowl .chatlog__reference-link:hover *:not(.chatlog__markdown-spoiler) {
color: inherit;
}
.fishbowl .chatlog__reference-edited-timestamp {
margin-left: 0.25rem;
color: #5e6772;
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: 600;
color: #2f3136;
}
.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: #5e6772;
font-size: 0.75rem;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__content {
padding-right: 1rem;
word-wrap: break-word;
}
.fishbowl .chatlog__edited-timestamp {
margin-left: 0.15rem;
color: #5e6772;
font-size: 0.7em;
}
.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 #ebedef;
border-radius: 3px;
background-color: #f2f3f5;
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: rgba(227, 229, 232, 1);
}
.fishbowl .chatlog__embed-content-container {
display: flex;
flex-direction: column;
padding: 0.5rem 0.6rem;
border: 1px solid rgba(204, 204, 204, 0.3);
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
background-color: rgba(249, 249, 249, 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: #4f545c;
font-size: 0.875rem;
font-weight: 600;
direction: ltr;
unicode-bidi: bidi-override;
}
.fishbowl .chatlog__embed-author-link {
color: #4f545c;
}
.fishbowl .chatlog__embed-title {
margin-bottom: 0.5rem;
color: #4f545c;
font-size: 0.875rem;
font-weight: 600;
}
.fishbowl .chatlog__embed-description {
color: #2e3338;
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: #36393e;
font-weight: 600;
}
.fishbowl .chatlog__embed-field-value {
color: #2e3338;
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: #2e3338;
}
.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: #f2f3f5;
align-items: center;
}
.fishbowl .chatlog__reaction:hover {
border: 1px solid rgba(0, 0, 0, 0.2);
background-color: white;
}
.fishbowl .chatlog__reaction-count {
min-width: 9px;
margin-left: 0.35rem;
color: #4f5660;
font-size: 0.875rem;
}
.fishbowl .chatlog__reaction:hover .chatlog__reaction-count {
color: #2e3338;
}
.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(0, 0, 0, 0.1);
border-radius: 3px;
}
.fishbowl .chatlog__markdown-spoiler--hidden {
cursor: pointer;
background-color: #b9bbbe;
color: rgba(0, 0, 0, 0);
}
.fishbowl .chatlog__markdown-spoiler--hidden:hover {
background-color: rgba(185, 187, 190, 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 #c7ccd1;
border-radius: 3px;
background-color: #c7ccd1;
}
.fishbowl .chatlog__markdown-pre {
background-color: #f9f9f9;
font-family: "Consolas", "Courier New", Courier, monospace;
}
.fishbowl .chatlog__markdown-pre--multiline {
margin-top: 0.25rem;
padding: 0.5rem;
border: 2px solid #f3f3f3;
border-radius: 5px;
color: #657b83;
}
.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, .15);
color: #505cdc;
font-weight: 500;
}
.fishbowl .chatlog__markdown-mention:hover {
background-color: #5865f2;
color: #ffffff
}
.fishbowl .chatlog__markdown-timestamp {
border-radius: 3px;
padding: 0 2px;
color: #5e6772;
}
.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: #2f3136;
}

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 734 30" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(0.412851,0,0,0.412851,-164.727,-144.911)">
<path d="M399,404C477.667,404 563.667,422.167 640,421C712.766,419.888 784.237,398.26 857,397C934,395.667 1021,413.167 1102,413C1182.53,412.834 1262.47,395.225 1343,396C1482.5,397.343 1719.83,418.976 1861,421.056C1915.68,421.862 2097.72,404.026 2176.88,404.026L2176.88,351.026L399,351L399,404Z" style="fill:rgb(255,0,0);"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 859 B

@ -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
}
}

@ -12,8 +12,9 @@ import (
type UsersQuery struct {
// Ignored when using FetchUser
UserIDs []int // if empty, all users
Usernames []string // if empty, all users
UserIDs []int // if empty, all users
Usernames []string // if empty, all users
DiscordUserIDs []string // if empty, no Discord filtering
// Flags to modify behavior
AnyStatus bool // Bypasses shadowban system
@ -44,8 +45,9 @@ func FetchUsers(
}
type userRow struct {
User models.User `db:"hmn_user"`
AvatarAsset *models.Asset `db:"avatar"`
User models.User `db:"hmn_user"`
AvatarAsset *models.Asset `db:"avatar"`
DiscordUser *models.DiscordUser `db:"discord_user"`
}
var qb db.QueryBuilder
@ -54,6 +56,7 @@ func FetchUsers(
FROM
hmn_user
LEFT JOIN asset AS avatar ON avatar.id = hmn_user.avatar_asset_id
LEFT JOIN discord_user ON discord_user.hmn_user_id = hmn_user.id
WHERE
TRUE
`)
@ -63,6 +66,9 @@ func FetchUsers(
if len(q.Usernames) > 0 {
qb.Add(`AND LOWER(hmn_user.username) = ANY($?)`, q.Usernames)
}
if len(q.DiscordUserIDs) > 0 {
qb.Add(`AND discord_user.userid = ANY($?)`, q.DiscordUserIDs)
}
if !q.AnyStatus {
if currentUser == nil {
qb.Add(`AND hmn_user.status = $?`, models.UserStatusApproved)
@ -89,6 +95,7 @@ func FetchUsers(
for i, row := range userRows {
user := row.User
user.AvatarAsset = row.AvatarAsset
user.DiscordUser = row.DiscordUser
result[i] = &user
}

@ -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, map[string]string{"slug": "oop"})
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<slug>[^/]+)/?$`)
func BuildFishbowl(slug string) string {
defer CatchPanic()
return Url(fmt.Sprintf("/fishbowl/%s/", slug), nil)
}
var RegexFishbowlFiles = regexp.MustCompile(`^/fishbowl/(?P<slug>[^/]+)(?P<path>/.+)$`)
/*
* Forums
*/

@ -50,6 +50,7 @@ type User struct {
// Non-db fields, to be filled in by fetch helpers
AvatarAsset *Asset
DiscordUser *DiscordUser
}
func (u *User) BestName() string {

@ -0,0 +1,89 @@
{{ template "base.html" . }}
{{ define "extrahead" }}
<link rel="stylesheet" href="{{ static (eq .Theme "dark" | ternary "fishbowl-dark.css" "fishbowl-light.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>
<style>
.fishbowl-banner {
background-color: {{ eq .Theme "dark" | ternary "#254464" "#a0c8f2" }};
position: relative;
overflow: hidden;
padding-top: 30px;
}
.fishbowl-banner::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
pointer-events: none;
background-image: url({{ static "waterline.svg" }});
background-size: 734px 30px;
background-repeat: repeat-x;
{{ if eq .Theme "dark" }}
filter: hue-rotate(210deg) saturate(0.3) brightness(1.1);
{{ else }}
filter: hue-rotate(210deg) saturate(0.15) brightness(2.9);
{{ end }}
}
.fishbowl-banner a {
color: {{ eq .Theme "dark" | ternary "#9ad0ff" "#1f4f99" }};
}
.fishbowl .chatlog__author a {
color: inherit;
}
</style>
{{ end }}
{{ define "content" }}
<div class="ph3 ph0-ns">
<h2>{{ .Info.Title }}</h2>