Created
August 16, 2010 03:15
-
-
Save milesegan/526333 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package code.comet | |
import net.liftweb._ | |
import http._ | |
import actor._ | |
import js._ | |
import JsCmds._ | |
import js.jquery.JqJsCmds.{AppendHtml, FadeOut, Hide, FadeIn} | |
import java.util.Date | |
import scala.xml._ | |
import util.Helpers._ | |
import util.Log | |
object ChatServer extends LiftActor with ListenerManager { | |
private var messages: List[ChatCmd] = List("Welcome") | |
def createUpdate = messages | |
override def lowPriority = { | |
case s: String => messages ::= s ; updateListeners() | |
case d: RemoveMessage => messages ::= d ; updateListeners() | |
} | |
} | |
sealed trait ChatCmd | |
object ChatCmd { | |
implicit def strToMsg(msg: String): ChatCmd = | |
new AddMessage(nextFuncName, msg, new Date) | |
} | |
final case class AddMessage(guid: String, msg: String, date: Date) extends ChatCmd | |
final case class RemoveMessage(guid: String) extends ChatCmd | |
class Chat extends CometActor with CometListener { | |
private var msgs: List[ChatCmd] = Nil | |
private var bindLine: NodeSeq = Nil | |
def registerWith = ChatServer | |
override def lowPriority = { | |
case m: List[ChatCmd] => { | |
val delta = m diff msgs | |
msgs = m | |
updateDeltas(delta) | |
} | |
} | |
def updateDeltas(what: List[ChatCmd]) { | |
partialUpdate(what.foldRight(Noop) { | |
case (m: AddMessage , x) => | |
x & AppendHtml("ul_dude", doLine(m)) & | |
Hide(m.guid) & FadeIn(m.guid, TimeSpan(0),TimeSpan(500)) | |
case (RemoveMessage(guid), x) => | |
x & FadeOut(guid,TimeSpan(0),TimeSpan(500)) & | |
After(TimeSpan(500),Replace(guid, NodeSeq.Empty)) | |
}) | |
} | |
def render = | |
bind("chat", // the namespace for binding | |
"line" -> lines _, // bind the function lines | |
"input" -> SHtml.text("", s => ChatServer ! s)) // the input | |
private def lines(xml: NodeSeq): NodeSeq = { | |
bindLine = xml | |
val deleted = Set((for { | |
RemoveMessage(guid) <- msgs | |
} yield guid) :_*) | |
for { | |
m @ AddMessage(guid, msg, date) <- msgs.reverse if !deleted.contains(guid) | |
node <- doLine(m) | |
} yield node | |
} | |
private def doLine(m: AddMessage): NodeSeq = | |
bind("chat", addId(bindLine, m.guid), | |
"msg" -> m.msg, | |
"btn" -> SHtml.ajaxButton("delete", | |
() => { | |
ChatServer ! | |
RemoveMessage(m.guid) | |
Noop})) | |
private def addId(in: NodeSeq, id: String): NodeSeq = in map { | |
case e: Elem => e % ("id" -> id) | |
case x => x | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment