Mercurial Hosting > freedit
annotate src/thread.html.luan @ 61:389e5d8e5f8a default tip
minor
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Tue, 06 Dec 2022 13:37:25 -0700 |
| parents | 8b5b1bce7d6b |
| children |
| 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 } | |
| 42 | 56 <% if user_name == nil then %> |
| 57 [logged_in] { | |
| 58 display: none; | |
| 59 } | |
| 60 <% end %> | |
| 61 [only_user] { | |
| 62 display: none; | |
|
25
66fd3784e60e
back to textarea for bbcode
Franklin Schmidt <fschmidt@gmail.com>
parents:
21
diff
changeset
|
63 } |
| 42 | 64 <% if user_name ~= nil then %> |
| 65 [only_user="<%=html_encode(user_name)%>"] { | |
| 66 display: initial; | |
| 67 } | |
| 68 <% end %> | |
| 69 div[post]:first-of-type [delete_opton] { | |
| 70 display: none; | |
| 71 } | |
| 72 body[thread_size="1"] div[post]:first-of-type [delete_opton] { | |
| 73 display: initial; | |
| 74 } | |
| 75 </style> | |
| 15 | 76 <script> |
| 19 | 77 function getPostDiv(node) { |
| 78 do { | |
| 79 if( node.getAttribute('post') ) | |
| 80 return node; | |
| 81 } while( node = node.parentNode ); | |
| 82 } | |
| 83 | |
| 46 | 84 function cancelEdit(event) { |
| 85 let postDiv = getPostDiv(event.target); | |
| 15 | 86 postDiv.querySelector('[output]').style.display = 'block'; |
| 87 postDiv.querySelector('[edit]').innerHTML = ''; | |
| 88 } | |
| 46 | 89 function saveEdit(event) { |
| 90 let postDiv = getPostDiv(event.target); | |
| 19 | 91 let post = postDiv.getAttribute('post'); |
|
25
66fd3784e60e
back to textarea for bbcode
Franklin Schmidt <fschmidt@gmail.com>
parents:
21
diff
changeset
|
92 let text = postDiv.querySelector('textarea').value; |
| 46 | 93 cancelEdit(event); |
| 52 | 94 let postData = 'post=' + post + '&text=' + encodeURIComponent(text) + '&convert_urls=' + event.convertUrls; |
| 34 | 95 ajax('save_edit.js',postData); |
| 15 | 96 } |
| 42 | 97 function updated(postId,html) { |
| 98 let postDiv = document.querySelector('[post="'+postId+'"]'); | |
| 99 if(postDiv) | |
| 49 | 100 postDiv.querySelector('[from_bbcode]').outerHTML = html; |
| 42 | 101 } |
| 102 | |
| 103 function newPost() { | |
| 104 let postDiv = document.querySelector('[post="new"]'); | |
| 105 let textarea = postDiv.querySelector('textarea') | |
| 106 let text = textarea.value; | |
| 107 textarea.value = ''; | |
| 52 | 108 let postData = 'root=<%=root_id%>&text=' + encodeURIComponent(text) + '&convert_urls=' + event.convertUrls; |
| 42 | 109 ajax('new_post.js',postData); |
| 110 } | |
| 111 function added(postId,html,thread_size) { | |
| 112 if( document.querySelector('[post="'+postId+'"]') ) | |
| 113 return; | |
| 114 let newDiv = document.querySelector('[post="new"]'); | |
| 115 newDiv.insertAdjacentHTML('beforebegin',html); | |
| 116 document.body.setAttribute('thread_size',thread_size); | |
| 117 } | |
| 16 | 118 |
| 35 | 119 function uploaded(input,url,filename) { |
| 120 let postDiv = getPostDiv(input); | |
| 121 let textarea = postDiv.querySelector('textarea'); | |
| 122 textarea.focus(); | |
| 123 textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select'); | |
| 32 | 124 } |
| 125 | |
| 16 | 126 function deletePost(span) { |
| 127 span.innerHTML = document.querySelector('[hidden][delete]').innerHTML; | |
| 128 } | |
| 129 function deleteNo(span) { | |
| 130 span.innerHTML = document.querySelector('[hidden][undelete]').innerHTML; | |
| 131 } | |
| 132 function deleteYes(span) { | |
| 19 | 133 let post = getPostDiv(span).getAttribute('post'); |
| 16 | 134 ajax( '/delete.js?post=' + post ); |
| 135 } | |
| 42 | 136 function deleted(postId,thread_size) { |
| 46 | 137 if( thread_size === 0 ) { |
| 138 location = '/'; | |
| 139 return; | |
| 140 } | |
| 42 | 141 let postDiv = document.querySelector('[post="'+postId+'"]'); |
| 142 if(!postDiv) | |
| 143 return | |
| 144 postDiv.outerHTML = ''; | |
| 145 document.body.setAttribute('thread_size',thread_size); | |
| 146 } | |
| 18 | 147 |
| 148 function init() { | |
| 149 let spans = document.querySelectorAll('span[ago]'); | |
| 150 for( let i=0; i<spans.length; i++ ) { | |
| 151 let span = spans[i]; | |
| 152 let date = span.getAttribute('date'); | |
| 153 date = parseInt(date); | |
| 154 span.title = new Date(date).toLocaleString(); | |
| 155 } | |
| 156 } | |
| 42 | 157 |
| 158 let eventSource = new EventSource(location.href); | |
| 159 eventSource.onmessage = function(event) { | |
| 160 eval( event.data ); | |
| 161 }; | |
| 15 | 162 </script> |
| 9 | 163 </head> |
| 42 | 164 <body onload="init()" thread_size="<%=Post.thread_size(root_id)%>"> |
| 9 | 165 <% header() %> |
| 166 <div content> | |
| 167 <h1><%=subject_html%></h1> | |
| 16 | 168 <% for _, post in ipairs(posts) do |
| 42 | 169 show_post(post,now) |
| 170 end %> | |
| 171 <div post=new logged_in> | |
| 172 <hr> | |
| 46 | 173 <div editor></div> |
| 15 | 174 </div> |
| 9 | 175 </div> |
| 176 <% footer() %> | |
| 42 | 177 |
| 16 | 178 <span hidden delete>Delete? <a href="javascript:" onclick="deleteYes(parentNode)">yes</a> / <a href="javascript:" onclick="deleteNo(parentNode)">no</a></span> |
| 42 | 179 <span hidden undelete><%delete_post()%></span> |
| 9 | 180 </body> |
| 46 | 181 <script> |
| 60 | 182 bbcodeCreate('div[post="new"] div[editor]',{buttons:{ |
| 183 Save: newPost | |
| 184 }}); | |
| 46 | 185 </script> |
| 9 | 186 </html> |
| 187 <% | |
| 188 end |
