Skip to content

Commit

Permalink
Content class added
Browse files Browse the repository at this point in the history
  • Loading branch information
ignatov committed Jul 20, 2011
1 parent f1dde8c commit 84756ce
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/main/scala/bootstrap/liftweb/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import _root_.net.liftweb.mapper.{DB, Schemifier, DefaultConnectionIdentifier, S

import tools.colladoc.api.ExportService
import tools.colladoc.lib.sitemap._
import tools.colladoc.model.mapper.{User, Comment, Properties, Discussion}
import tools.colladoc.model.mapper.{User, Comment, Content, Properties, Discussion}
import tools.colladoc.lib.js.JqUI._
import tools.colladoc.api.{GridAPI, RestAPI}
import tools.colladoc.lib.openid.ColladocOpenIDVendor
Expand All @@ -61,7 +61,7 @@ class Boot {

// where to search snippet
LiftRules.addToPackages("scala.tools.colladoc")
Schemifier.schemify(true, Schemifier.infoF _, User, Comment, Properties, Discussion)
Schemifier.schemify(true, Schemifier.infoF _, User, Comment, Content, Properties, Discussion)

ColladocBoot.boot

Expand Down
72 changes: 72 additions & 0 deletions src/main/scala/scala/tools/colladoc/model/mapper/Content.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2011, Sergey Ignatov. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
* the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
* and the following disclaimer in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COLLABORATIVE SCALADOC PROJECT ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COLLABORATIVE SCALADOC
* PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package scala.tools.colladoc
package model.mapper

import net.liftweb.mapper._
import net.liftweb.common.Full
import lib.util.DateUtils.{atomDateFormatter, dateFormatter}

/**
* Comment of content thread.
* @author Sergey Ignatov
*/
class Content extends LongKeyedMapper[Content] with IdPK {
def getSingleton = Content

/** Qualified name of symbol this comment belongs to. */
object qualifiedName extends MappedString(this, 255) {
override def dbIndexed_? = true
}

/** Changed comment content. */
object comment extends MappedString(this, 4000)

/** Changed comment author. */
object user extends LongMappedMapper(this, User)

/** Change date and time. */
object dateTime extends MappedDateTime(this)

/** Whether this change is still valid. */
object valid extends MappedBoolean(this) {
override def defaultValue = true
}

/** Get change author's username. */
def userName: String = User.find(user.is) match {
case Full(u) => u.userName
case _ => ""
}

/** Get change author's username and date. */
def userNameDate: String = "%s by %s".format(dateFormatter(dateTime.is), userName)

def atomDateTime: String = atomDateFormatter(dateTime.is).toString

def humanDateTime: String = dateFormatter(dateTime.is).toString
}

object Content extends Content with LongKeyedMetaMapper[Content] {
override def dbTableName = "content"
}
110 changes: 109 additions & 1 deletion src/main/scala/scala/tools/colladoc/page/Template.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import lib.js.JqUI._
import lib.widgets.Editor
import model.Model
import model.Model.factory._
import model.mapper.{Discussion, Comment, User}
import model.mapper.{Discussion, Comment, Content, User}

import net.liftweb.common._
import net.liftweb.http.SHtml
Expand Down Expand Up @@ -109,6 +109,8 @@ class Template(tpl: DocTemplateEntity) extends tools.nsc.doc.html.page.Template(
}
</div>

{ content }

{ if (User.loggedIn_?) discussion }

{ if (constructors.isEmpty) NodeSeq.Empty else
Expand Down Expand Up @@ -242,6 +244,7 @@ class Template(tpl: DocTemplateEntity) extends tools.nsc.doc.html.page.Template(
/** Reload discussion block after new comment adding. */
private def reloadDiscussion = Replace("discussion", discussion) &
JsRaw("$('#discussion_wrapper').toggle();") &
JsRaw("prettyDate();") &
Jq(Str("button")) ~> Button()

/** Save discussion comment to database. */
Expand Down Expand Up @@ -276,6 +279,111 @@ class Template(tpl: DocTemplateEntity) extends tools.nsc.doc.html.page.Template(
d.comment(text).save
}

/** Render content block. */
private def content: NodeSeq =
<div id="content">
<h3 id="content_header">Content ({contentCommentsCount})</h3>
<div id="content_wrapper">
<ul id="content_thread">
{contentComments map (d => contentToHtmlWithActions(d))}
</ul>
{ if (User.loggedIn_?) contentCommentAddButton }
</div>
</div>

/** Get content comments for current template. */
private def contentComments = Content.findAll(
By(Content.qualifiedName, tpl.qualifiedName),
By(Content.valid, true),
OrderBy(Content.dateTime, Ascending))

/** Get content comments count for current template. */
private def contentCommentsCount = contentComments.length

/** Render content comment. */
def contentToHtml(c: Content) =
<li id={"content_comment_" + c.id} class="content_comment">
<div class="content_content">{bodyToHtml(parseWiki(c.comment.is, NoPosition))}</div>
<div class="content_info">
<span class="datetime" title={c.atomDateTime}>{c.humanDateTime}</span>
by
<span class="author">{c.userName}</span>
<content_comment:link />
<content_comment:edit />
<content_comment:delete />
</div>
</li>

/** Render content comment with actions. */
private def contentToHtmlWithActions(d: Content) = bind("content_comment", contentToHtml(d),
"edit" -> {if (User.superUser_?) { editContentButton(d) } else NodeSeq.Empty},
"delete" -> {if (User.superUser_?) { deleteContentButton(d) } else NodeSeq.Empty}
)

/** Render add comment button. */
private def contentCommentAddButton = {
SHtml.ajaxButton(Text("Add comment"), contentEditor(None) _, ("class", "button"), ("id", "add_content_button"))
}

/** Render editor. */
private def contentEditor(maybe: Option[Content] = None)(): JsCmd = {
maybe match {
case Some(d) =>
Editor.editorObj(d.comment.is, preview _, updateContentComment(d) _) match {
case (n, j) =>
Replace("content_comment_" + d.id,
<form id={"edit_form_" + d.id} class="edit" method="GET">
<div class="editor">
{ n }
<div class="buttons">
{ SHtml.ajaxButton(Text("Save"), () => SHtml.submitAjaxForm("edit_form_" + d.id, () => reloadContent)) }
{ SHtml.a(Text("Cancel"), Replace("edit_form_" + d.id, contentToHtmlWithActions(d)) & Jq(Str("button")) ~> Button(), ("class", "button")) }
</div>
</div>
</form>) & j & Jq(Str("button")) ~> Button()
case _ => JsCmds.Noop
}
case None =>
Editor.editorObj("", preview _, saveContentComment _) match {
case (n, j) =>
Replace("add_content_button",
<form id="content_form" class="edit" method="GET">
<div class="editor">
{ n }
<div class="buttons">
{ SHtml.ajaxButton(Text("Save"), () => SHtml.submitAjaxForm("content_form", () => reloadContent)) }
{ SHtml.a(Text("Cancel"), Replace("content_form", contentCommentAddButton) & Jq(Str("button")) ~> Button(), ("class", "button")) }
</div>
</div>
</form>) & j & Jq(Str("button")) ~> Button()
case _ => JsCmds.Noop
}
}
}

/** Reload content block after new comment adding. */
private def reloadContent = Replace("content", content) &
JsRaw("$('#content_wrapper').toggle();") &
JsRaw("prettyDate();") &
Jq(Str("button")) ~> Button()

/** Save content comment to database. */
private def saveContentComment(text: String) {
Content.create.qualifiedName(tpl.qualifiedName).comment(text).dateTime(now).user(User.currentUser.open_!).valid(true).save
}

/** Render delete button for content comment. */
def deleteContentButton(d: Content) = SHtml.a(
ColladocConfirm("Confirm delete"), () => {d.valid(false).save; reloadContent}, Text("Delete"))

/** Render delete button for content comment. */
def editContentButton(d: Content) = SHtml.a(contentEditor(Some(d)) _, Text("Edit"))

/** Update content comment record in database. */
private def updateContentComment(d: Content)(text: String) {
d.comment(text).save
}

override def memberToHtml(mbr: MemberEntity): NodeSeq =
super.memberToHtml(mbr) \% Map("data-istype" -> (mbr.isAbstractType || mbr.isAliasType).toString)

Expand Down
22 changes: 22 additions & 0 deletions src/main/webapp/cotemplate.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,26 @@ background-color: #E5E5E5;

.discussion_info {
color: #999999;
}

#content h3 {
color: white;
padding: 4px;
background-color: #8EAD20;
font-size: 12pt;
font-weight: bold;
}

#content_wrapper {
display: none;
padding: 4px;
}

.content_comment {
margin: 7px 0;
list-style: none;
}

.content_info {
color: #999999;
}
10 changes: 9 additions & 1 deletion src/main/webapp/scripts/cotemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,15 @@ $("#discussion_header").live("click", function(){
$("#discussion_wrapper").slideToggle(100);
});

$(document).ready(function() {
$("#content_header").live("click", function(){
$("#content_wrapper").slideToggle(100);
});

function prettyDate() {
if (jQuery.prettyDate)
$(".datetime").prettyDate();
}

$(document).ready(function() {
prettyDate();
});

0 comments on commit 84756ce

Please sign in to comment.