Float replies that aren't a solution, but are important, within a topic
Saw a Product Idea for this, so I thought I'd share my custom solution. Perhaps not for the faint of heart, but when you get it working it'll be fun :)
This adds an option to all the replies in a topic, which lets you float them to the top. Like Solutions, but not marked as such. Sometimes you want to float a reply to make it easier to find and stand out, without implying that it's a solution.
Looks like this:
You will need three things for this:
- Component that shows the floated reply
- Option in the reply's message options to float it
- Endpoint to make the magic work
And they are these:
One:
(I removed my CSS, but just reply here if you'd like to have it and I'll send it over. It'd just take a lot of space here).
<#assign topic_id = page.context.message.uniqueId/>
<#-- insert your preferred method of testing a user's role here -->
if user has role:
<#assign usercanUnfloat = true/>
else
<#assign usercanUnfloat = false/>
/if
<#-- ask Lithium to add a metadata field for messages -->
<#assign float_ids = restadmin("/messages/id/${topic_id}/metadata/key/spotify.floated_replies").value/>
<#if float_ids != ""> <#-- if this topic has floated replies -->
<#list float_ids?split(",") as msg_id>
<#if msg_id != "">
<#assign query_msg = restadmin("2.0","/search?q=" + "SELECT view_href,author.id,author.login,current_revision.last_edit_time,search_snippet,body FROM messages WHERE id = '${msg_id}'"?url) />
<#list query_msg.data.items as q>
<#assign author_id = q.author.id/>
<#assign author_login = q.author.login/>
<#assign msg_url = q.view_href/>
<#assign msg_post_time_date = q.current_revision.last_edit_time?number_to_datetime?datetime?string[cust_user_date_format]/>
<#assign msg_post_time_time = q.current_revision.last_edit_time?number_to_datetime?datetime?string[cust_user_time_format]/>
<#attempt>
<#assign msg_body = q.search_snippet/>
<#recover>
<#assign msg_body = q.body/>
</#attempt>
<#assign query_author = restadmin("2.0","/search?q=" + "SELECT view_href,rank,avatar.message FROM users WHERE id = '${author_id}'"?url) />
<#list query_author.data.items as a>
<#assign author_url = a.view_href/>
<#assign author_avatar = a.avatar.message/>
<#assign author_rank_name = a.rank.name/>
<#if a.rank.bold == true>
<#assign author_rank_bold = "bold"/>
<#else>
<#assign author_rank_bold = "normal"/>
</#if>
<#assign author_rank_color = a.rank.color/>
<#attempt>
<#assign author_rank_icon_url = a.rank.icon_left/>
<#assign show_icon = true/>
<#recover>
<#assign show_icon = false/>
</#attempt>
<div class="cust-floater-container">
<div class="cust-floater-message">
<div class="lia-quilt-column lia-quilt-column-24 lia-quilt-column-single lia-quilt-column-header-content">
<div class="lia-quilt-column-alley lia-quilt-column-alley-single">
<div class="lia-message-author-avatar lia-component-user-avatar">
<div class="UserAvatar lia-user-avatar lia-component-common-widget-user-avatar">
<a class="UserAvatar lia-link-navigation" tabindex="-1" target="_self" href="${author_url}"><img class="lia-user-avatar-message" title="${author_login}" alt="${author_login}" src="${author_avatar}"></a>
</div>
</div>
<div class="lia-message-author-username lia-component-user-name">
<span class="UserName lia-user-name lia-user-rank-${author_rank_name?replace(' ','-')}">
<a class="lia-link-navigation lia-page-link lia-user-name-link" style="color:#${author_rank_color}" target="_self" href="${author_url}"><span class="">${author_login}</span></a>
</span>
</div>
<div class="lia-message-author-rank lia-component-author-rank-name">${author_rank_name}</div>
<p class="lia-message-dates lia-message-post-date lia-component-post-date-last-edited">
<span class="DateTime lia-message-posted-on lia-component-common-widget-date">
<span class="local-date">${msg_post_time_date}</span>
<span class="local-time">${msg_post_time_time}</span>
</span>
</p>
<#-- button to let users un-float this reply -->
<#if usercanUnfloat == true>
<div class="lia-message-unfloat">
<#-- create an endpoint that will edit the topic's metadata field and remove the id of this floated reply -->
<a class="lia-link-navigation lia-page-link" href="ENDPOINT_URL_HERE?msgId=${msg_id}&topicId=${topic_id}&do=remove&url=${http.request.url}">Un-Float as Top Answer</a>
</div>
</#if>
</div>
</div>
<div class="lia-message-body-wrapper lia-component-message-view-widget-body">
<div id="bodydisplay" class="lia-message-body">
<div class="lia-message-body-content">
${msg_body}
</div>
</div>
<#-- the floated reply shows a snippet, just in case the floated reply is one looong post. This links to the full reply. -->
<div class="cust-readmore"><a href="${msg_url}">Read more</a></div>
</div>
</div>
</div>
</#list>
</#list>
</#if>
</#list>
</#if>Two:
(I added this to the Forum Topic Page and the Idea Page. You might need to tweak the JavaScript to work with your specific layout and classes)
<#-- insert your preferred method of testing a user's role here -->
<#-- if user has role: -->
<#if userIsAdminMod == true>
<#attempt>
<#assign topic_id = page.context.message.uniqueId/>
<#assign float_ids = restadmin("/messages/id/${topic_id}/metadata/key/spotify.floated_replies").value/>
<@liaAddScript>
<#if float_ids == "">
var arFloats = new Array();
<#else>
var arFloats = [${float_ids?trim}];
</#if>
$(document).ready(function() {
$(".lia-component-reply-list .lia-message-view, .CommentList .lia-message-view").each(function () {
var obj_msg = $(this);
var obj_href = obj_msg.attr('class');
var UidIndex = obj_href.indexOf("message-uid-");
if(UidIndex != -1) {
UidIndex = UidIndex + 12;
var msg_id = obj_href.slice(UidIndex, obj_href.length);
} else {
var msg_id = 0;
}
if(arFloats.indexOf(parseInt(msg_id)) == -1) {
var action_do = 'add';
var action_text = 'Float';
} else {
var action_do = 'remove';
var action_text = 'Un-Float';
}
var obj_add = '<li><a class="lia-link-navigation cust-action-float-message" rel="nofollow" href="/spotify/plugins/custom/spotify/spotify/end_float_reply?msgId=' + msg_id + '&topicId=${topic_id}&do=' + action_do +'&url=${http.request.url}">' + action_text + ' as Top Answer</a></li>' +
'<li class="cust-item-float-sep" aria-hidden="true"><span class="lia-separator lia-component-common-widget-link-separator"><span class="lia-separator-post"></span><span class="lia-separator-pre"></span></span></li>';
obj_msg.find(".lia-component-forums-action-highlight-message").each(function() {
obj_menu_item = $(this).parent('li');
obj_menu_item.before( obj_add );
});
});
});
</@liaAddScript>
<#recover>
</#attempt>
</#if>Three:
(The endpoint that makes it all work. Turned out smaller than I thought it would).
<#-- insert your preferred method of testing a user's role here -->
<#-- if user has role: -->
<#if userIsAdminMod == true>
<#assign status = ""/>
<#assign msg_id = http.request.parameters.name.get("msgId", "")?string />
<#assign topic_id = http.request.parameters.name.get("topicId", "")?string />
<#assign action = http.request.parameters.name.get("do", "")?string />
<#assign return_url = http.request.parameters.name.get("url", "")?string />
<#if msg_id != "" && topic_id != "" && action != "">
<#assign float_ids = restadmin("/messages/id/${topic_id}/metadata/key/spotify.floated_replies").value/>
<#assign float_ids_seq = []/>
<#if action == "add">
<#if float_ids == "">
<#assign float_ids_new = msg_id/>
<#else>
<#list float_ids?split(",") as f_id>
<#if f_id != "" && f_id?number != msg_id?number>
<#assign float_ids_seq = float_ids_seq + [f_id]/>
</#if>
</#list>
<#assign float_ids_seq = float_ids_seq + [msg_id]/>
<#if (float_ids_seq?size > 2)>
<#assign float_ids_seq_new = []/>
<#list float_ids_seq?reverse as f_id>
<#if (f_id_index < 2)>
<#assign float_ids_seq_new = float_ids_seq_new + [f_id]/>
</#if>
</#list>
<#assign float_ids_new = float_ids_seq_new?join(",")/>
<#else>
<#assign float_ids_new = float_ids_seq?join(",")/>
</#if>
</#if>
<#elseif action == "remove">
<#list float_ids?split(",")?reverse as f_id>
<#if f_id != "" && f_id?number != msg_id?number>
<#assign float_ids_seq = float_ids_seq + [f_id]/>
</#if>
</#list>
<#if (float_ids_seq?size > 0)>
<#assign float_ids_new = float_ids_seq?join(",")/>
<#else>
<#assign float_ids_new = ""/>
</#if>
</#if>
<#if float_ids_new??>
<#assign result = restadmin("/messages/id/${topic_id}/metadata/key/spotify.floated_replies/set?value=${float_ids_new}")/>
</#if>
</#if>
<script>
<#if result?? && result.error?has_content>
history.replaceState( {} , 'Float Message', '${return_url}' );
window.history.back();
<#else>
history.replaceState( {} , 'Float Message', '${return_url}' );
window.history.back();
</#if>
</script>
</#if>