A clean, Markdown-based publishing platform made for writers. Write together, and build a community. https://writefreely.org
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.
 
 
 
 
 

236 lines
7.3 KiB

  1. {{define "pad"}}<!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <title>{{if .Editing}}Editing {{if .Post.Title}}{{.Post.Title}}{{else}}{{.Post.Id}}{{end}}{{else}}New Post{{end}} &mdash; {{.SiteName}}</title>
  5. <link rel="stylesheet" type="text/css" href="/css/write.css" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7. <meta name="google" value="notranslate">
  8. </head>
  9. <body id="pad" class="light">
  10. <div id="overlay"></div>
  11. <textarea id="writer" placeholder="Write..." class="{{.Post.Font}}" autofocus>{{if .Post.Title}}# {{.Post.Title}}
  12. {{end}}{{.Post.Content}}</textarea>
  13. <header id="tools">
  14. <div id="clip">
  15. {{if not .SingleUser}}<h1>{{if .Chorus}}<a href="/" title="Home">{{else}}<a href="/me/c/" title="View blogs">{{end}}{{.SiteName}}</a></h1>{{end}}
  16. <nav id="target" {{if .SingleUser}}style="margin-left:0"{{end}}><ul>
  17. <li>{{if .Blogs}}<a href="{{$c := index .Blogs 0}}{{$c.CanonicalURL}}">My Posts</a>{{else}}<a>Draft</a>{{end}}</li>
  18. </ul></nav>
  19. <span id="wc" class="hidden if-room room-4">0 words</span>
  20. </div>
  21. <noscript style="margin-left: 2em;"><strong>NOTE</strong>: for now, you'll need Javascript enabled to post.</noscript>
  22. <div id="belt">
  23. {{if .Editing}}<div class="tool hidden if-room"><a href="{{if .EditCollection}}{{.EditCollection.CanonicalURL}}{{.Post.Slug}}/edit/meta{{else}}/{{if .SingleUser}}d/{{end}}{{.Post.Id}}/meta{{end}}" title="Edit post metadata" id="edit-meta"><img class="ic-24dp" src="/img/ic_info_dark@2x.png" /></a></div>{{end}}
  24. <div class="tool"><button title="Publish your writing" id="publish" style="font-weight: bold">Post</button></div>
  25. </div>
  26. </header>
  27. <script src="/js/h.js"></script>
  28. <script>
  29. var $writer = H.getEl('writer');
  30. var $btnPublish = H.getEl('publish');
  31. var $wc = H.getEl("wc");
  32. var updateWordCount = function() {
  33. var words = 0;
  34. var val = $writer.el.value.trim();
  35. if (val != '') {
  36. words = $writer.el.value.trim().replace(/\s+/gi, ' ').split(' ').length;
  37. }
  38. $wc.el.innerText = words + " word" + (words != 1 ? "s" : "");
  39. };
  40. var setButtonStates = function() {
  41. if (!canPublish) {
  42. $btnPublish.el.className = 'disabled';
  43. return;
  44. }
  45. if ($writer.el.value.length === 0 || (draftDoc != 'lastDoc' && $writer.el.value == origDoc)) {
  46. $btnPublish.el.className = 'disabled';
  47. } else {
  48. $btnPublish.el.className = '';
  49. }
  50. };
  51. {{if .Post.Id}}var draftDoc = 'draft{{.Post.Id}}';
  52. var origDoc = '{{.Post.Content}}';{{else}}var draftDoc = 'lastDoc';{{end}}
  53. H.load($writer, draftDoc, true);
  54. updateWordCount();
  55. var typingTimer;
  56. var doneTypingInterval = 200;
  57. var posts;
  58. {{if and .Post.Id (not .Post.Slug)}}
  59. var token = null;
  60. var curPostIdx;
  61. posts = JSON.parse(H.get('posts', '[]'));
  62. for (var i=0; i<posts.length; i++) {
  63. if (posts[i].id == "{{.Post.Id}}") {
  64. token = posts[i].token;
  65. break;
  66. }
  67. }
  68. var canPublish = token != null;
  69. {{else}}var canPublish = true;{{end}}
  70. var publishing = false;
  71. var justPublished = false;
  72. var publish = function(content, font) {
  73. {{if and (and .Post.Id (not .Post.Slug)) (not .User)}}
  74. if (!token) {
  75. alert("You don't have permission to update this post.");
  76. return;
  77. }
  78. {{end}}
  79. publishing = true;
  80. $btnPublish.el.textContent = 'Posting...';
  81. $btnPublish.el.disabled = true;
  82. var http = new XMLHttpRequest();
  83. var lang = navigator.languages ? navigator.languages[0] : (navigator.language || navigator.userLanguage);
  84. lang = lang.substring(0, 2);
  85. var post = H.getTitleStrict(content);
  86. var params = {
  87. body: post.content,
  88. title: post.title,
  89. font: font,
  90. lang: lang
  91. };
  92. {{ if .Post.Slug }}
  93. var url = "/api/collections/{{.EditCollection.Alias}}/posts/{{.Post.Id}}";
  94. {{ else if .Post.Id }}
  95. var url = "/api/posts/{{.Post.Id}}";
  96. if (typeof token === 'undefined' || !token) {
  97. token = "";
  98. }
  99. params.token = token;
  100. {{ else }}
  101. var url = "/api/posts";
  102. var postTarget = '{{if .Blogs}}{{$c := index .Blogs 0}}{{$c.Alias}}{{else}}anonymous{{end}}';
  103. if (postTarget != 'anonymous') {
  104. url = "/api/collections/" + postTarget + "/posts";
  105. }
  106. {{ end }}
  107. http.open("POST", url, true);
  108. // Send the proper header information along with the request
  109. http.setRequestHeader("Content-type", "application/json");
  110. http.onreadystatechange = function() {
  111. if (http.readyState == 4) {
  112. publishing = false;
  113. if (http.status == 200 || http.status == 201) {
  114. data = JSON.parse(http.responseText);
  115. id = data.data.id;
  116. nextURL = '{{if .SingleUser}}/d{{end}}/'+id;
  117. {{ if not .Post.Id }}
  118. // Post created
  119. if (postTarget != 'anonymous') {
  120. nextURL = {{if not .SingleUser}}'/'+postTarget+{{end}}'/'+data.data.slug;
  121. }
  122. editToken = data.data.token;
  123. {{ if not .User }}if (postTarget == 'anonymous') {
  124. // Save the data
  125. var posts = JSON.parse(H.get('posts', '[]'));
  126. {{if .Post.Id}}var newPost = H.createPost("{{.Post.Id}}", token, content);
  127. for (var i=0; i<posts.length; i++) {
  128. if (posts[i].id == "{{.Post.Id}}") {
  129. posts[i].title = newPost.title;
  130. posts[i].summary = newPost.summary;
  131. break;
  132. }
  133. }
  134. nextURL = "/pad/posts";{{else}}posts.push(H.createPost(id, editToken, content));{{end}}
  135. H.set('posts', JSON.stringify(posts));
  136. }
  137. {{ end }}
  138. {{ end }}
  139. justPublished = true;
  140. if (draftDoc != 'lastDoc') {
  141. H.remove(draftDoc);
  142. {{if .Editing}}H.remove('draft{{.Post.Id}}font');{{end}}
  143. } else {
  144. H.set(draftDoc, '');
  145. }
  146. {{if .EditCollection}}
  147. window.location = '{{.EditCollection.CanonicalURL}}{{.Post.Slug}}';
  148. {{else}}
  149. window.location = nextURL;
  150. {{end}}
  151. } else {
  152. $btnPublish.el.textContent = 'Post';
  153. alert("Failed to post. Please try again.");
  154. }
  155. }
  156. }
  157. http.send(JSON.stringify(params));
  158. };
  159. setButtonStates();
  160. $writer.on('keyup input', function() {
  161. setButtonStates();
  162. clearTimeout(typingTimer);
  163. typingTimer = setTimeout(doneTyping, doneTypingInterval);
  164. }, false);
  165. $writer.on('keydown', function(e) {
  166. clearTimeout(typingTimer);
  167. if (e.keyCode == 13 && (e.metaKey || e.ctrlKey)) {
  168. $btnPublish.el.click();
  169. }
  170. });
  171. $btnPublish.on('click', function(e) {
  172. e.preventDefault();
  173. if (!publishing && $writer.el.value) {
  174. var content = $writer.el.value;
  175. publish(content, selectedFont);
  176. }
  177. });
  178. WebFontConfig = {
  179. custom: { families: [ 'Lora:400,700:latin' ], urls: [ '/css/fonts.css' ] }
  180. };
  181. var selectedFont = H.get('{{if .Editing}}draft{{.Post.Id}}font{{else}}padFont{{end}}', '{{.Post.Font}}');
  182. var doneTyping = function() {
  183. if (draftDoc == 'lastDoc' || $writer.el.value != origDoc) {
  184. H.save($writer, draftDoc);
  185. updateWordCount();
  186. }
  187. };
  188. window.addEventListener('beforeunload', function(e) {
  189. if (draftDoc != 'lastDoc' && $writer.el.value == origDoc) {
  190. H.remove(draftDoc);
  191. } else if (!justPublished) {
  192. doneTyping();
  193. }
  194. });
  195. try {
  196. (function() {
  197. var wf=document.createElement('script');
  198. wf.src = '/js/webfont.js';
  199. wf.type='text/javascript';
  200. wf.async='true';
  201. var s=document.getElementsByTagName('script')[0];
  202. s.parentNode.insertBefore(wf, s);
  203. })();
  204. } catch (e) {
  205. // whatevs
  206. }
  207. </script>
  208. </body>
  209. </html>{{end}}