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.

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