+
Fishbowls
+
+
Every two months on the Discord, we host a fishbowl: a panel conversation where a select few community members can discuss a topic in detail. Fishbowls give us the opportunity to discuss difficult subjects with more nuance and detail than you can find anywhere else on the Internet. In many ways, they're a distillation of everything the network is about.
+
+
This is an archive of those conversations. If you would like to catch one live, join the Discord!
+
+
We're still working through our backlog of fishbowls, so not all of these are available yet. We'll publish them as we finish them.
+
+
+ {{ range .Fishbowls }}
+
+ {{ if .Valid }}
+
{{ .Fishbowl.Title }}
+ {{ else }}
+
{{ .Fishbowl.Title }}
+ {{ end }}
+
+ {{ .Fishbowl.Month }} {{ .Fishbowl.Year }}
+
+ {{ with .Fishbowl.Description }}
+
{{ . }}
+ {{ end }}
+
+ {{ end }}
+
+
+
If you'd like to help us plan more fishbowls, join the discussion over on GitHub.
+
+{{ end }}
diff --git a/src/templates/src/fishbowls/README.md b/src/templates/src/fishbowls/README.md
new file mode 100644
index 00000000..7e22d74a
--- /dev/null
+++ b/src/templates/src/fishbowls/README.md
@@ -0,0 +1 @@
+Make sure to name these folders according to the URL slugs of the fishbowls. Otherwise, static files for fishbowls will not work.
diff --git a/src/templates/src/fishbowls/oop/OOP.html b/src/templates/src/fishbowls/oop/OOP.html
new file mode 100644
index 00000000..acb3bb14
--- /dev/null
+++ b/src/templates/src/fishbowls/oop/OOP.html
@@ -0,0 +1,12127 @@
+
- This is a selection of recent work done by community members. Want to participate?
Join us on Discord.
+ This is a selection of recent work done by community members. Want to participate?
Join us on Discord.
diff --git a/src/templates/src/wheeljam_index.html b/src/templates/src/wheeljam_index.html
index 1ef17af2..2ca44dad 100644
--- a/src/templates/src/wheeljam_index.html
+++ b/src/templates/src/wheeljam_index.html
@@ -243,7 +243,7 @@
@@ -263,7 +263,7 @@
.*?)(
)(.*?
)(.*?)())`)
+
+func linkifyDiscordContent(c *RequestContext, dbConn db.ConnOrTx, content string) (string, error) {
+ discordUserIdSet := make(map[string]struct{})
+ userIdMatches := reFishbowlDiscordUserId.FindAllStringSubmatch(content, -1)
+ for _, m := range userIdMatches {
+ discordUserIdSet[m[1]] = struct{}{}
+ }
+ discordUserIds := make([]string, 0, len(discordUserIdSet))
+ for id := range discordUserIdSet {
+ discordUserIds = append(discordUserIds, id)
+ }
+
+ hmnUsers, err := hmndata.FetchUsers(c.Context(), dbConn, c.CurrentUser, hmndata.UsersQuery{
+ DiscordUserIDs: discordUserIds,
+ })
+ if err != nil {
+ return "", err
+ }
+
+ return reFishbowlDiscordAuthorHeader.ReplaceAllStringFunc(content, func(s string) string {
+ m := reFishbowlDiscordAuthorHeader.FindStringSubmatch(s)
+ discordUserID := m[4]
+
+ var matchingUser *models.User
+ for _, u := range hmnUsers {
+ if u.DiscordUser.UserID == discordUserID {
+ matchingUser = u
+ break
+ }
+ }
+
+ if matchingUser == nil {
+ return s
+ } else {
+ link := fmt.Sprintf(`
`, hmnurl.BuildUserProfile(matchingUser.Username))
+ return m[1] + link + m[2] + "" + m[3] + link + m[5] + "" + m[6]
+ }
+ }), nil
+}
diff --git a/src/website/routes.go b/src/website/routes.go
index 089dc14d..2b64e966 100644
--- a/src/website/routes.go
+++ b/src/website/routes.go
@@ -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)