1 package net.pterodactylus.sone.web.ajax
3 import com.fasterxml.jackson.databind.JsonNode
4 import net.pterodactylus.sone.data.Post
5 import net.pterodactylus.sone.data.PostReply
6 import net.pterodactylus.sone.data.Sone
7 import net.pterodactylus.sone.data.SoneOptions
8 import net.pterodactylus.sone.freenet.L10nFilter
9 import net.pterodactylus.sone.template.SoneAccessor
10 import net.pterodactylus.sone.text.TimeTextConverter
11 import net.pterodactylus.sone.utils.jsonObject
12 import net.pterodactylus.sone.utils.toArray
13 import net.pterodactylus.sone.web.WebInterface
14 import net.pterodactylus.sone.web.page.FreenetRequest
15 import java.text.SimpleDateFormat
18 * The “get status” AJAX handler returns all information that is necessary to
19 * update the web interface in real-time.
21 class GetStatusAjaxPage(webInterface: WebInterface, private val timeTextConverter: TimeTextConverter, private val l10nFilter: L10nFilter):
22 JsonPage("getStatus.ajax", webInterface) {
24 private val dateFormatter = SimpleDateFormat("MMM d, yyyy, HH:mm:ss")
26 override fun createJsonObject(request: FreenetRequest) =
27 (webInterface.getCurrentSoneWithoutCreatingSession(request.toadletContext) as Sone?).let { currentSone ->
28 createSuccessJsonObject().apply {
29 this["loggedIn"] = currentSone != null
30 this["options"] = currentSone?.options?.toJsonOptions() ?: jsonObject {}
31 this["notificationHash"] = webInterface.getNotifications(currentSone).sortedBy { it.createdTime }.hashCode()
32 this["sones"] = request.httpRequest.getParam("soneIds").split(',').map { webInterface.core.getSone(it).orNull() }.plus(currentSone).filterNotNull().toJsonSones()
33 this["newPosts"] = webInterface.getNewPosts(currentSone).toJsonPosts()
34 this["newReplies"] = webInterface.getNewReplies(currentSone).toJsonReplies()
38 private operator fun JsonReturnObject.set(key: String, value: JsonNode) = put(key, value)
39 private operator fun JsonReturnObject.set(key: String, value: Int) = put(key, value)
40 private operator fun JsonReturnObject.set(key: String, value: Boolean) = put(key, value)
42 override fun needsFormPassword() = false
43 override fun requiresLogin() = false
45 private fun SoneOptions.toJsonOptions() = jsonObject {
46 put("ShowNotification/NewSones", isShowNewSoneNotifications)
47 put("ShowNotification/NewPosts", isShowNewPostNotifications)
48 put("ShowNotification/NewReplies", isShowNewReplyNotifications)
51 private fun Iterable<Sone>.toJsonSones() = map { sone ->
54 put("name", SoneAccessor.getNiceName(sone))
55 put("local", sone.isLocal)
56 put("status", sone.status.name)
57 put("modified", webInterface.core.isModifiedSone(sone))
58 put("locked", webInterface.core.isLocked(sone))
59 put("lastUpdatedUnknown", sone.time == 0L)
60 synchronized(dateFormatter) {
61 put("lastUpdated", dateFormatter.format(sone.time))
63 put("lastUpdatedText", timeTextConverter.getTimeText(sone.time).l10nText.let { l10nFilter.format(null, it, emptyMap()) })
67 private fun Iterable<Post>.toJsonPosts() = map { post ->
70 put("sone", post.sone.id)
71 put("time", post.time)
72 put("recipient", post.recipientId.orNull())
76 private fun Iterable<PostReply>.toJsonReplies() = map { reply ->
79 put("sone", reply.sone.id)
80 put("post", reply.postId)
81 put("postSone", reply.post.get().sone.id)