Mercurial Hosting > freedit
annotate src/thread.html.luan @ 48:4e1a01db19ec
add lists
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 17 Nov 2022 00:11:44 -0700 |
parents | 289718f121e4 |
children | f225e82b2bf8 |
rev | line source |
---|---|
9 | 1 local Luan = require "luan:Luan.luan" |
2 local error = Luan.error | |
3 local ipairs = Luan.ipairs or error() | |
18 | 4 local Time = require "luan:Time.luan" |
5 local time_now = Time.now or error() | |
42 | 6 local Html = require "luan:Html.luan" |
7 local html_encode = Html.encode or error() | |
9 | 8 local Io = require "luan:Io.luan" |
9 local Http = require "luan:http/Http.luan" | |
10 local Shared = require "site:/lib/Shared.luan" | |
11 local head = Shared.head or error() | |
12 local header = Shared.header or error() | |
13 local footer = Shared.footer or error() | |
42 | 14 local delete_post = Shared.delete_post or error() |
15 local show_post = Shared.show_post or error() | |
9 | 16 local Forum = require "site:/lib/Forum.luan" |
17 local forum_title = Forum.title or error() | |
18 local Db = require "site:/lib/Db.luan" | |
19 local Post = require "site:/lib/Post.luan" | |
16 | 20 local User = require "site:/lib/User.luan" |
9 | 21 |
11 | 22 |
9 | 23 return function() |
24 local root_id = Http.request.parameters.root or error() | |
25 local docs, total_hits = Db.search("post_root_id:"..root_id,1,1000,{sort="id"}) | |
26 local posts = Post.from_docs(docs) | |
27 local subject_html = posts[1].subject_html | |
16 | 28 local user = User.current() |
29 local user_name = user and user.name | |
18 | 30 local now = time_now() |
9 | 31 Io.stdout = Http.response.text_writer() |
32 %> | |
33 <!doctype html> | |
34 <html> | |
35 <head> | |
36 <% head() %> | |
37 <title><%=forum_title%>: <%=subject_html%></title> | |
38 <style> | |
46 | 39 @import "/bbcode/bbcode.css"; |
40 | |
18 | 41 div[author] { |
42 margin-bottom: 6px; | |
43 font-size: 10px; | |
44 } | |
45 div[author] img { | |
46 width: 28px; | |
47 vertical-align: middle; | |
48 border-radius: 50%; | |
49 } | |
50 div[author] a { | |
51 font-weight: bold; | |
52 } | |
53 span[ago] { | |
54 color: #888; | |
55 } | |
15 | 56 [message] { |
9 | 57 white-space: pre-wrap; |
26 | 58 line-height: 1.4; |
9 | 59 } |
42 | 60 <% if user_name == nil then %> |
61 [logged_in] { | |
62 display: none; | |
63 } | |
64 <% end %> | |
65 [only_user] { | |
66 display: none; | |
25
66fd3784e60e
back to textarea for bbcode
Franklin Schmidt <fschmidt@gmail.com>
parents:
21
diff
changeset
|
67 } |
42 | 68 <% if user_name ~= nil then %> |
69 [only_user="<%=html_encode(user_name)%>"] { | |
70 display: initial; | |
71 } | |
72 <% end %> | |
73 div[post]:first-of-type [delete_opton] { | |
74 display: none; | |
75 } | |
76 body[thread_size="1"] div[post]:first-of-type [delete_opton] { | |
77 display: initial; | |
78 } | |
79 </style> | |
46 | 80 <script src="/bbcode/bbcode.js"></script> |
15 | 81 <script> |
19 | 82 function getPostDiv(node) { |
83 do { | |
84 if( node.getAttribute('post') ) | |
85 return node; | |
86 } while( node = node.parentNode ); | |
87 } | |
88 | |
46 | 89 function cancelEdit(event) { |
90 let postDiv = getPostDiv(event.target); | |
15 | 91 postDiv.querySelector('[output]').style.display = 'block'; |
92 postDiv.querySelector('[edit]').innerHTML = ''; | |
93 } | |
46 | 94 function saveEdit(event) { |
95 let postDiv = getPostDiv(event.target); | |
19 | 96 let post = postDiv.getAttribute('post'); |
25
66fd3784e60e
back to textarea for bbcode
Franklin Schmidt <fschmidt@gmail.com>
parents:
21
diff
changeset
|
97 let text = postDiv.querySelector('textarea').value; |
46 | 98 cancelEdit(event); |
15 | 99 let postData = 'post=' + post + '&text=' + encodeURIComponent(text); |
34 | 100 ajax('save_edit.js',postData); |
15 | 101 } |
42 | 102 function updated(postId,html) { |
103 let postDiv = document.querySelector('[post="'+postId+'"]'); | |
104 if(postDiv) | |
105 postDiv.querySelector('[message]').innerHTML = html; | |
106 } | |
107 | |
108 function newPost() { | |
109 let postDiv = document.querySelector('[post="new"]'); | |
110 let textarea = postDiv.querySelector('textarea') | |
111 let text = textarea.value; | |
112 textarea.value = ''; | |
113 let postData = 'root=<%=root_id%>&text=' + encodeURIComponent(text); | |
114 ajax('new_post.js',postData); | |
115 } | |
116 function added(postId,html,thread_size) { | |
117 if( document.querySelector('[post="'+postId+'"]') ) | |
118 return; | |
119 let newDiv = document.querySelector('[post="new"]'); | |
120 newDiv.insertAdjacentHTML('beforebegin',html); | |
121 document.body.setAttribute('thread_size',thread_size); | |
122 } | |
16 | 123 |
35 | 124 function uploaded(input,url,filename) { |
125 let postDiv = getPostDiv(input); | |
126 let textarea = postDiv.querySelector('textarea'); | |
127 textarea.focus(); | |
128 textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select'); | |
32 | 129 } |
130 | |
16 | 131 function deletePost(span) { |
132 span.innerHTML = document.querySelector('[hidden][delete]').innerHTML; | |
133 } | |
134 function deleteNo(span) { | |
135 span.innerHTML = document.querySelector('[hidden][undelete]').innerHTML; | |
136 } | |
137 function deleteYes(span) { | |
19 | 138 let post = getPostDiv(span).getAttribute('post'); |
16 | 139 ajax( '/delete.js?post=' + post ); |
140 } | |
42 | 141 function deleted(postId,thread_size) { |
46 | 142 if( thread_size === 0 ) { |
143 location = '/'; | |
144 return; | |
145 } | |
42 | 146 let postDiv = document.querySelector('[post="'+postId+'"]'); |
147 if(!postDiv) | |
148 return | |
149 postDiv.outerHTML = ''; | |
150 document.body.setAttribute('thread_size',thread_size); | |
151 } | |
18 | 152 |
153 function init() { | |
154 let spans = document.querySelectorAll('span[ago]'); | |
155 for( let i=0; i<spans.length; i++ ) { | |
156 let span = spans[i]; | |
157 let date = span.getAttribute('date'); | |
158 date = parseInt(date); | |
159 span.title = new Date(date).toLocaleString(); | |
160 } | |
161 } | |
42 | 162 |
163 let eventSource = new EventSource(location.href); | |
164 eventSource.onmessage = function(event) { | |
165 eval( event.data ); | |
166 }; | |
15 | 167 </script> |
9 | 168 </head> |
42 | 169 <body onload="init()" thread_size="<%=Post.thread_size(root_id)%>"> |
9 | 170 <% header() %> |
171 <div content> | |
172 <h1><%=subject_html%></h1> | |
16 | 173 <% for _, post in ipairs(posts) do |
42 | 174 show_post(post,now) |
175 end %> | |
176 <div post=new logged_in> | |
177 <hr> | |
46 | 178 <div editor></div> |
15 | 179 </div> |
9 | 180 </div> |
181 <% footer() %> | |
42 | 182 |
16 | 183 <span hidden delete>Delete? <a href="javascript:" onclick="deleteYes(parentNode)">yes</a> / <a href="javascript:" onclick="deleteNo(parentNode)">no</a></span> |
42 | 184 <span hidden undelete><%delete_post()%></span> |
9 | 185 </body> |
46 | 186 <script> |
187 bbcodeCreate('div[post="new"] div[editor]',{ | |
188 save: newPost | |
189 }); | |
190 </script> | |
9 | 191 </html> |
192 <% | |
193 end |