func HandleCreateMessage(ctx context.Context, w http.ResponseWriter, r *http.Request) { uid, ok := CurrentUserID(r) if !ok { // TODO - redirect to authentication page, but remember form content tmpl.Render500(w, errors.New("not implemented")) return } tid, err := strconv.Atoi(param(ctx, "topicid")) if err != nil || tid < 0 { tmpl.Render404(w, "Topic does not exist") return } content := strings.TrimSpace(r.FormValue("content")) if len(content) < 3 { tmpl.Render400(w, "Message too short") return } if len(content) > 20000 { tmpl.Render400(w, "Message too long") return } tx, err := DB(ctx).Beginx() if err != nil { tmpl.Render500(w, err) return } defer tx.Rollback() store := NewStore(tx) t, err := store.TopicByID(uint(tid)) if err != nil { if err == ErrNotFound { tmpl.Render404(w, "Topic does not exist") } else { tmpl.Render500(w, err) } return } m, err := store.CreateMessage(t.TopicID, uid, content, time.Now()) if err != nil { tmpl.Render500(w, err) return } if err := tx.Commit(); err != nil { tmpl.Render500(w, err) return } murl := fmt.Sprintf( "/t/%d/%s?page=%d#m%d", t.TopicID, t.Topic.Slug(), t.Pages(), m.MessageID) http.Redirect(w, r, murl, http.StatusFound) }
func HandleListTopicMessages(ctx context.Context, w http.ResponseWriter, r *http.Request) { tx, err := DB(ctx).Beginx() if err != nil { panic(err) } defer tx.Rollback() store := NewStore(tx) topicID, err := strconv.Atoi(param(ctx, "topicid")) if err != nil || topicID < 0 { tmpl.Render404(w, "Topic does not exist") return } topic, err := store.TopicByID(uint(topicID)) if err == ErrNotFound { tmpl.Render404(w, "Topic does not exist") return } if err != nil { tmpl.Render500(w, err) return } if checkLastModified(w, r, topic.Updated) { return } p := NewPaginator(r.URL.Query(), int(topic.Replies+1)) messages, err := store.TopicMessages(topic.TopicID, p.Offset(), p.Limit()) if err != nil { tmpl.Render500(w, err) return } type MessageWithUserPos struct { *Message *User CollectionPos int // position number in messages collection } emsgs := make([]*MessageWithUserPos, 0, len(messages)) for i, m := range messages { emsgs = append(emsgs, &MessageWithUserPos{ CollectionPos: i + (p.CurrentPage()-1)*int(p.PageSize()) + 1, Message: &m.Message, User: &m.User, }) } c := struct { Topic *TopicWithUserCategory Messages []*MessageWithUserPos Paginator *Paginator }{ Topic: topic, Messages: emsgs, Paginator: p, } tmpl.Render(w, http.StatusOK, "page_message_list", c) }