experiment with ajax load for topic

track route perf for BadRoute
This commit is contained in:
Azareal 2020-03-11 13:26:33 +10:00
parent bba83ef727
commit d43bffdec5
26 changed files with 462 additions and 399 deletions

View File

@ -249,7 +249,9 @@ func compileCommons(c *tmpl.CTemplateSet, head, head2 *Header, forumList []Forum
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
o.Add("topic", "c.TopicPage", tpage)
o.Add("topic_mini", "c.TopicPage", tpage)
o.Add("topic_alt", "c.TopicPage", tpage)
o.Add("topic_alt_mini", "c.TopicPage", tpage)
return nil
}

View File

@ -2787,7 +2787,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} else {
r.DumpRequest(req,"Bad Route")
}
co.RouteViewCounter.Bump(172)
co.RouteViewCounter.Bump3(172, cn)
return c.NotFound(w,req,nil)
}
return err

View File

@ -28,7 +28,7 @@ function ajaxError(xhr,status,errstr) {
console.log("The AJAX request failed");
console.log("xhr", xhr);
console.log("status", status);
console.log("errstr", errstr);
console.log("err", errstr);
if(status=="parsererror") console.log("The server didn't respond with a valid JSON response");
console.trace();
}
@ -135,8 +135,8 @@ function loadAlerts(menuAlerts, eTc = false) {
let tc = "";
if(eTc && lastTc != 0) tc = "&t=" + lastTc + "&c=" + alertCount;
$.ajax({
type: 'get',
dataType: 'json',
type:'get',
dataType:'json',
url:'/api/?m=alerts' + tc,
success: (data) => {
if("errmsg" in data) {
@ -460,9 +460,9 @@ function mainInit(){
if("success" in data && data["success"] == "1") return;
// addNotice("Failed to add a like: {err}")
//likeCountNode.innerHTML = parseInt(likeCountNode.innerHTML)-1;
console.log("data", data);
console.log("status", status);
console.log("xhr", xhr);
console.log("data",data);
console.log("status",status);
console.log("xhr",xhr);
}
});
});
@ -620,110 +620,7 @@ function mainInit(){
});
});
$(".open_edit").click(ev => {
ev.preventDefault();
$('.hide_on_edit').addClass("edit_opened");
$('.show_on_edit').addClass("edit_opened");
runHook("open_edit");
});
$(".topic_item .submit_edit").click(function(ev){
ev.preventDefault();
let topicNameInput = $(".topic_name_input").val();
$(".topic_name").html(topicNameInput);
$(".topic_name").attr(topicNameInput);
let topicContentInput = $('.topic_content_input').val();
$(".topic_content").html(quickParse(topicContentInput));
let topicStatusInput = $('.topic_status_input').val();
$(".topic_status_e:not(.open_edit)").html(topicStatusInput);
$('.hide_on_edit').removeClass("edit_opened");
$('.show_on_edit').removeClass("edit_opened");
runHook("close_edit");
$.ajax({
url: this.form.getAttribute("action"),
type: "POST",
dataType: "json",
data: {
topic_name: topicNameInput,
topic_status: topicStatusInput,
topic_content: topicContentInput,
js: 1
},
error: ajaxError,
success: (data,status,xhr) => {
if("Content" in data) $(".topic_content").html(data["Content"]);
}
});
});
$(".delete_item").click(function(ev) {
postLink(ev);
$(this).closest('.deletable_block').remove();
});
// Miniature implementation of the parser to avoid sending as much data back and forth
function quickParse(m) {
m = m.replace(":)", "😀")
m = m.replace(":(", "😞")
m = m.replace(":D", "😃")
m = m.replace(":P", "😛")
m = m.replace(":O", "😲")
m = m.replace(":p", "😛")
m = m.replace(":o", "😲")
m = m.replace(";)", "😉")
m = m.replace("\n","<br>")
return m
}
$(".edit_item").click(function(ev){
ev.preventDefault();
let bp = this.closest('.editable_parent');
$(bp).find('.hide_on_edit').addClass("edit_opened");
$(bp).find('.show_on_edit').addClass("edit_opened");
$(bp).find('.hide_on_block_edit').addClass("edit_opened");
$(bp).find('.show_on_block_edit').addClass("edit_opened");
let srcNode = bp.querySelector(".edit_source");
let block = bp.querySelector('.editable_block');
block.classList.add("in_edit");
let source = "";
if(srcNode!=null) source = srcNode.innerText;
else source = block.innerHTML;
block.innerHTML = Template_topic_c_edit_post({
ID: bp.getAttribute("id").slice("post-".length),
Source: source,
Ref: this.closest('a').getAttribute("href")
})
runHook("edit_item_pre_bind");
$(".submit_edit").click(function(ev){
ev.preventDefault();
$(bp).find('.hide_on_edit').removeClass("edit_opened");
$(bp).find('.show_on_edit').removeClass("edit_opened");
$(bp).find('.hide_on_block_edit').removeClass("edit_opened");
$(bp).find('.show_on_block_edit').removeClass("edit_opened");
block.classList.remove("in_edit");
let content = block.querySelector('textarea').value;
block.innerHTML = quickParse(content);
if(srcNode!=null) srcNode.innerText = content;
let formAction = this.closest('a').getAttribute("href");
// TODO: Bounce the parsed post back and set innerHTML to it?
$.ajax({
url: formAction,
type: "POST",
dataType: "json",
data: { js: 1, edit_item: content },
error: ajaxError,
success: (data,status,xhr) => {
if("Content" in data) block.innerHTML = data["Content"];
}
});
});
});
bindTopic();
$(".edit_field").click(function(ev) {
ev.preventDefault();
@ -963,6 +860,149 @@ function mainInit(){
})
});
$(".rowtopic a, a.rowtopic").click(function(ev) {
let base = this.getAttribute("href");
let href = base + "?i=1";
fetch(href, {credentials:"same-origin"})
.then(resp => {
if(!resp.ok) throw(href+" failed to load");
return resp.text();
}).then(data => {
let el = document.createElement("div");
el.innerHTML = data;
console.log("el",el);
document.querySelector("main").outerHTML = el.children[0].innerHTML;
//$(".sidebar").html(el.children[1]);
document.querySelector(".sidebar").outerHTML = el.children[1].outerHTML;
unbindTopic();
bindTopic();
let obj = {Title: document.title, Url: base};
history.pushState(obj, obj.Title, obj.Url);
}).catch(ex => {
console.log("Unable to get script '"+href+""+"'");
console.log("ex",ex);
console.trace();
});
ev.stopPropagation();
ev.preventDefault();
})
runInitHook("almost_end_init");
runInitHook("end_init");
}
function bindTopic() {
$(".open_edit").click(ev => {
ev.preventDefault();
$('.hide_on_edit').addClass("edit_opened");
$('.show_on_edit').addClass("edit_opened");
runHook("open_edit");
});
$(".topic_item .submit_edit").click(function(ev){
ev.preventDefault();
let nameInput = $(".topic_name_input").val();
$(".topic_name").html(nameInput);
$(".topic_name").attr(nameInput);
let contentInput = $('.topic_content_input').val();
$(".topic_content").html(quickParse(contentInput));
let statusInput = $('.topic_status_input').val();
$(".topic_status_e:not(.open_edit)").html(statusInput);
$('.hide_on_edit').removeClass("edit_opened");
$('.show_on_edit').removeClass("edit_opened");
runHook("close_edit");
$.ajax({
url: this.form.getAttribute("action"),
type: "POST",
dataType: "json",
data: {
name: nameInput,
status: statusInput,
content: contentInput,
js: 1
},
error: ajaxError,
success: (data,status,xhr) => {
if("Content" in data) $(".topic_content").html(data["Content"]);
}
});
});
$(".delete_item").click(function(ev) {
postLink(ev);
$(this).closest('.deletable_block').remove();
});
// Miniature implementation of the parser to avoid sending as much data back and forth
function quickParse(m) {
m = m.replace(":)", "😀")
m = m.replace(":(", "😞")
m = m.replace(":D", "😃")
m = m.replace(":P", "😛")
m = m.replace(":O", "😲")
m = m.replace(":p", "😛")
m = m.replace(":o", "😲")
m = m.replace(";)", "😉")
m = m.replace("\n","<br>")
return m
}
$(".edit_item").click(function(ev){
ev.preventDefault();
let bp = this.closest('.editable_parent');
$(bp).find('.hide_on_edit').addClass("edit_opened");
$(bp).find('.show_on_edit').addClass("edit_opened");
$(bp).find('.hide_on_block_edit').addClass("edit_opened");
$(bp).find('.show_on_block_edit').addClass("edit_opened");
let srcNode = bp.querySelector(".edit_source");
let block = bp.querySelector('.editable_block');
block.classList.add("in_edit");
let src = "";
if(srcNode!=null) src = srcNode.innerText;
else src = block.innerHTML;
block.innerHTML = Template_topic_c_edit_post({
ID: bp.getAttribute("id").slice("post-".length),
Source: src,
Ref: this.closest('a').getAttribute("href")
})
runHook("edit_item_pre_bind");
$(".submit_edit").click(function(ev){
ev.preventDefault();
$(bp).find('.hide_on_edit').removeClass("edit_opened");
$(bp).find('.show_on_edit').removeClass("edit_opened");
$(bp).find('.hide_on_block_edit').removeClass("edit_opened");
$(bp).find('.show_on_block_edit').removeClass("edit_opened");
block.classList.remove("in_edit");
let content = block.querySelector('textarea').value;
block.innerHTML = quickParse(content);
if(srcNode!=null) srcNode.innerText = content;
let formAction = this.closest('a').getAttribute("href");
// TODO: Bounce the parsed post back and set innerHTML to it?
$.ajax({
url: formAction,
type:"POST",
dataType:"json",
data: { js: 1, edit_item: content },
error: ajaxError,
success: (data,status,xhr) => {
if("Content" in data) block.innerHTML = data["Content"];
}
});
});
});
}
function unbindTopic() {
$(".open_edit").unbind("click");
$(".topic_item .submit_edit").unbind("click");
$(".delete_item").unbind("click");
$(".edit_item").unbind("click");
$(".submit_edit").unbind("click");
}

View File

@ -3,8 +3,8 @@
fetch("/api/watches/")
.then(resp => {
if(resp.status!==200) {
console.log("error");
console.log("resp:", resp);
console.log("err");
console.log("resp",resp);
return;
}
resp.text().then(data => eval(data));

View File

@ -348,7 +348,7 @@ func main() {
"Googlebot": "googlebot",
"yandex": "yandex", // from the URL
"DuckDuckBot": "duckduckgo",
"DuckDuckGo":"duckduckgo",
"DuckDuckGo": "duckduckgo",
"Baiduspider": "baidu",
"Sogou": "sogou",
"ToutiaoSpider": "toutiao",
@ -980,7 +980,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} else {
r.DumpRequest(req,"Bad Route")
}
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.BadRoute"}})
co.RouteViewCounter.Bump3({{index .AllRouteMap "routes.BadRoute"}}, cn)
return c.NotFound(w,req,nil)
}
return err

View File

@ -165,13 +165,25 @@ func ViewTopic(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
var rerr c.RouteError
tmpl := forum.Tmpl
if tmpl == "" {
rerr = renderTemplate("topic", w, r, header, tpage)
if r.FormValue("i") == "1" {
if tmpl == "" {
rerr = renderTemplate("topic_mini", w, r, header, tpage)
} else {
tmpl = "topic_mini" + tmpl
err = renderTemplate3(tmpl, tmpl, w, r, header, tpage)
if err != nil {
rerr = renderTemplate("topic_mini", w, r, header, tpage)
}
}
} else {
tmpl = "topic_" + tmpl
err = renderTemplate3(tmpl, tmpl, w, r, header, tpage)
if err != nil {
if tmpl == "" {
rerr = renderTemplate("topic", w, r, header, tpage)
} else {
tmpl = "topic_" + tmpl
err = renderTemplate3(tmpl, tmpl, w, r, header, tpage)
if err != nil {
rerr = renderTemplate("topic", w, r, header, tpage)
}
}
}
counters.TopicViewCounter.Bump(topic.ID) // TODO: Move this into the router?
@ -576,7 +588,7 @@ func EditTopicSubmit(w http.ResponseWriter, r *http.Request, user c.User, stid s
return c.NoPermissionsJSQ(w, r, user, js)
}
err = topic.Update(r.PostFormValue("topic_name"), r.PostFormValue("topic_content"))
err = topic.Update(r.PostFormValue("name"), r.PostFormValue("content"))
// TODO: Avoid duplicating this across this route and the topic creation route
if err != nil {
switch err {

View File

@ -1,10 +1,11 @@
{{template "header.html" . }}
<main id="forumItemList" itemscope itemtype="http://schema.org/ItemList">
{{if gt .Page 1}}<div id="prevFloat" class="prev_button"><a class="prev_link" aria-label="{{lang "paginator.prev_page_aria"}}" rel="prev" href="{{.Forum.Link}}?page={{subtract .Page 1}}">{{lang "paginator.less_than"}}</a></div>{{end}}
{{if ne .LastPage .Page}}<div id="nextFloat" class="next_button"><a class="next_link" aria-label="{{lang "paginator.next_page_aria"}}" rel="next" href="{{.Forum.Link}}?page={{add .Page 1}}">{{lang "paginator.greater_than"}}</a></div>{{end}}
<link rel="canonical" href="//{{.Site.URL}}{{.Forum.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<main id="forumItemList" itemscope itemtype="http://schema.org/ItemList">
<div id="forum_head_block" class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
<div class="rowitem forum_title">
<h1 itemprop="name">{{.Title}}</h1>
@ -59,7 +60,7 @@
</span>
{{/** TODO: Phase this out of Cosora and remove it **/}}
<div class="topic_inner_right rowsmall">
<span class="replyCount">{{.PostCount}}</span><br />
<span class="replyCount">{{.PostCount}}</span><br>
<span class="likeCount">{{.LikeCount}}</span>
</div>
</div>
@ -72,7 +73,7 @@
</div>
<div class="rowitem topic_right passive datarow">
<div class="topic_right_inside">
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}" height=64 alt="Avatar" title="{{.LastUser.Name}}'s Avatar" aria-hidden="true"/></a>
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}" height=64 alt="Avatar"title="{{.LastUser.Name}}'s Avatar"aria-hidden="true"/></a>
<span>
<a href="{{.LastUser.Link}}" class="lastName" title="{{.LastUser.Name}}">{{.LastUser.Name}}</a><br>
<a href="{{.Link}}?page={{.LastPage}}{{if .LastReplyID}}#post-{{.LastReplyID}}{{end}}" class="rowsmall lastReplyAt" title="{{abstime .LastReplyAt}}">{{reltime .LastReplyAt}}</a>

View File

@ -1,8 +1,7 @@
{{template "header.html" . }}
<main id="forumItemList" itemscope itemtype="http://schema.org/ItemList">
<link rel="canonical" href="//{{.Site.URL}}{{.Forum.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<main id="forumItemList" itemscope itemtype="http://schema.org/ItemList">
<div id="forum_head_block" class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
<div class="rowitem forum_title">
<h1 itemprop="name">{{.Title}}</h1>
@ -18,8 +17,7 @@
<a class="moderate_link" href="#" aria-label="{{lang "topic_list.moderate_aria"}}"></a>
</div>
{{else}}<div class="opt locked_opt" title="{{lang "forum_locked_tooltip"}}" aria-label="{{lang "forum_locked_aria"}}"><a></a></div>{{end}}
</div>
<div style="clear:both;"></div>
</div><div style="clear:both;"></div>
{{end}}
</div>
{{if .CurrentUser.Loggedin}}
@ -47,7 +45,7 @@
{{range .ItemList}}<div class="rowitem" data-tid="{{.ID}}">
<div>
<a class="rowtopic" href="{{.Link}}" itemprop="itemListElement"><img src="{{.Content}}" style="width:100%;height:160px;"/></a>
<br /><a class="rowsmall starter" href="{{.Link}}">{{.Title}}</a>
<br><a class="rowsmall starter" href="{{.Link}}">{{.Title}}</a>
</div>
<!--<div class="topic_left passive datarow">
<a href="{{.Creator.Link}}"><img src="{{.Creator.MicroAvatar}}" height=64 alt="Avatar" title="{{.Creator.Name}}'s Avatar" aria-hidden="true"/></a>

View File

@ -1,113 +1,3 @@
{{template "header.html" . }}
{{if gt .Page 1}}<link rel="prev" href="{{.Topic.Link}}?page={{subtract .Page 1}}" />
<div id="prevFloat" class="prev_button"><a class="prev_link" aria-label="{{lang "paginator.prev_page_aria"}}" rel="prev" href="{{.Topic.Link}}?page={{subtract .Page 1}}">{{lang "paginator.less_than"}}</a></div>{{end}}
{{if ne .LastPage .Page}}<link rel="prerender next" href="{{.Topic.Link}}?page={{add .Page 1}}" />
<div id="nextFloat" class="next_button">
<a class="next_link" aria-label="{{lang "paginator.next_page_aria"}}" rel="next" href="{{.Topic.Link}}?page={{add .Page 1}}">{{lang "paginator.greater_than"}}</a>
</div>{{end}}
<main id="topicPage">
<link rel="canonical" href="//{{.Site.URL}}{{.Topic.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}" />
<div {{scope "topic_title_block"}} class="rowblock rowhead topic_block" aria-label="{{lang "topic.topic_info_aria"}}">
<div class="rowitem topic_item{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.IsClosed}} topic_closed_head{{end}}">
<h1 class='topic_name hide_on_edit' title='{{.Topic.Title}}'>{{.Topic.Title}}</h1>
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}'>&#x1F512;&#xFE0E</span>{{end}}
{{/** TODO: Does this need to be guarded by a permission? It's only visible in edit mode anyway, which can't be triggered, if they don't have the permission **/}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}
<form id="edit_topic_form" action='/topic/edit/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' method="post"></form>
<input form='edit_topic_form' class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" aria-label="{{lang "topic.title_input_aria"}}" />
<button form='edit_topic_form' name="topic-button" class="formbutton show_on_edit submit_edit">{{lang "topic.update_button"}}</button>
{{end}}
{{end}}
</div>
</div>
{{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}),url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
<span class="controls{{if .Topic.LikeCount}} has_likes{{end}}" aria-label="{{lang "topic.post_controls_aria"}}">
<a href="{{.Topic.UserLink}}" class="username real_username" rel="author">{{.Topic.CreatedByName}}</a>&nbsp;&nbsp;
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.LikeItem}}{{if ne .CurrentUser.ID .Topic.CreatedBy}}
{{if .Topic.Liked}}
<a href="/topic/unlike/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.unlike_tooltip"}}" aria-label="{{lang "topic.unlike_aria"}}">
<button class="username like_label remove_like"></button></a>{{else}}
<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button" title="{{lang "topic.like_tooltip"}}" aria-label="{{lang "topic.like_aria"}}">
<button class="username like_label add_like"></button></a>{{end}}
{{end}}{{end}}
<a href="" class="mod_button quote_item" title="{{lang "topic.quote_tooltip"}}" aria-label="{{lang "topic.quote_aria"}}"><button class="username quote_label"></button></a>
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit" title="{{lang "topic.edit_tooltip"}}" aria-label="{{lang "topic.edit_aria"}}"><button class="username edit_label"></button></a>{{end}}
{{end}}
{{if .Topic.Deletable}}<a href='/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.delete_tooltip"}}" aria-label="{{lang "topic.delete_aria"}}"><button class="username delete_label"></button></a>{{end}}
{{if .CurrentUser.Perms.CloseTopic}}{{if .Topic.IsClosed}}<a class="mod_button" href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' title="{{lang "topic.unlock_tooltip"}}" aria-label="{{lang "topic.unlock_aria"}}"><button class="username unlock_label"></button></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.lock_tooltip"}}" aria-label="{{lang "topic.lock_aria"}}"><button class="username lock_label"></button></a>{{end}}{{end}}
{{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' title="{{lang "topic.unpin_tooltip"}}" aria-label="{{lang "topic.unpin_aria"}}"><button class="username unpin_label"></button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button" title="{{lang "topic.pin_tooltip"}}" aria-label="{{lang "topic.pin_aria"}}"><button class="username pin_label"></button></a>{{end}}{{end}}
{{if .CurrentUser.Perms.ViewIPs}}<a class="mod_button" href='/users/ips/?ip={{.Topic.IP}}' title="{{lang "topic.ip_tooltip"}}" aria-label="The poster's IP is {{.Topic.IP}}"><button class="username ip_label"></button></a>{{end}}
{{end}}
<a href="/report/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}&type=topic" class="mod_button report_item" title="{{lang "topic.flag_tooltip"}}" aria-label="{{lang "topic.flag_aria"}}" rel="nofollow"><button class="username flag_label"></button></a>
<a class="username hide_on_micro like_count" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="{{lang "topic.like_count_tooltip"}}"></a>
{{if .Topic.Tag}}<a class="username hide_on_micro user_tag">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level" aria-label="{{lang "topic.level_aria"}}" title="{{lang "topic.level_tooltip"}}">{{level .Topic.Level}}</a><a class="username hide_on_micro level_label" title="{{lang "topic.level_tooltip"}}"></a>{{end}}
</span>
</div>
</article>
{{template "topic_posts.html" . }}
{{if .CurrentUser.Perms.CreateReply}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
<form id="quick_post_form" enctype="multipart/form-data" action="/reply/create/?s={{.CurrentUser.Session}}" method="post"></form>
<input form="quick_post_form" name="tid" value='{{.Topic.ID}}' type="hidden" />
<input form="quick_post_form" id="has_poll_input" name="has_poll" value=0 type="hidden" />
<div class="formrow real_first_child">
<div class="formitem">
<textarea id="input_content" form="quick_post_form" name="content" placeholder="{{lang "topic.reply_content"}}" required></textarea>
</div>
</div>
<div class="formrow poll_content_row auto_hide">
<div class="formitem">
<div class="pollinput" data-pollinput=0>
<input type="checkbox" disabled />
<label class="pollinputlabel"></label>
<input form="quick_post_form" name="pollinputitem[0]" class="pollinputinput" type="text" placeholder="{{lang "topic.reply_add_poll_option_first"}}" />
</div>
</div>
</div>
<div class="formrow quick_button_row">
<div class="formitem">
<button form="quick_post_form" name="reply-button" class="formbutton">{{lang "topic.reply_button"}}</button>
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "topic.reply_add_poll_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" style="display:none;" />
<label for="upload_files" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
<div id="upload_file_dock"></div>{{end}}
</div>
</div>
</div>
{{end}}
{{end}}
</main>
{{template "topic_inner.html" . }}
{{template "footer.html" . }}

View File

@ -1,124 +1,3 @@
{{template "header.html" . }}
{{if gt .Page 1}}<link rel="prev" href="{{.Topic.Link}}?page={{subtract .Page 1}}"/>{{end}}
{{if ne .LastPage .Page}}<link rel="prerender next" href="{{.Topic.Link}}?page={{add .Page 1}}"/>{{end}}
<main id="topicPage">
<link rel="canonical" href="//{{.Site.URL}}{{.Topic.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}" />
<div {{scope "topic_title_block"}} class="rowblock rowhead topic_block" aria-label="{{lang "topic.topic_info_aria"}}">
<div class="rowitem topic_item{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.IsClosed}} topic_closed_head{{end}}">
<h1 class='topic_name hide_on_edit' title='{{.Topic.Title}}'>{{.Topic.Title}}</h1>
<span class="topic_name_forum_sep hide_on_edit"> - </span>
<a href="{{.Forum.Link}}" class="topic_forum hide_on_edit">{{.Forum.Name}}</a>
{{/** TODO: Does this need to be guarded by a permission? It's only visible in edit mode anyway, which can't be triggered, if they don't have the permission **/}}
{{if .CurrentUser.Loggedin}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}
<form id="edit_topic_form" action='/topic/edit/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' method="post"></form>
<input form="edit_topic_form" class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" aria-label="{{lang "topic.title_input_aria"}}"/>
<button form="edit_topic_form" name="topic-button" class="formbutton show_on_edit submit_edit">{{lang "topic.update_button"}}</button>
{{end}}
{{end}}
{{end}}
<span class="topic_view_count hide_on_edit">{{.Topic.ViewCount}}</span>
{{/** TODO: Inline this CSS **/}}
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}'>&#x1F512;&#xFE0E</span>{{end}}
</div>
</div>
<div class="rowblock post_container">
{{if .Poll.ID}}<form id="poll_{{.Poll.ID}}_form" action="/poll/vote/{{.Poll.ID}}?s={{.CurrentUser.Session}}" method="post"></form>
<article class="rowitem passive deletable_block editable_parent post_item poll_item top_post hide_on_edit">
{{/**{{template "topic_alt_userinfo.html" .Topic }}**/}}
<div id="poll_voter_{{.Poll.ID}}" class="content_container poll_voter">
<div class="topic_content user_content">
{{range .Poll.QuickOptions}}
<div class="poll_option">
<input form="poll_{{$.Poll.ID}}_form" id="poll_option_{{.ID}}" name="poll_option_input" type="checkbox" value="{{.ID}}" />
<label class="poll_option_label" for="poll_option_{{.ID}}"><div class="sel"></div></label>
<span id="poll_option_text_{{.ID}}" class="poll_option_text">{{.Value}}</span>
</div>
{{end}}
<div class="poll_buttons">
<button form="poll_{{.Poll.ID}}_form" class="poll_vote_button">{{lang "topic.poll_vote"}}</button>
<button class="poll_results_button" data-poll-id="{{.Poll.ID}}">{{lang "topic.poll_results"}}</button>
<a href="#"><button class="poll_cancel_button">{{lang "topic.poll_cancel"}}</button></a>
</div>
</div>
</div>
<div id="poll_results_{{.Poll.ID}}" class="content_container poll_results auto_hide">
<div class="topic_content user_content">
<div class="auto_hide poll_no_results">{{lang "topic.poll_no_results"}}</div>
</div>
</div>
</article>
{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item top_post{{if .Topic.Attachments}} has_attachs{{end}}" aria-label="{{lang "topic.opening_post_aria"}}">
{{template "topic_alt_userinfo.html" .Topic }}
<div class="content_container">
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>
{{if .CurrentUser.Perms.EditTopic}}
<div class="show_on_edit attach_edit_bay" type="topic" id="{{.Topic.ID}}">
{{range .Topic.Attachments}}
<div class="attach_item attach_item_item{{if .Image}} attach_image_holder{{end}}">
{{if .Image}}<img src="//{{$.Header.Site.URL}}/attachs/{{.Path}}?sid={{.SectionID}}&amp;stype=forums" height=24 width=24 />{{end}}
<span class="attach_item_path" aid="{{.ID}}" fullPath="//{{$.Header.Site.URL}}/attachs/{{.Path}}">{{.Path}}</span>
<button class="attach_item_select">{{lang "topic.select_button_text"}}</button>
<button class="attach_item_copy">{{lang "topic.copy_button_text"}}</button>
</div>
{{end}}
<div class="attach_item attach_item_buttons">
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" id="upload_files_op" multiple type="file" class="auto_hide" />
<label for="upload_files_op" class="formbutton add_file_button">{{lang "topic.upload_button_text"}}</label>{{end}}
<button class="attach_item_delete formbutton">{{lang "topic.delete_button_text"}}</button>
</div>
</div>
{{end}}{{end}}
<div class="controls button_container{{if .Topic.LikeCount}} has_likes{{end}}">
<div class="action_button_left">
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.LikeItem}}{{if ne .CurrentUser.ID .Topic.CreatedBy}}
{{if .Topic.Liked}}<a href="/topic/unlike/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button like_item remove_like" aria-label="{{lang "topic.unlike_aria"}}" data-action="unlike"></a>{{else}}<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button like_item add_like" aria-label="{{lang "topic.like_aria"}}" data-action="like"></a>{{end}}
{{end}}{{end}}
<a href="" class="action_button quote_item" aria-label="{{lang "topic.quote_aria"}}" data-action="quote"></a>
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}<a href="/topic/edit/{{.Topic.ID}}" class="action_button open_edit" aria-label="{{lang "topic.edit_aria"}}" data-action="edit"></a>{{end}}
{{end}}
{{if .Topic.Deletable}}<a href="/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.delete_aria"}}" data-action="delete"></a>{{end}}
{{if .CurrentUser.Perms.CloseTopic}}
{{if .Topic.IsClosed}}<a href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unlock_item" data-action="unlock" aria-label="{{lang "topic.unlock_aria"}}"></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button lock_item" data-action="lock" aria-label="{{lang "topic.lock_aria"}}"></a>{{end}}{{end}}
{{if .CurrentUser.Perms.PinTopic}}
{{if .Topic.Sticky}}<a href='/topic/unstick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unpin_item" data-action="unpin" aria-label="{{lang "topic.unpin_aria"}}"></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button pin_item" data-action="pin" aria-label="{{lang "topic.pin_aria"}}"></a>{{end}}{{end}}
{{if .CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.Topic.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item_button hide_on_big" aria-label="{{lang "topic.ip_full_aria"}}" data-action="ip"></a>{{end}}
<a href="/report/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}&type=topic" class="action_button report_item" aria-label="{{lang "topic.report_aria"}}" data-action="report"></a>
<a href="#" class="action_button button_menu"></a>
{{end}}
</div>
<div class="action_button_right">
<a class="action_button like_count hide_on_micro" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a>
<a class="action_button created_at hide_on_mobile" title="{{abstime .Topic.CreatedAt}}">{{reltime .Topic.CreatedAt}}</a>
{{if .CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.Topic.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item hide_on_mobile" aria-hidden="true">{{.Topic.IP}}</a>{{end}}
</div>
</div>
</div><div style="clear:both;"></div>
</article>
{{template "topic_alt_posts.html" . }}
</div>
{{template "paginator.html" . }}
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.CreateReply}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{template "topic_alt_quick_reply.html" . }}
{{end}}
{{end}}
{{end}}
</main>
{{template "topic_alt_inner.html" . }}
{{template "footer.html" . }}

View File

@ -0,0 +1,120 @@
<main id="topicPage">
{{if gt .Page 1}}<link rel="prev"href="{{.Topic.Link}}?page={{subtract .Page 1}}"/>{{end}}
{{if ne .LastPage .Page}}<link rel="prerender next"href="{{.Topic.Link}}?page={{add .Page 1}}"/>{{end}}
<link rel="canonical" href="//{{.Site.URL}}{{.Topic.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<div {{scope "topic_title_block"}} class="rowblock rowhead topic_block" aria-label="{{lang "topic.topic_info_aria"}}">
<div class="rowitem topic_item{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.IsClosed}} topic_closed_head{{end}}">
<h1 class='topic_name hide_on_edit' title='{{.Topic.Title}}'>{{.Topic.Title}}</h1>
<span class="topic_name_forum_sep hide_on_edit"> - </span>
<a href="{{.Forum.Link}}" class="topic_forum hide_on_edit">{{.Forum.Name}}</a>
{{/** TODO: Does this need to be guarded by a permission? It's only visible in edit mode anyway, which can't be triggered, if they don't have the permission **/}}
{{if .CurrentUser.Loggedin}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}
<form id="edit_topic_form" action='/topic/edit/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' method="post"></form>
<input form="edit_topic_form" class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" aria-label="{{lang "topic.title_input_aria"}}"/>
<button form="edit_topic_form" name="topic-button" class="formbutton show_on_edit submit_edit">{{lang "topic.update_button"}}</button>
{{end}}
{{end}}
{{end}}
<span class="topic_view_count hide_on_edit">{{.Topic.ViewCount}}</span>
{{/** TODO: Inline this CSS **/}}
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}'>&#x1F512;&#xFE0E</span>{{end}}
</div>
</div>
<div class="rowblock post_container">
{{if .Poll.ID}}<form id="poll_{{.Poll.ID}}_form" action="/poll/vote/{{.Poll.ID}}?s={{.CurrentUser.Session}}" method="post"></form>
<article class="rowitem passive deletable_block editable_parent post_item poll_item top_post hide_on_edit">
{{/**{{template "topic_alt_userinfo.html" .Topic }}**/}}
<div id="poll_voter_{{.Poll.ID}}" class="content_container poll_voter">
<div class="topic_content user_content">
{{range .Poll.QuickOptions}}
<div class="poll_option">
<input form="poll_{{$.Poll.ID}}_form" id="poll_option_{{.ID}}" name="poll_option_input" type="checkbox" value="{{.ID}}"/>
<label class="poll_option_label" for="poll_option_{{.ID}}"><div class="sel"></div></label>
<span id="poll_option_text_{{.ID}}" class="poll_option_text">{{.Value}}</span>
</div>
{{end}}
<div class="poll_buttons">
<button form="poll_{{.Poll.ID}}_form" class="poll_vote_button">{{lang "topic.poll_vote"}}</button>
<button class="poll_results_button" data-poll-id="{{.Poll.ID}}">{{lang "topic.poll_results"}}</button>
<a href="#"><button class="poll_cancel_button">{{lang "topic.poll_cancel"}}</button></a>
</div>
</div>
</div>
<div id="poll_results_{{.Poll.ID}}" class="content_container poll_results auto_hide">
<div class="topic_content user_content">
<div class="auto_hide poll_no_results">{{lang "topic.poll_no_results"}}</div>
</div>
</div>
</article>
{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowitem passive deletable_block editable_parent post_item top_post{{if .Topic.Attachments}} has_attachs{{end}}" aria-label="{{lang "topic.opening_post_aria"}}">
{{template "topic_alt_userinfo.html" .Topic }}
<div class="content_container">
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>
{{if .CurrentUser.Perms.EditTopic}}
<div class="show_on_edit attach_edit_bay" type="topic" id="{{.Topic.ID}}">
{{range .Topic.Attachments}}
<div class="attach_item attach_item_item{{if .Image}} attach_image_holder{{end}}">
{{if .Image}}<img src="//{{$.Header.Site.URL}}/attachs/{{.Path}}?sid={{.SectionID}}&amp;stype=forums" height=24 width=24/>{{end}}
<span class="attach_item_path" aid="{{.ID}}" fullPath="//{{$.Header.Site.URL}}/attachs/{{.Path}}">{{.Path}}</span>
<button class="attach_item_select">{{lang "topic.select_button_text"}}</button>
<button class="attach_item_copy">{{lang "topic.copy_button_text"}}</button>
</div>
{{end}}
<div class="attach_item attach_item_buttons">
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" id="upload_files_op" multiple type="file" class="auto_hide" />
<label for="upload_files_op" class="formbutton add_file_button">{{lang "topic.upload_button_text"}}</label>{{end}}
<button class="attach_item_delete formbutton">{{lang "topic.delete_button_text"}}</button>
</div>
</div>
{{end}}{{end}}
<div class="controls button_container{{if .Topic.LikeCount}} has_likes{{end}}">
<div class="action_button_left">
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.LikeItem}}{{if ne .CurrentUser.ID .Topic.CreatedBy}}
{{if .Topic.Liked}}<a href="/topic/unlike/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button like_item remove_like" aria-label="{{lang "topic.unlike_aria"}}" data-action="unlike"></a>{{else}}<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button like_item add_like" aria-label="{{lang "topic.like_aria"}}" data-action="like"></a>{{end}}
{{end}}{{end}}
<a href="" class="action_button quote_item" aria-label="{{lang "topic.quote_aria"}}" data-action="quote"></a>
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}<a href="/topic/edit/{{.Topic.ID}}" class="action_button open_edit" aria-label="{{lang "topic.edit_aria"}}" data-action="edit"></a>{{end}}
{{end}}
{{if .Topic.Deletable}}<a href="/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="action_button delete_item" aria-label="{{lang "topic.delete_aria"}}" data-action="delete"></a>{{end}}
{{if .CurrentUser.Perms.CloseTopic}}
{{if .Topic.IsClosed}}<a href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unlock_item" data-action="unlock" aria-label="{{lang "topic.unlock_aria"}}"></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button lock_item" data-action="lock" aria-label="{{lang "topic.lock_aria"}}"></a>{{end}}{{end}}
{{if .CurrentUser.Perms.PinTopic}}
{{if .Topic.Sticky}}<a href='/topic/unstick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button unpin_item" data-action="unpin" aria-label="{{lang "topic.unpin_aria"}}"></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="action_button pin_item" data-action="pin" aria-label="{{lang "topic.pin_aria"}}"></a>{{end}}{{end}}
{{if .CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.Topic.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item_button hide_on_big" aria-label="{{lang "topic.ip_full_aria"}}" data-action="ip"></a>{{end}}
<a href="/report/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}&type=topic" class="action_button report_item" aria-label="{{lang "topic.report_aria"}}" data-action="report"></a>
<a href="#" class="action_button button_menu"></a>
{{end}}
</div>
<div class="action_button_right">
<a class="action_button like_count hide_on_micro" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a>
<a class="action_button created_at hide_on_mobile" title="{{abstime .Topic.CreatedAt}}">{{reltime .Topic.CreatedAt}}</a>
{{if .CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.Topic.IP}}" title="{{lang "topic.ip_full_tooltip"}}" class="action_button ip_item hide_on_mobile" aria-hidden="true">{{.Topic.IP}}</a>{{end}}
</div>
</div>
</div><div style="clear:both;"></div>
</article>
{{template "topic_alt_posts.html" . }}
</div>
{{template "paginator.html" . }}
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.CreateReply}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{template "topic_alt_quick_reply.html" . }}
{{end}}
{{end}}
{{end}}
</main>

View File

@ -0,0 +1,2 @@
{{template "topic_alt_inner.html" . }}
<aside class="midRight sidebar">{{dock "rightSidebar" .Header}}</aside>

View File

@ -2,10 +2,9 @@
{{if js}}js{{/**{{ptmpl "topic_alt_userinfo" .}}**/}}{{else}}{{template "topic_alt_userinfo.html" . }}{{end}}
<div class="content_container">
{{if .ActionType}}
<span class="action_icon" aria-hidden="true">{{.ActionIcon}}</span>
<span itemprop="text">{{.ActionType}}</span>
<span class="action_icon" aria-hidden="true">{{.ActionIcon}}</span><span itemprop="text">{{.ActionType}}</span>
{{else}}
<div class="editable_block user_content" itemprop="text">{{.ContentHtml}}</div>
<div class="editable_block user_content"itemprop="text">{{.ContentHtml}}</div>
{{if $.CurrentUser.Loggedin}}
<div class="edit_source auto_hide">{{.Content}}</div>
@ -48,9 +47,9 @@
<div class="action_button_right">
<a class="action_button like_count hide_on_micro" aria-label="{{lang "topic.post_like_count_tooltip"}}">{{.LikeCount}}</a>
<a class="action_button created_at hide_on_mobile" title="{{abstime .CreatedAt}}">{{reltime .CreatedAt}}</a>
{{if $.CurrentUser.Loggedin}}{{if $.CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.IP}}" title="IP Address" class="action_button ip_item hide_on_mobile" aria-hidden="true">{{.IP}}</a>{{end}}{{end}}
{{if $.CurrentUser.Loggedin}}{{if $.CurrentUser.Perms.ViewIPs}}<a href="/users/ips/?ip={{.IP}}"title="IP Address" class="action_button ip_item hide_on_mobile" aria-hidden="true">{{.IP}}</a>{{end}}{{end}}
</div>
</div>
{{end}}
</div><div style="clear:both;"></div>
</article>{{end}}
</article>{{end}}

View File

@ -1,6 +1,6 @@
<div class="userinfo" aria-label="{{lang "topic.userinfo_aria"}}">
<!--<div class="avatar_item" style="background-image:url({{.Avatar}}),url(/s/white-dot.jpg);">&nbsp;</div>-->
<img class="aitem" src="{{.Avatar}}" alt="Avatar">
<img class="aitem"src="{{.Avatar}}"alt="Avatar">
<div class="user_meta">
<a href="{{.UserLink}}" class="the_name" rel="author">{{.CreatedByName}}</a>
<div class="tag_block">

108
templates/topic_inner.html Normal file
View File

@ -0,0 +1,108 @@
<main id="topicPage">
{{if gt .Page 1}}<link rel="prev" href="{{.Topic.Link}}?page={{subtract .Page 1}}"/>
<div id="prevFloat" class="prev_button"><a class="prev_link" aria-label="{{lang "paginator.prev_page_aria"}}" rel="prev" href="{{.Topic.Link}}?page={{subtract .Page 1}}">{{lang "paginator.less_than"}}</a></div>{{end}}
{{if ne .LastPage .Page}}<link rel="prerender next" href="{{.Topic.Link}}?page={{add .Page 1}}"/>
<div id="nextFloat" class="next_button">
<a class="next_link" aria-label="{{lang "paginator.next_page_aria"}}" rel="next" href="{{.Topic.Link}}?page={{add .Page 1}}">{{lang "paginator.greater_than"}}</a>
</div>{{end}}
<link rel="canonical" href="//{{.Site.URL}}{{.Topic.Link}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<div {{scope "topic_title_block"}} class="rowblock rowhead topic_block" aria-label="{{lang "topic.topic_info_aria"}}">
<div class="rowitem topic_item{{if .Topic.Sticky}} topic_sticky_head{{else if .Topic.IsClosed}} topic_closed_head{{end}}">
<h1 class='topic_name hide_on_edit' title='{{.Topic.Title}}'>{{.Topic.Title}}</h1>
{{if .Topic.IsClosed}}<span class='username hide_on_micro topic_status_e topic_status_closed hide_on_edit' title='{{lang "status.closed_tooltip"}}' aria-label='{{lang "topic.status_closed_aria"}}'>&#x1F512;&#xFE0E</span>{{end}}
{{/** TODO: Does this need to be guarded by a permission? It's only visible in edit mode anyway, which can't be triggered, if they don't have the permission **/}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}
<form id="edit_topic_form" action='/topic/edit/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' method="post"></form>
<input form='edit_topic_form' class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" aria-label="{{lang "topic.title_input_aria"}}"/>
<button form='edit_topic_form' name="topic-button" class="formbutton show_on_edit submit_edit">{{lang "topic.update_button"}}</button>
{{end}}
{{end}}
</div>
</div>
{{if .Poll.ID}}{{template "topic_poll.html" . }}{{end}}
<article {{scope "opening_post"}} itemscope itemtype="http://schema.org/CreativeWork" class="rowblock post_container top_post" aria-label="{{lang "topic.opening_post_aria"}}">
<div class="rowitem passive editable_parent post_item {{.Topic.ClassName}}" style="background-image:url({{.Topic.Avatar}}),url(/s/{{.Header.Theme.Name}}/post-avatar-bg.jpg);background-position:0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat:no-repeat,repeat-y;">
<div class="hide_on_edit topic_content user_content" itemprop="text">{{.Topic.ContentHTML}}</div>
{{if .CurrentUser.Loggedin}}<textarea name="topic_content" class="show_on_edit topic_content_input edit_source">{{.Topic.Content}}</textarea>{{end}}
<span class="controls{{if .Topic.LikeCount}} has_likes{{end}}" aria-label="{{lang "topic.post_controls_aria"}}">
<a href="{{.Topic.UserLink}}" class="username real_username" rel="author">{{.Topic.CreatedByName}}</a>&nbsp;&nbsp;
{{if .CurrentUser.Loggedin}}
{{if .CurrentUser.Perms.LikeItem}}{{if ne .CurrentUser.ID .Topic.CreatedBy}}
{{if .Topic.Liked}}
<a href="/topic/unlike/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button"title="{{lang "topic.unlike_tooltip"}}" aria-label="{{lang "topic.unlike_aria"}}">
<button class="username like_label remove_like"></button></a>{{else}}
<a href="/topic/like/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}" class="mod_button"title="{{lang "topic.like_tooltip"}}" aria-label="{{lang "topic.like_aria"}}">
<button class="username like_label add_like"></button></a>{{end}}
{{end}}{{end}}
<a href="" class="mod_button quote_item"title="{{lang "topic.quote_tooltip"}}" aria-label="{{lang "topic.quote_aria"}}"><button class="username quote_label"></button></a>
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
{{if .CurrentUser.Perms.EditTopic}}<a href='/topic/edit/{{.Topic.ID}}' class="mod_button open_edit"title="{{lang "topic.edit_tooltip"}}" aria-label="{{lang "topic.edit_aria"}}"><button class="username edit_label"></button></a>{{end}}
{{end}}
{{if .Topic.Deletable}}<a href='/topic/delete/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button"title="{{lang "topic.delete_tooltip"}}" aria-label="{{lang "topic.delete_aria"}}"><button class="username delete_label"></button></a>{{end}}
{{if .CurrentUser.Perms.CloseTopic}}{{if .Topic.IsClosed}}<a class="mod_button" href='/topic/unlock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}'title="{{lang "topic.unlock_tooltip"}}" aria-label="{{lang "topic.unlock_aria"}}"><button class="username unlock_label"></button></a>{{else}}<a href='/topic/lock/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button"title="{{lang "topic.lock_tooltip"}}" aria-label="{{lang "topic.lock_aria"}}"><button class="username lock_label"></button></a>{{end}}{{end}}
{{if .CurrentUser.Perms.PinTopic}}{{if .Topic.Sticky}}<a class="mod_button" href='/topic/unstick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}'title="{{lang "topic.unpin_tooltip"}}" aria-label="{{lang "topic.unpin_aria"}}"><button class="username unpin_label"></button></a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}' class="mod_button"title="{{lang "topic.pin_tooltip"}}" aria-label="{{lang "topic.pin_aria"}}"><button class="username pin_label"></button></a>{{end}}{{end}}
{{if .CurrentUser.Perms.ViewIPs}}<a class="mod_button" href='/users/ips/?ip={{.Topic.IP}}' title="{{lang "topic.ip_tooltip"}}" aria-label="The poster's IP is {{.Topic.IP}}"><button class="username ip_label"></button></a>{{end}}
{{end}}
<a href="/report/submit/{{.Topic.ID}}?s={{.CurrentUser.Session}}&type=topic" class="mod_button report_item"title="{{lang "topic.flag_tooltip"}}" aria-label="{{lang "topic.flag_aria"}}" rel="nofollow"><button class="username flag_label"></button></a>
<a class="username hide_on_micro like_count" aria-label="{{lang "topic.like_count_aria"}}">{{.Topic.LikeCount}}</a><a class="username hide_on_micro like_count_label" title="{{lang "topic.like_count_tooltip"}}"></a>
{{if .Topic.Tag}}<a class="username hide_on_micro user_tag">{{.Topic.Tag}}</a>{{else}}<a class="username hide_on_micro level" aria-label="{{lang "topic.level_aria"}}" title="{{lang "topic.level_tooltip"}}">{{level .Topic.Level}}</a><a class="username hide_on_micro level_label" title="{{lang "topic.level_tooltip"}}"></a>{{end}}
</span>
</div>
</article>
{{template "topic_posts.html" . }}
{{if .CurrentUser.Perms.CreateReply}}
{{if not .Topic.IsClosed or .CurrentUser.Perms.CloseTopic}}
<div class="rowblock topic_reply_form quick_create_form" aria-label="{{lang "topic.reply_aria"}}">
<form id="quick_post_form" enctype="multipart/form-data" action="/reply/create/?s={{.CurrentUser.Session}}" method="post"></form>
<input form="quick_post_form" name="tid" value='{{.Topic.ID}}' type="hidden"/>
<input form="quick_post_form" id="has_poll_input" name="has_poll" value=0 type="hidden"/>
<div class="formrow real_first_child">
<div class="formitem">
<textarea id="input_content" form="quick_post_form" name="content" placeholder="{{lang "topic.reply_content"}}" required></textarea>
</div>
</div>
<div class="formrow poll_content_row auto_hide">
<div class="formitem">
<div class="pollinput" data-pollinput=0>
<input type="checkbox" disabled />
<label class="pollinputlabel"></label>
<input form="quick_post_form" name="pollinputitem[0]" class="pollinputinput" type="text" placeholder="{{lang "topic.reply_add_poll_option_first"}}"/>
</div>
</div>
</div>
<div class="formrow quick_button_row">
<div class="formitem">
<button form="quick_post_form" name="reply-button" class="formbutton">{{lang "topic.reply_button"}}</button>
<button form="quick_post_form" class="formbutton" id="add_poll_button">{{lang "topic.reply_add_poll_button"}}</button>
{{if .CurrentUser.Perms.UploadFiles}}
<input name="upload_files" form="quick_post_form" id="upload_files" multiple type="file" style="display:none;" />
<label for="upload_files" class="formbutton add_file_button">{{lang "topic.reply_add_file_button"}}</label>
<div id="upload_file_dock"></div>{{end}}
</div>
</div>
</div>
{{end}}
{{end}}
</main>

View File

@ -0,0 +1,2 @@
{{template "topic_inner.html" . }}
<aside class="midRight sidebar">{{dock "rightSidebar" .Header}}</aside>

View File

@ -1,6 +1,6 @@
{{template "header.html" . }}
<link rel="canonical" href="//{{.Site.URL}}/topics/{{if eq .Sort.SortBy "mostviewed"}}most-viewed/{{end}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<main id="topicsItemList" itemscope itemtype="http://schema.org/ItemList">
<link rel="canonical" href="//{{.Site.URL}}/topics/{{if eq .Sort.SortBy "mostviewed"}}most-viewed/{{end}}{{if gt .Page 1}}?page={{.Page}}{{end}}"/>
<div class="rowblock rowhead topic_list_title_block{{if .CurrentUser.Loggedin}} has_opt{{end}}">
<div class="rowitem topic_list_title"><h1 itemprop="name">{{.Title}}</h1></div>

View File

@ -6,8 +6,8 @@
<a class="rowtopic" href="{{.Link}}" itemprop="itemListElement" title="{{.Title}}"><span>{{.Title}}</span></a> {{if .ForumName}}<a class="rowsmall parent_forum" href="{{.ForumLink}}" title="{{.ForumName}}">{{.ForumName}}</a>{{end}}
<br><a class="rowsmall starter" href="{{.Creator.Link}}" title="{{.Creator.Name}}">{{.Creator.Name}}</a>
{{/** TODO: Avoid the double '|' when both .IsClosed and .Sticky are set to true. We could probably do this with CSS **/}}
{{if .IsClosed}}<span class="rowsmall topic_status_e topic_status_closed" title="{{lang "status.closed_tooltip"}}"> | &#x1F512;&#xFE0E</span>{{end}}
{{if .Sticky}}<span class="rowsmall topic_status_e topic_status_sticky" title="{{lang "status.pinned_tooltip"}}"> | &#x1F4CD;&#xFE0E</span>{{end}}
{{if .IsClosed}}<span class="rowsmall topic_status_e topic_status_closed"title="{{lang "status.closed_tooltip"}}"> | &#x1F512;&#xFE0E</span>{{end}}
{{if .Sticky}}<span class="rowsmall topic_status_e topic_status_sticky"title="{{lang "status.pinned_tooltip"}}"> | &#x1F4CD;&#xFE0E</span>{{end}}
</span>
{{/** TODO: Phase this out of Cosora and remove it **/}}
<div class="topic_inner_right rowsmall">

View File

@ -10,6 +10,10 @@
{
"Name": "topic",
"Source": "topic_alt"
},
{
"Name": "topic_mini",
"Source": "topic_alt_mini"
}
],
"Resources": [
@ -20,7 +24,7 @@
{
"Name":"trumbowyg/trumbowyg.min.js",
"Location":"global",
"Loggedin": true
"Loggedin":true
},
{
"Name":"trumbowyg/ui/trumbowyg.custom.css",
@ -33,4 +37,4 @@
"Async":true
}
]
}
}

View File

@ -1,8 +1,8 @@
<div class="topic_row{{if .Sticky}} topic_sticky{{else if .IsClosed}} topic_closed{{end}}" data-tid="{{.ID}}">
<div class="topic_row{{if .Sticky}} topic_sticky{{else if .IsClosed}} topic_closed{{end}}" data-tid={{.ID}}>
<div class="rowitem topic_left passive datarow">
<a href="{{.Creator.Link}}"><img src="{{.Creator.MicroAvatar}}" height=64 alt="Avatar" title="{{.Creator.Name}}'s Avatar" aria-hidden="true"/></a>
<a href="{{.Creator.Link}}"><img src="{{.Creator.MicroAvatar}}" height=64 alt="Avatar"title="{{.Creator.Name}}'s Avatar"aria-hidden="true"/></a>
<span class="topic_inner_left">
<span class="rowtopic" itemprop="itemListElement" title="{{.Title}}"><a href="{{.Link}}">{{.Title}}</a>{{if .ForumName}}<a class="parent_forum_sep">-</a><a href="{{.ForumLink}}" title="{{.ForumName}}" class="rowsmall parent_forum">{{.ForumName}}</a>{{end}}</span>
<span class="rowtopic" itemprop="itemListElement"title="{{.Title}}"><a href="{{.Link}}">{{.Title}}</a>{{if .ForumName}}<a class="parent_forum_sep">-</a><a href="{{.ForumLink}}" title="{{.ForumName}}" class="rowsmall parent_forum">{{.ForumName}}</a>{{end}}</span>
<br><a class="rowsmall starter" href="{{.Creator.Link}}" title="{{.Creator.Name}}">{{.Creator.Name}}</a>
</span>
</div>
@ -15,10 +15,10 @@
</div>
<div class="rowitem topic_right passive datarow">
<div class="topic_right_inside">
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}" height=64 alt="Avatar" title="{{.LastUser.Name}}'s Avatar" aria-hidden="true"/></a>
<a href="{{.LastUser.Link}}"><img src="{{.LastUser.MicroAvatar}}" height=64 alt="Avatar"title="{{.LastUser.Name}}'s Avatar"aria-hidden="true"/></a>
<span>
<a href="{{.LastUser.Link}}" class="lastName" title="{{.LastUser.Name}}">{{.LastUser.Name}}</a><br>
<a href="{{.Link}}?page={{.LastPage}}{{if .LastReplyID}}#post-{{.LastReplyID}}{{end}}" class="rowsmall lastReplyAt" title="{{abstime .LastReplyAt}}">{{reltime .LastReplyAt}}</a>
<a href="{{.LastUser.Link}}"class="lastName"title="{{.LastUser.Name}}">{{.LastUser.Name}}</a><br>
<a href="{{.Link}}?page={{.LastPage}}{{if .LastReplyID}}#post-{{.LastReplyID}}{{end}}"class="rowsmall lastReplyAt"title="{{abstime .LastReplyAt}}">{{reltime .LastReplyAt}}</a>
</span>
</div>
</div>

View File

@ -45,7 +45,7 @@ function noxMenuBind() {
else $('.alert').insertAfter(".rowhead:first");
}
addInitHook("after_update_alert_list", (alertCount) => {
addInitHook("after_update_alert_list", alertCount => {
console.log("misc.js");
console.log("alertCount",alertCount);
if(alertCount==0) {
@ -57,9 +57,8 @@ function noxMenuBind() {
$(".user_box").addClass("has_alerts");
}
});
let tb=$('.topic_block');
addHook("open_edit", () => tb.addClass("edithead"));
addHook("close_edit", () => tb.removeClass("edithead"));
addHook("open_edit", () => $('.topic_block').addClass("edithead"));
addHook("close_edit", () => $('.topic_block').removeClass("edithead"));
addInitHook("end_init", () => {
$(".alerts").click(ev => {
@ -77,7 +76,6 @@ function noxMenuBind() {
$(".menu_hamburger").click(function() {
event.stopPropagation();
console.log("hi")
let mm = document.getElementsByClassName("more_menu")[0];
mm.classList.add("more_menu_selected");
let calc = $(this).offset().left - (mm.offsetWidth / 4);

View File

@ -6,7 +6,7 @@
"URL": "github.com/Azareal/Gosora",
"Tag": "WIP",
"Docks":["topMenu","rightSidebar","footer"],
"GridLists":true,
"GridLists": true,
"MapTmplToDock": {
"rightOfNav": {
"File": "./templates/userDock.html"
@ -16,13 +16,17 @@
{
"Name": "topic",
"Source": "topic_alt"
},
{
"Name": "topic_mini",
"Source": "topic_alt_mini"
}
],
"Resources": [
{
"Name":"trumbowyg/trumbowyg.min.js",
"Location":"global",
"Loggedin": true
"Loggedin":true
},
{
"Name":"trumbowyg/ui/trumbowyg.custom.css",
@ -35,4 +39,4 @@
"Async":true
}
]
}
}

View File

@ -4,12 +4,10 @@ addInitHook("end_init", () => {
$(".topic_list img").each(function(){
let aspectRatio = this.naturalHeight / this.naturalWidth;
console.log("aspectRatio",aspectRatio);
console.log("this.height",this.naturalHeight);
console.log("this.width",this.naturalWidth);
console.log("height",this.naturalHeight);
console.log("width",this.naturalWidth);
$(this).css({
height: aspectRatio * this.width
});
$(this).css({ height: aspectRatio * this.width });
});
});
})()

View File

@ -11,6 +11,10 @@
{
"Name": "topic",
"Source": "topic"
},
{
"Name":"topic_mini",
"Source":"topic_mini"
}
],
"Resources": [

View File

@ -4,12 +4,10 @@ addInitHook("end_init", () => {
$(".topic_list img").each(function(){
let aspectRatio = this.naturalHeight / this.naturalWidth;
console.log("aspectRatio",aspectRatio);
console.log("this.height",this.naturalHeight);
console.log("this.width",this.naturalWidth);
console.log("height",this.naturalHeight);
console.log("width",this.naturalWidth);
$(this).css({
height: aspectRatio * this.width
});
$(this).css({ height: aspectRatio * this.width });
});
});
})()

View File

@ -10,8 +10,12 @@
"Docks":["topMenu","rightSidebar"],
"Templates": [
{
"Name": "topic",
"Source": "topic"
"Name":"topic",
"Source":"topic"
},
{
"Name":"topic_mini",
"Source":"topic_mini"
}
],
"Resources": [