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