posts.html 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <div class="ts-container is-very-narrow">
  2. <p>Work in progress</p>
  3. </div>
  4. <script>
  5. let loggedIn = false;
  6. //Check the user has logged in
  7. //Post editing function still require session check
  8. //this just here to hide the edit buttons
  9. $.get("/api/auth/chk", function(data){
  10. if (data == false){
  11. //User cannot use admin function. Hide the buttons.
  12. $(".adminOnly").remove();
  13. loggedIn = false;
  14. }else{
  15. loggedIn = true;
  16. }
  17. loadValue("blog-posts", function(){
  18. initPosts();
  19. });
  20. });
  21. //Initialize blog info
  22. function initBlogInfo(){
  23. loadValue("blog-title", function(title){
  24. if (title.error != undefined || title == ""){
  25. title = "WebStick";
  26. }
  27. document.title = decodeURIComponent(title);
  28. $("#pageTitle").text(decodeURIComponent(title));
  29. });
  30. loadValue("blog-subtitle", function(title){
  31. if (title.error != undefined || title == ""){
  32. title = "A personal web server hosted on an ESP8266 using a micro SD card";
  33. }
  34. $("#pageDesc").text(decodeURIComponent(title));
  35. });
  36. }
  37. $(document).ready(function(){
  38. initBlogInfo();
  39. });
  40. //Edit blog title and subtitles
  41. function editBlogSubtitle(){
  42. let newtitle = prompt("New Blog Subtitle", "");
  43. if (newtitle != null) {
  44. setValue("blog-subtitle", encodeURIComponent(newtitle), function(){
  45. initBlogInfo();
  46. })
  47. }
  48. }
  49. function editBlogTitle(){
  50. let newtitle = prompt("New Blog Title", "");
  51. if (newtitle != null) {
  52. setValue("blog-title", encodeURIComponent(newtitle), function(){
  53. initBlogInfo();
  54. })
  55. }
  56. }
  57. /*
  58. Post Edit functions
  59. */
  60. function editPost(btn){
  61. let postFilename = $(btn).attr("filename");
  62. let hash = encodeURIComponent(JSON.stringify({
  63. "filename": postFilename,
  64. "filepath": "/blog/posts/" + postFilename
  65. }))
  66. window.open("/admin/mde/index.html#" + hash);
  67. }
  68. /*
  69. Rendering for Posts
  70. */
  71. //Load a markdown file from URL and render it to target element
  72. function loadMarkdownToHTML(markdownURL, targetElement){
  73. fetch(markdownURL).then( r => r.text() ).then( text =>{
  74. var converter = new showdown.Converter();
  75. let targetHTML = converter.makeHtml(text);
  76. console.log(targetHTML);
  77. $(targetElement).html(targetHTML);
  78. });
  79. }
  80. function initPosts(){
  81. $("#posttable").html("<div class='ui basic segment'><p><i class='ui loading spinner icon'></i> Loading Blog Posts</p></div>");
  82. loadValue("blog-posts", function(data){
  83. $("#posttable").html("");
  84. try{
  85. let postList = JSON.parse(decodeURIComponent(atob(data)));
  86. //From latest to oldest
  87. postList.reverse();
  88. console.log("Post listed loaded: ", postList);
  89. if (postList.length == 0){
  90. $("#nopost").show();
  91. }else{
  92. $("#nopost").hide();
  93. postList.forEach(postFilename => {
  94. renderPost(postFilename);
  95. })
  96. }
  97. }catch(ex){
  98. $("#nopost").show();
  99. }
  100. })
  101. }
  102. function forceUpdatePostIndex(){
  103. updatePostIndex(function(){
  104. window.location.reload();
  105. });
  106. }
  107. //Render post
  108. function renderPost(filename){
  109. //Remove the timestamp
  110. let postTitle = filename.split("_");
  111. let timeStamp = postTitle.shift();
  112. postTitle = postTitle.join("_");
  113. //Pop the file extension
  114. postTitle = postTitle.split(".");
  115. postTitle.pop();
  116. postTitle = postTitle.join(".");
  117. var postTime = new Date(parseInt(timeStamp) * 1000).toLocaleDateString("en-US")
  118. let postEditFeature = `<div class="adminOnly" style="position: absolute; top: 3em; right: 0.4em;">
  119. <a class="ui basic mini icon button" onclick="editPost(this);" filename="${filename}" title="Edit Post"><i class="edit icon"></i></a>
  120. <button class="ui basic mini icon button" onclick="deletePost(this);" ptitle="${postTitle}" filename="${filename}" title="Remove Post"><i class="red trash icon"></i></button>
  121. </div>`;
  122. if (!loggedIn){
  123. postEditFeature = "";
  124. }
  125. //Create a wrapper element
  126. $("#posttable").append(`
  127. <div class="ui basic segment postObject" id="${timeStamp}">
  128. <div class="ui divider"></div>
  129. <h4 class="ui header">
  130. <i class="blue paperclip icon"></i>
  131. <div class="content">
  132. ${postTitle}
  133. </div>
  134. </h4>
  135. ${postEditFeature}
  136. <div class="postContent">
  137. </div>
  138. <small><i class="calendar alternate outline icon"></i> ${postTime}</small>
  139. </div>
  140. `);
  141. let targetElement = $("#" + timeStamp).find(".postContent");
  142. loadMarkdownToHTML("/blog/posts/" + filename,targetElement);
  143. }
  144. </script>