start point of hotlist support (untested)

This commit is contained in:
2026-01-25 22:47:28 -07:00
parent c5b2c3d64b
commit 0dd66709d9
6 changed files with 114 additions and 20 deletions
+1 -1
View File
@@ -119,7 +119,7 @@ func Topics(ctxt ui.AmContext) (string, any, error) {
ctxt.VarMap().Set("conferenceName", conf.Name)
ctxt.VarMap().Set("urlBack", fmt.Sprintf("/comm/%s/conf", comm.Alias))
ctxt.VarMap().Set("urlStem", urlStem)
ctxt.VarMap().Set("permalink", "TODO")
ctxt.VarMap().Set("permalink", fmt.Sprintf("/go/%s!%s", comm.Alias, ctxt.GetScratch("currentAlias")))
ctxt.VarMap().Set("view", view)
ctxt.VarMap().Set("sort", sort)
ctxt.VarMap().Set("topics", topics)
+48 -1
View File
@@ -1,6 +1,6 @@
/*
* Amsterdam Web Communities System
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
* Copyright (c) 2025-2026 Erbosoft Metaverse Design Solutions, All Rights Reserved
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,9 +9,56 @@
// The database package contains database management and storage logic.
package database
import "context"
// ConferenceHotlist represents a user's conference hotlist.
type ConferenceHotlist struct {
Uid int32 `db:"uid"`
Sequence int16 `db:"sequence"`
CommId int32 `db:"commid"`
ConfId int32 `db:"confid"`
}
// Community gets the community pointer from the hotlist.
func (h *ConferenceHotlist) Community(ctx context.Context) (*Community, error) {
return AmGetCommunity(ctx, h.CommId)
}
// Conference gets the conference pointer from the hotlist.
func (h *ConferenceHotlist) Conference(ctx context.Context) (*Conference, error) {
return AmGetConference(ctx, h.ConfId)
}
// AmGetConferenceHotlist gets the conference hotlist for a user.
func AmGetConferenceHotlist(ctx context.Context, u *User) ([]ConferenceHotlist, error) {
var rc []ConferenceHotlist
err := amdb.SelectContext(ctx, &rc, "SELECT * FROM confhotlist WHERE uid = ? ORDER BY sequence", u.Uid)
return rc, err
}
// AmCopyConferenceHotlist copies the conference hotlist from one user to another.
func AmCopyConferenceHotlist(ctx context.Context, from, to *User) error {
hotlist, err := AmGetConferenceHotlist(ctx, from)
if err != nil {
return err
}
success := false
tx := amdb.MustBegin()
defer func() {
if !success {
tx.Rollback()
}
}()
for _, hl := range hotlist {
if _, err = tx.ExecContext(ctx, "INSERT INTO confhotlist (uid, sequence, commid, confid) VALUES (?, ?, ?, ?)",
to.Uid, hl.Sequence, hl.CommId, hl.ConfId); err != nil {
return err
}
}
if err = tx.Commit(); err != nil {
return err
}
success = true
return nil
}
+7 -4
View File
@@ -680,7 +680,7 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
defer func() {
AmStoreAudit(ar)
}()
anon, _ := getAnonUserID(ctx)
anon, _ := AmGetAnonUser(ctx)
success := false
tx := amdb.MustBegin()
defer func() {
@@ -728,7 +728,7 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
// add user properties
props := make([]UserProperties, 0)
if err = tx.SelectContext(ctx, &props, "SELECT * FROM propuser WHERE uid = ?", anon); err != nil {
if err = tx.SelectContext(ctx, &props, "SELECT * FROM propuser WHERE uid = ?", anon.Uid); err != nil {
return nil, err
}
for _, p := range props {
@@ -739,7 +739,7 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
}
// add user sideboxes
if err = copySideboxes(ctx, tx, user.Uid, anon); err != nil {
if err = copySideboxes(ctx, tx, user.Uid, anon.Uid); err != nil {
return nil, err
}
@@ -756,7 +756,10 @@ func AmCreateNewUser(ctx context.Context, username string, password string, remi
return nil, err
}
// TODO: copy conference hotlists
// copy conference hotlists
if err = AmCopyConferenceHotlist(ctx, anon, user); err != nil {
return nil, err
}
// operation was a success - add an audit record
ar = AmNewAudit(AuditAccountCreated, user.Uid, remoteIP)
+1 -1
View File
@@ -1,6 +1,6 @@
# TODOs list:
- Topics list: Set up Conference permalink
- ~~Topics list: Set up Conference permalink~~
- Send out E-mails to topic subscribers when a post is made
- Error handling: shift titles and templates for different error codes
- Find Posts
+40 -4
View File
@@ -22,6 +22,7 @@ import (
// RenderedSideboxItem is an item for display inside a rendered sidebox.
type RenderedSideboxItem struct {
Text string
Text2 string
Link *string
Flags map[string]bool
}
@@ -95,15 +96,50 @@ func buildCommunitiesSidebox(ctxt ui.AmContext, uid int32, out *RenderedSidebox,
/* buildFeaturedConferences creates the data for the "Featured Conferences" sidebox.
* Parameters:
* ctxt - AmContext for the operation.
* uid - UID of the user rendering the page.
* out - The RenderedSidebox to be built.
* in - The sidebox data from the database.
* Returns:
* Standard Go error status.
*/
func buildFeaturedConferences(uid int32, out *RenderedSidebox, in *database.Sidebox) error {
out.TemplateName = "sb_ftrconf.jet"
return nil
func buildFeaturedConferences(ctxt ui.AmContext, uid int32, out *RenderedSidebox, in *database.Sidebox) error {
user, err := database.AmGetUser(ctxt.Ctx(), uid)
if err == nil {
if user.IsAnon {
out.Title = "Featured Conferences"
} else {
out.Title = "Your Conference Hotlist"
}
var hl []database.ConferenceHotlist
hl, err := database.AmGetConferenceHotlist(ctxt.Ctx(), user)
if err == nil {
out.Items = make([]RenderedSideboxItem, len(hl))
for i, h := range hl {
comm, err := h.Community(ctxt.Ctx())
if err != nil {
break
}
conf, err := h.Conference(ctxt.Ctx())
if err != nil {
break
}
alias, err := conf.Aliases(ctxt.Ctx())
if err != nil {
break
}
out.Items[i].Text = conf.Name
out.Items[i].Text2 = comm.Name
lk := fmt.Sprintf("/comm/%s/conf/%s", comm.Alias, alias[0])
out.Items[i].Link = &lk
out.Items[i].Flags = make(map[string]bool)
// TODO: add "New" indicator
}
out.Flags = make(map[string]bool)
out.TemplateName = "sb_ftrconf.jet"
}
}
return err
}
/* buildUsersOnline creates the data for the "Users Online" sidebox.
@@ -158,7 +194,7 @@ func buildRenderedSidebox(ctxt ui.AmContext, uid int32, out *RenderedSidebox, in
case 1:
return buildCommunitiesSidebox(ctxt, uid, out, in)
case 2:
return buildFeaturedConferences(uid, out, in)
return buildFeaturedConferences(ctxt, uid, out, in)
case 3:
return buildUsersOnline(uid, out, in)
default:
+17 -9
View File
@@ -6,19 +6,27 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*}
<!-- Featured Conferences -->
<!-- Conference Hotlist sidebox -->
{{ sb := .GetScratch("__sidebox") }}
<div class="mb-4">
<div class="bg-blue-600 px-2 py-1 rounded-t">
<h3 class="text-white font-bold text-base">Featured Conferences:</h3>
<h3 class="text-white font-bold text-base">{{ sb.Title }}:</h3>
</div>
<div class="bg-blue-400 px-2 py-2 rounded-b">
<div class="flex items-center">
<span class="mr-2">🟣</span>
<div class="text-sm">
<a href="http://necrovenice:8080/venice/conf/topics.js.vs?sig=2&conf=2"
class="text-blue-700 hover:text-blue-900 font-bold">General Discussion</a>
<span class="text-black"> (La Piazza)</span>
</div>
<div class="space-y-2">
{{ if len(sb.Items) > 0 }}
{{ range i, item := sb.Items }}
<div class="flex items-center">
<span class="mr-2">🟣</span>
<div class="text-sm">
<a href="{{ item.Link }}" class="text-blue-700 hover:text-blue-900 font-bold">{{ item.Text }}</a>
<span class="text-black"> ({{ item.Text2 }})</span>
</div>
</div>
{{ end }}
{{ else }}
<div class="text-small">No conferences in hotlist.</div>
{{ end }}
</div>
</div>
</div>