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.
 
 
 
 
 

153 lines
5.3 KiB

  1. {{define "articles"}}
  2. {{template "header" .}}
  3. <div class="snug content-container">
  4. {{if .Flashes}}<ul class="errors">
  5. {{range .Flashes}}<li class="urgent">{{.}}</li>{{end}}
  6. </ul>{{end}}
  7. {{if .Silenced}}
  8. {{template "user-silenced"}}
  9. {{end}}
  10. <h2 id="posts-header">drafts</h2>
  11. {{ if .AnonymousPosts }}
  12. <p>These are your draft posts. You can share them individually (without a blog) or move them to your blog when you're ready.</p>
  13. <div class="atoms posts">
  14. {{ range $el := .AnonymousPosts }}<div id="post-{{.ID}}" class="post">
  15. <h3><a href="/{{if $.SingleUser}}d/{{end}}{{.ID}}" itemprop="url">{{.DisplayTitle}}</a></h3>
  16. <h4>
  17. <date datetime="{{.Created}}" pubdate itemprop="datePublished" content="{{.Created}}">{{.DisplayDate}}</date>
  18. <a class="action" href="/{{if $.SingleUser}}d/{{end}}{{.ID}}/edit">edit</a>
  19. <a class="delete action" href="/{{.ID}}" onclick="delPost(event, '{{.ID}}', true)">delete</a>
  20. {{ if $.Collections }}
  21. {{if gt (len $.Collections) 1}}<div class="action flat-select">
  22. <select id="move-{{.ID}}" onchange="postActions.multiMove(this, '{{.ID}}', {{if $.SingleUser}}true{{else}}false{{end}})" title="Move this post to one of your blogs">
  23. <option style="display:none"></option>
  24. {{range $.Collections}}<option value="{{.Alias}}">{{.DisplayTitle}}</option>{{end}}
  25. </select>
  26. <label for="move-{{.ID}}">move to...</label>
  27. <img class="ic-18dp" src="/img/ic_down_arrow_dark@2x.png" />
  28. </div>{{else}}
  29. {{range $.Collections}}
  30. <a class="action" href="/{{$el.ID}}" title="Publish this post to your blog '{{.DisplayTitle}}'" onclick="postActions.move(this, '{{$el.ID}}', '{{.Alias}}', {{if $.SingleUser}}true{{else}}false{{end}});return false">move to {{.DisplayTitle}}</a>
  31. {{end}}
  32. {{end}}
  33. {{ end }}
  34. </h4>
  35. {{if .Summary}}<p>{{.SummaryHTML}}</p>{{end}}
  36. </div>{{end}}
  37. </div>{{ else }}<div id="no-posts-published">
  38. <p>Your anonymous and draft posts will show up here once you've published some. You'll be able to share them individually (without a blog) or move them to a blog when you're ready.</p>
  39. {{if not .SingleUser}}<p>Alternatively, see your blogs and their posts on your <a href="/me/c/">Blogs</a> page.</p>{{end}}
  40. <p class="text-cta"><a href="{{if .SingleUser}}/me/new{{else}}/{{end}}">Start writing</a></p></div>{{ end }}
  41. <div id="moving"></div>
  42. <h2 id="unsynced-posts-header" style="display: none">unsynced posts</h2>
  43. <div id="unsynced-posts-info" style="margin-top: 1em"></div>
  44. <div id="unsynced-posts" class="atoms"></div>
  45. </div>
  46. <script src="/js/h.js"></script>
  47. <script src="/js/postactions.js"></script>
  48. <script>
  49. var auth = true;
  50. function postsLoaded(n) {
  51. if (n == 0) {
  52. return;
  53. }
  54. document.getElementById('unsynced-posts-header').style.display = 'block';
  55. var syncing = false;
  56. var $pInfo = document.getElementById('unsynced-posts-info');
  57. $pInfo.className = 'alert info';
  58. var plural = n != 1;
  59. $pInfo.innerHTML = '<p>You have <strong>'+n+'</strong> post'+(plural?'s that aren\'t':' that isn\'t')+' synced to your account yet. <a href="#" id="btn-sync">Sync '+(plural?'them':'it')+' now</a>.</p>';
  60. var $noPosts = document.getElementById('no-posts-published');
  61. if ($noPosts != null) {
  62. $noPosts.style.display = 'none';
  63. document.getElementById('posts-header').style.display = 'none';
  64. }
  65. H.getEl('btn-sync').on('click', function(e) {
  66. e.preventDefault();
  67. if (syncing) {
  68. return;
  69. }
  70. var http = new XMLHttpRequest();
  71. var params = [];
  72. var posts = JSON.parse(H.get('posts', '[]'));
  73. if (posts.length > 0) {
  74. for (var i=0; i<posts.length; i++) {
  75. params.push({id: posts[i].id, token: posts[i].token});
  76. }
  77. }
  78. this.style.fontWeight = 'bold';
  79. this.innerText = 'Syncing '+(plural?'them':'it')+' now...';
  80. http.open("POST", "/api/posts/claim", true);
  81. // Send the proper header information along with the request
  82. http.setRequestHeader("Content-type", "application/json");
  83. http.onreadystatechange = function() {
  84. if (http.readyState == 4) {
  85. syncing = false;
  86. this.innerText = 'Importing '+(plural?'them':'it')+' now...';
  87. if (http.status == 200) {
  88. var res = JSON.parse(http.responseText);
  89. if (res.data.length > 0) {
  90. if (res.data.length != posts.length) {
  91. // TODO: handle something that royally fucked up
  92. console.error("Request and result array length didn't match!");
  93. return;
  94. }
  95. for (var i=0; i<res.data.length; i++) {
  96. if (res.data[i].code == 200) {
  97. // Post successfully claimed.
  98. for (var j=0; j<posts.length; j++) {
  99. // Find post in local store
  100. if (posts[j].id == res.data[i].post.id) {
  101. // Remove this post
  102. posts.splice(j, 1);
  103. break;
  104. }
  105. }
  106. } else {
  107. for (var j=0; j<posts.length; j++) {
  108. // Find post in local store
  109. if (posts[j].id == res.data[i].id) {
  110. // Note the error in the local post
  111. posts[j].error = res.data[i].error_msg;
  112. break;
  113. }
  114. }
  115. }
  116. }
  117. H.set('posts', JSON.stringify(posts));
  118. location.reload();
  119. }
  120. } else {
  121. // TODO: handle error visually (option to retry)
  122. console.error("Didn't work at all, man.");
  123. this.style.fontWeight = 'normal';
  124. this.innerText = 'Sync '+(plural?'them':'it')+' now';
  125. }
  126. }
  127. }
  128. http.send(JSON.stringify(params));
  129. syncing = true;
  130. });
  131. }
  132. </script>
  133. <script src="/js/posts.js"></script>
  134. {{template "footer" .}}
  135. {{end}}