-
Notifications
You must be signed in to change notification settings - Fork 125
/
hello_chat.opa
93 lines (84 loc) · 2.54 KB
/
hello_chat.opa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/**
* {1 Import standard classes of bootstrap css}
*
* see http://twitter.github.com/bootstrap/
*/
import stdlib.themes.bootstrap
/**
* {1 Network infrastructure}
*/
/**
* The type of messages sent by a client to the chatroom
*/
type message = {author: string /**The name of the author (arbitrary string)*/
; text: string /**Content entered by the user*/}
/**
* The chatroom.
*/
@publish room = Network.cloud("room"): Network.network(message)
/**
* {1 User interface}
*/
/**
* Update the user interface in reaction to reception of a message.
*
* This function is meant to be registered with [room] as a callback.
* Its sole role is to display the new message in [#conversation].
*
* @param x The message received from the chatroom
*/
user_update(x: message) =
line = <div class="row line">
<div class="span2 columns">
<span class="user">{x.author}:</span>
</div>
<div class="span14 columns">
<span class="message">{x.text}</span>
</div>
</div>
do Dom.transform([#conversation +<- line ])
Dom.scroll_to_bottom(#conversation)
/**
* Broadcast text to the [room].
*
* Read the contents of [#entry], clear these contents and send the message to [room].
*
* @param author The name of the author. Will be included in the message broadcasted.
*/
broadcast(author) =
do Network.broadcast({~author text=Dom.get_value(#entry)}, room)
Dom.clear_value(#entry)
/**
* Build the user interface for a client.
*
* Pick a random author name which will be used throughout the chat.
*
* @return The user interface, ready to be sent by the server to the client on connection.
*/
start() =
author = Random.string(8)
<div class="topbar">
<div class="fill">
<div class="container">
<div id=#logo></div>
</div>
</div>
</div>
<div class="container" id=#conversation onready={_ -> Network.add_callback(user_update, room)}></div>
<div class="row" id=#footer>
<input id=#entry onnewline={_ -> broadcast(author)}/>
<div class="btn" onclick={_ -> broadcast(author)}>Post</div>
</div>
/**
* {1 Application}
*/
/**
* Main entry point.
*
* Construct an application called "Chat" (users will see the name in the title bar),
* embedding statically the contents of directory "resources", using the global stylesheet
* "resources/css.css" and the user interface defined in [start].
*/
server = Server.one_page_bundle("Chat",
[@static_resource_directory("resources")],
["resources/css.css"], start)