Beispiel #1
0
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)
}
Beispiel #2
0
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)
}