Personal blog written from scratch using Node.js, Bootstrap, and MySQL. https://jrtechs.net
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
6.6 KiB

  1. {header}
  2. <script src="https://code.jquery.com/jquery-3.3.1.min.js"
  3. integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  4. crossorigin="anonymous">
  5. </script>
  6. <style>
  7. :root {
  8. --primary:rgba(16,116,231,1);
  9. --secondary:rgba(46,188,79,1);
  10. --dark:rgba(36,41,46,1);
  11. --dark-2:rgba(43,49,55,1);
  12. --white:rgba(255,255,255,1);
  13. }
  14. .vis-timeline {
  15. border: none;
  16. font-size: 16px;
  17. color: var(--white);
  18. background-color: var(--dark);
  19. }
  20. .vis-item {
  21. font-size: 16px;
  22. color: var(--dark);
  23. background-color: var(--white);
  24. box-sizing: border-box;
  25. box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.06), 0px 4px 6px rgba(0, 0, 0, 0.06);
  26. border-color: transparent;
  27. }
  28. .vis-item.vis-box {
  29. border-radius: 2px;
  30. padding: 0;
  31. border: none;
  32. }
  33. .vis-item .vis-item-content {
  34. padding: 8px 10px;
  35. }
  36. .vis-item.vis-box.vis-selected {
  37. border: 2px solid var(--primary);
  38. }
  39. .vis-item.vis-line {
  40. border-width: 2px;
  41. border-color: var(--primary)
  42. }
  43. .vis-item.vis-dot {
  44. border-color: var(--primary);
  45. }
  46. .vis-item.vis-selected {
  47. border-color: var(--primary);
  48. background-color: var(--white);
  49. box-shadow: 0px 20px 25px rgba(0, 0, 0, 0.2), 0px 10px 10px rgba(0, 0, 0, 0.14);
  50. }
  51. .vis-time-axis .vis-text {
  52. color: var(--white)!important;
  53. padding-top: 8px;
  54. padding-left: 16px;
  55. }
  56. .vis-time-axis .vis-grid.vis-minor {
  57. border-width: 2px;
  58. border-color: rgba(255, 255, 255, .29);
  59. }
  60. .vis-labelset .vis-label {
  61. color: var(--white);
  62. }
  63. .vis-time-axis .vis-grid.vis-major {
  64. border-width: 1px;
  65. border-color: rgba(255, 255, 255, .5);
  66. }
  67. </style>
  68. <br><br><br><br><br>
  69. <div id="timeline"></div>
  70. <br><br>
  71. <div class="container">
  72. <div class="row">
  73. <div class="col-md-8 col-12">
  74. <div class="blogPost">
  75. <div id=POST_PICTURE>
  76. </div>
  77. <div class="p-4">
  78. <b><h3 id="POST_TITLE"></h3></b>
  79. <h5>
  80. <span class="w3-opacity"><div id="POST_PUBLISHED"></div></span>
  81. </h5>
  82. <div id="POST_BODY"></div>
  83. </div>
  84. </div>
  85. <br>
  86. <br><br>
  87. </div>
  88. <div class="col-md-4 col-12">
  89. {>sideBar}
  90. </div>
  91. </div>
  92. </div>
  93. <script src="/includes/js/vis/dist/vis-timeline-graph2d.min.js"></script>
  94. <link href="/includes/js/vis/dist/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
  95. <script type="text/javascript">
  96. /**
  97. * Runs a get request using ajax
  98. */
  99. function runAjax(url, successCallBack, errorCallBack)
  100. {
  101. console.log(url);
  102. $.ajax({
  103. type:'GET',
  104. url: url,
  105. crossDomain: true,
  106. dataType: "json",
  107. success: successCallBack,
  108. error:errorCallBack,
  109. timeout: 3000
  110. });
  111. }
  112. /** Lazy loads youtube videos on the page
  113. */
  114. function lazyLoad()
  115. {
  116. var youtube = document.querySelectorAll( ".youtube" );
  117. for (var i = 0; i < youtube.length; i++) {
  118. var source = "https://img.youtube.com/vi/"+ youtube[i].dataset.embed +"/sddefault.jpg";
  119. var image = new Image();
  120. image.src = source;
  121. image.addEventListener( "load", function() {
  122. youtube[ i ].appendChild( image );
  123. }( i ) );
  124. youtube[i].addEventListener( "click", function() {
  125. var iframe = document.createElement( "iframe" );
  126. iframe.setAttribute( "frameborder", "0" );
  127. iframe.setAttribute( "allowfullscreen", "" );
  128. iframe.setAttribute( "src", "https://www.youtube.com/embed/"+ this.dataset.embed +"?rel=0&showinfo=0&autoplay=1" );
  129. this.innerHTML = "";
  130. this.appendChild( iframe );
  131. } );
  132. };
  133. }
  134. function renderPostOnPage(postID)
  135. {
  136. runAjax("api/render/" + postID,
  137. (html)=>
  138. {
  139. //uses ajax to update blog page
  140. $('#POST_TITLE').text(html.name);
  141. $('#POST_PUBLISHED').text(html.published);
  142. $('#POST_BODY').html(html.blogBody);
  143. $('#POST_PICTURE').html(html.hasPicture ?
  144. '<img src="/blogContent/headerImages/' + html.picture_url + '" style="width:100%;">' :
  145. '');
  146. //lazy loads youtube videos
  147. lazyLoad();
  148. //highlights code
  149. document.querySelectorAll('pre code').forEach((block) => {
  150. hljs.highlightBlock(block);
  151. });
  152. //renders latex math
  153. MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
  154. },
  155. (err)=>
  156. {
  157. console.log(err);
  158. });
  159. }
  160. /**
  161. * After a timeline event gets clicked this will
  162. * query the api for the blog post content and
  163. * display it on the page.
  164. */
  165. function timeLineClick(properties)
  166. {
  167. if(properties.item !== null)
  168. {
  169. renderPostOnPage(properties.item);
  170. }
  171. }
  172. /**
  173. * Fetches all the
  174. */
  175. function fetchPosts()
  176. {
  177. return new Promise((resolve, reject)=>
  178. {
  179. runAjax("api/posts", (data)=>
  180. {
  181. var datasetContents = [];
  182. for(var i=0; i < data.length; i++)
  183. {
  184. datasetContents.push(
  185. {
  186. start: new Date(data[i].published),
  187. content: data[i].name,
  188. id: data[i].post_id
  189. }
  190. );
  191. }
  192. resolve(datasetContents);
  193. renderPostOnPage(data[0].post_id);
  194. },
  195. (error)=>
  196. {
  197. resolve([]);
  198. });
  199. });
  200. }
  201. var container = document.getElementById('timeline');
  202. $(document).ready(function()
  203. {
  204. fetchPosts().then((data)=>
  205. {
  206. var options =
  207. {
  208. editable: false,
  209. margin: {
  210. item: 20,
  211. axis: 40
  212. },
  213. start:data[12].start,
  214. end:data[0].start
  215. };
  216. var items = new vis.DataSet(data);
  217. var timeline = new vis.Timeline(container, items, options);
  218. timeline.on('click', timeLineClick);
  219. });
  220. });
  221. </script>
  222. {footer}