✨ Use @ToadletPath for JSON pages, too
[Sone.git] / src / main / kotlin / net / pterodactylus / sone / web / ajax / GetNotificationsAjaxPage.kt
1 package net.pterodactylus.sone.web.ajax
2
3 import net.pterodactylus.sone.data.Sone
4 import net.pterodactylus.sone.data.SoneOptions
5 import net.pterodactylus.sone.main.SonePlugin
6 import net.pterodactylus.sone.utils.jsonArray
7 import net.pterodactylus.sone.utils.jsonObject
8 import net.pterodactylus.sone.web.WebInterface
9 import net.pterodactylus.sone.web.page.*
10 import net.pterodactylus.util.notify.Notification
11 import net.pterodactylus.util.notify.TemplateNotification
12 import java.io.StringWriter
13 import javax.inject.Inject
14
15 /**
16  * AJAX handler to return all current notifications.
17  */
18 @ToadletPath("getNotifications.ajax")
19 class GetNotificationsAjaxPage @Inject constructor(webInterface: WebInterface) : JsonPage(webInterface) {
20
21         override val needsFormPassword = false
22         override val requiresLogin = false
23
24         override fun createJsonObject(request: FreenetRequest) =
25                         getCurrentSone(request.toadletContext, false).let { currentSone ->
26                                 webInterface.getNotifications(currentSone)
27                                                 .sortedBy(Notification::getCreatedTime)
28                                                 .let { notifications ->
29                                                         createSuccessJsonObject().apply {
30                                                                 put("notificationHash", notifications.hashCode())
31                                                                 put("options", currentSone?.options.asJsonObject)
32                                                                 put("notifications", notifications.asJsonObject(currentSone, request))
33                                                         }
34                                                 }
35                         }
36
37         private fun Collection<Notification>.asJsonObject(currentSone: Sone?, freenetRequest: FreenetRequest) = jsonArray(
38                         *map { notification ->
39                                 jsonObject(
40                                                 "id" to notification.id,
41                                                 "createdTime" to notification.createdTime,
42                                                 "lastUpdatedTime" to notification.lastUpdatedTime,
43                                                 "dismissable" to notification.isDismissable,
44                                                 "text" to if (notification is TemplateNotification) notification.render(currentSone, freenetRequest) else notification.render()
45                                 )
46                         }.toTypedArray()
47         )
48
49         private fun TemplateNotification.render(currentSone: Sone?, freenetRequest: FreenetRequest) = StringWriter().use {
50                 val mergedTemplateContext = webInterface.templateContextFactory.createTemplateContext()
51                                 .mergeContext(templateContext)
52                                 .apply {
53                                         this["core"] = core
54                                         this["currentSone"] = currentSone
55                                         this["localSones"] = core.localSones
56                                         this["request"] = freenetRequest
57                                         this["currentVersion"] = SonePlugin.getPluginVersion()
58                                         this["hasLatestVersion"] = core.updateChecker.hasLatestVersion()
59                                         this["latestEdition"] = core.updateChecker.latestEdition
60                                         this["latestVersion"] = core.updateChecker.latestVersion
61                                         this["latestVersionTime"] = core.updateChecker.latestVersionDate
62                                         this["notification"] = this@render
63                                 }
64                 it.also { render(mergedTemplateContext, it) }
65         }.toString()
66
67 }
68
69 private val SoneOptions?.asJsonObject
70         get() = this?.let { options ->
71                 jsonObject(
72                                 "ShowNotification/NewSones" to options.isShowNewSoneNotifications,
73                                 "ShowNotification/NewPosts" to options.isShowNewPostNotifications,
74                                 "ShowNotification/NewReplies" to options.isShowNewReplyNotifications
75                 )
76         } ?: jsonObject {}
77
78 private fun Notification.render() = StringWriter().use { it.also { render(it) } }.toString()