Mercurial Hosting > freedit
comparison src/thread.html.luan @ 42:0c1b820fff34
use push
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Tue, 08 Nov 2022 14:02:28 -0700 |
parents | 1ce75c5ab0f7 |
children | 96f0c3d65698 |
comparison
equal
deleted
inserted
replaced
41:acb730710328 | 42:0c1b820fff34 |
---|---|
1 local Luan = require "luan:Luan.luan" | 1 local Luan = require "luan:Luan.luan" |
2 local error = Luan.error | 2 local error = Luan.error |
3 local ipairs = Luan.ipairs or error() | 3 local ipairs = Luan.ipairs or error() |
4 local Time = require "luan:Time.luan" | 4 local Time = require "luan:Time.luan" |
5 local time_now = Time.now or error() | 5 local time_now = Time.now or error() |
6 local Html = require "luan:Html.luan" | |
7 local html_encode = Html.encode or error() | |
6 local Io = require "luan:Io.luan" | 8 local Io = require "luan:Io.luan" |
7 local Http = require "luan:http/Http.luan" | 9 local Http = require "luan:http/Http.luan" |
8 local Shared = require "site:/lib/Shared.luan" | 10 local Shared = require "site:/lib/Shared.luan" |
9 local head = Shared.head or error() | 11 local head = Shared.head or error() |
10 local header = Shared.header or error() | 12 local header = Shared.header or error() |
11 local footer = Shared.footer or error() | 13 local footer = Shared.footer or error() |
14 local delete_post = Shared.delete_post or error() | |
15 local show_post = Shared.show_post or error() | |
12 local Forum = require "site:/lib/Forum.luan" | 16 local Forum = require "site:/lib/Forum.luan" |
13 local forum_title = Forum.title or error() | 17 local forum_title = Forum.title or error() |
14 local Db = require "site:/lib/Db.luan" | 18 local Db = require "site:/lib/Db.luan" |
15 local Post = require "site:/lib/Post.luan" | 19 local Post = require "site:/lib/Post.luan" |
16 local Bbcode = require "site:/lib/Bbcode.luan" | 20 local Bbcode = require "site:/lib/Bbcode.luan" |
17 local bbcode_to_html = Bbcode.to_html or error() | 21 local bbcode_to_html = Bbcode.to_html or error() |
18 local User = require "site:/lib/User.luan" | 22 local User = require "site:/lib/User.luan" |
19 | 23 |
20 | |
21 local function deletePost() | |
22 %><a href="javascript:" onclick="deletePost(parentNode)">delete</a><% | |
23 end | |
24 | 24 |
25 return function() | 25 return function() |
26 local root_id = Http.request.parameters.root or error() | 26 local root_id = Http.request.parameters.root or error() |
27 local docs, total_hits = Db.search("post_root_id:"..root_id,1,1000,{sort="id"}) | 27 local docs, total_hits = Db.search("post_root_id:"..root_id,1,1000,{sort="id"}) |
28 local posts = Post.from_docs(docs) | 28 local posts = Post.from_docs(docs) |
58 line-height: 1.4; | 58 line-height: 1.4; |
59 } | 59 } |
60 textarea { | 60 textarea { |
61 width: 100%; | 61 width: 100%; |
62 xmax-width: 450px; | 62 xmax-width: 450px; |
63 height: 100px; | 63 xheight: 100px; |
64 } | 64 } |
65 </style> | 65 <% if user_name == nil then %> |
66 [logged_in] { | |
67 display: none; | |
68 } | |
69 <% end %> | |
70 [only_user] { | |
71 display: none; | |
72 } | |
73 <% if user_name ~= nil then %> | |
74 [only_user="<%=html_encode(user_name)%>"] { | |
75 display: initial; | |
76 } | |
77 <% end %> | |
78 div[post]:first-of-type [delete_opton] { | |
79 display: none; | |
80 } | |
81 body[thread_size="1"] div[post]:first-of-type [delete_opton] { | |
82 display: initial; | |
83 } | |
84 </style> | |
66 <script> | 85 <script> |
67 function getPostDiv(node) { | 86 function getPostDiv(node) { |
68 do { | 87 do { |
69 if( node.getAttribute('post') ) | 88 if( node.getAttribute('post') ) |
70 return node; | 89 return node; |
78 } | 97 } |
79 function saveEdit(src) { | 98 function saveEdit(src) { |
80 let postDiv = getPostDiv(src); | 99 let postDiv = getPostDiv(src); |
81 let post = postDiv.getAttribute('post'); | 100 let post = postDiv.getAttribute('post'); |
82 let text = postDiv.querySelector('textarea').value; | 101 let text = postDiv.querySelector('textarea').value; |
102 cancelEdit(src); | |
83 let postData = 'post=' + post + '&text=' + encodeURIComponent(text); | 103 let postData = 'post=' + post + '&text=' + encodeURIComponent(text); |
84 ajax('save_edit.js',postData); | 104 ajax('save_edit.js',postData); |
105 } | |
106 function updated(postId,html) { | |
107 let postDiv = document.querySelector('[post="'+postId+'"]'); | |
108 if(postDiv) | |
109 postDiv.querySelector('[message]').innerHTML = html; | |
110 } | |
111 | |
112 function newPost() { | |
113 let postDiv = document.querySelector('[post="new"]'); | |
114 let textarea = postDiv.querySelector('textarea') | |
115 let text = textarea.value; | |
116 textarea.value = ''; | |
117 let postData = 'root=<%=root_id%>&text=' + encodeURIComponent(text); | |
118 ajax('new_post.js',postData); | |
119 } | |
120 function added(postId,html,thread_size) { | |
121 if( document.querySelector('[post="'+postId+'"]') ) | |
122 return; | |
123 let newDiv = document.querySelector('[post="new"]'); | |
124 newDiv.insertAdjacentHTML('beforebegin',html); | |
125 document.body.setAttribute('thread_size',thread_size); | |
85 } | 126 } |
86 | 127 |
87 function uploaded(input,url,filename) { | 128 function uploaded(input,url,filename) { |
88 let postDiv = getPostDiv(input); | 129 let postDiv = getPostDiv(input); |
89 let textarea = postDiv.querySelector('textarea'); | 130 let textarea = postDiv.querySelector('textarea'); |
98 span.innerHTML = document.querySelector('[hidden][undelete]').innerHTML; | 139 span.innerHTML = document.querySelector('[hidden][undelete]').innerHTML; |
99 } | 140 } |
100 function deleteYes(span) { | 141 function deleteYes(span) { |
101 let post = getPostDiv(span).getAttribute('post'); | 142 let post = getPostDiv(span).getAttribute('post'); |
102 ajax( '/delete.js?post=' + post ); | 143 ajax( '/delete.js?post=' + post ); |
144 } | |
145 function deleted(postId,thread_size) { | |
146 let postDiv = document.querySelector('[post="'+postId+'"]'); | |
147 if(!postDiv) | |
148 return | |
149 postDiv.outerHTML = ''; | |
150 document.body.setAttribute('thread_size',thread_size); | |
103 } | 151 } |
104 | 152 |
105 function init() { | 153 function init() { |
106 let spans = document.querySelectorAll('span[ago]'); | 154 let spans = document.querySelectorAll('span[ago]'); |
107 for( let i=0; i<spans.length; i++ ) { | 155 for( let i=0; i<spans.length; i++ ) { |
109 let date = span.getAttribute('date'); | 157 let date = span.getAttribute('date'); |
110 date = parseInt(date); | 158 date = parseInt(date); |
111 span.title = new Date(date).toLocaleString(); | 159 span.title = new Date(date).toLocaleString(); |
112 } | 160 } |
113 } | 161 } |
162 | |
163 let eventSource = new EventSource(location.href); | |
164 eventSource.onmessage = function(event) { | |
165 eval( event.data ); | |
166 }; | |
114 </script> | 167 </script> |
115 </head> | 168 </head> |
116 <body onload="init()"> | 169 <body onload="init()" thread_size="<%=Post.thread_size(root_id)%>"> |
117 <% header() %> | 170 <% header() %> |
118 <div content> | 171 <div content> |
119 <h1><%=subject_html%></h1> | 172 <h1><%=subject_html%></h1> |
120 <% for _, post in ipairs(posts) do | 173 <% for _, post in ipairs(posts) do |
121 if post.is_deleted then | 174 show_post(post,now) |
122 continue | 175 end %> |
123 end | 176 <div post=new logged_in> |
124 %> | 177 <hr> |
125 <hr> | 178 <textarea oninput="fixTextarea(this)"></textarea> |
126 <div post="<%=post.id%>"> | 179 <p> |
127 <div author> | 180 <input type=file onchange="upload(this,uploaded)"> |
128 <img src="/images/profile.png"> | 181 <button onclick="fileButtonClick(this)">Upload File</button> |
129 <a href="/whatever"><%= post.author_name %></a> | 182 <button onclick="newPost()">save</button> |
130 <span ago date="<%=post.date%>"><% post.ago(now) %> ago</span> | 183 </p> |
131 </div> | |
132 <div output> | |
133 <% bbcode_to_html(post.content) %> | |
134 <p> | |
135 <a href="/reply.html?parent=<%=post.id%>">reply</a> | |
136 <% if post.author_name == user_name then %> | |
137 - <a href="javascript:ajax('/edit.js?post=<%=post.id%>')">edit</a> | |
138 - <span delete><%deletePost()%></span> | |
139 <% end %> | |
140 </p> | |
141 </div> | |
142 <div edit></div> | |
143 </div> | 184 </div> |
144 <% end %> | |
145 </div> | 185 </div> |
146 <% footer() %> | 186 <% footer() %> |
187 | |
147 <span hidden delete>Delete? <a href="javascript:" onclick="deleteYes(parentNode)">yes</a> / <a href="javascript:" onclick="deleteNo(parentNode)">no</a></span> | 188 <span hidden delete>Delete? <a href="javascript:" onclick="deleteYes(parentNode)">yes</a> / <a href="javascript:" onclick="deleteNo(parentNode)">no</a></span> |
148 <span hidden undelete><%deletePost()%></span> | 189 <span hidden undelete><%delete_post()%></span> |
149 <div hidden edit> | 190 <div hidden edit> |
150 <textarea></textarea> | 191 <textarea oninput="fixTextarea(this)"></textarea> |
151 <p> | 192 <p> |
152 <input type=file onchange="upload(this,uploaded)"> | 193 <input type=file onchange="upload(this,uploaded)"> |
153 <button onclick="fileButtonClick(this)">Upload File</button> | 194 <button onclick="fileButtonClick(this)">Upload File</button> |
154 <button onclick="saveEdit(this)">save</button> | 195 <button onclick="saveEdit(this)">save</button> |
155 <button onclick="cancelEdit(this)">cancel</button> | 196 <button onclick="cancelEdit(this)">cancel</button> |