Mirror of Quill
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.

367 lines
13 KiB

7 years ago
7 years ago
  1. <div class="narrow">
  2. <?= partial('partials/header') ?>
  3. <div style="clear: both;">
  4. <div class="alert alert-success hidden" id="test_success"><strong>Success! </strong><a href="" id="post_href">View your post</a></div>
  5. <div class="alert alert-danger hidden" id="test_error"><strong>Something went wrong!</strong><br>Your Micropub endpoint indicated that something went wrong creating the post.</div>
  6. </div>
  7. <form role="form" style="margin-top: 20px;" id="note_form">
  8. <div class="form-group" style="margin-top: 18px;">
  9. <label>Event Name</label>
  10. <input type="text" class="form-control" id="event_name" placeholder="" value="">
  11. </div>
  12. <div class="form-group" style="margin-top: 18px;">
  13. <label>Location</label>
  14. <input type="text" class="form-control" id="event_location" placeholder="" value="">
  15. <span class="help-block" id="location_preview"></span>
  16. </div>
  17. <div id="map" class="hidden" style="width: 100%; height: 180px; border-radius: 4px; border: 1px #ccc solid;"></div>
  18. <div class="form-group" id="start_date" style="margin-top: 18px;">
  19. <label>Start Date/Time</label>
  20. <div class="form-group">
  21. <input type="text" class="form-control date" placeholder="<?= date('Y-m-d') ?>" value="" style="max-width: 40%; margin-right: 4px; float: left;">
  22. <input type="text" class="form-control time" placeholder="14:30" value="" style="max-width: 40%; margin-right: 4px; float: left;">
  23. <input type="text" class="form-control timezone" placeholder="-08:00" style="max-width: 15%;">
  24. </div>
  25. </div>
  26. <div class="form-group" id="end_date" style="margin-top: 18px;">
  27. <label>End Date/Time (Optional)</label>
  28. <div class="form-group">
  29. <input type="text" class="form-control date" placeholder="<?= date('Y-m-d') ?>" value="" style="max-width: 40%; margin-right: 4px; float: left;">
  30. <input type="text" class="form-control time" placeholder="14:30" value="" style="max-width: 40%; margin-right: 4px; float: left;">
  31. <input type="text" class="form-control timezone" placeholder="-08:00" style="max-width: 15%;">
  32. </div>
  33. </div>
  34. <div id="presentation-fields" class="hidden">
  35. <div class="form-group" style="margin-top: 18px;">
  36. <label>Link to Slides</label>
  37. <input type="url" class="form-control" id="slides">
  38. </div>
  39. <div class="form-group">
  40. <label for="slides-embed">Slides Embed Code</label>
  41. <textarea id="slides-embed" class="form-control" style="height: 4em;"></textarea>
  42. </div>
  43. <div class="form-group" style="margin-top: 18px;">
  44. <label>Link to Video</label>
  45. <input type="url" class="form-control" id="video-link">
  46. </div>
  47. <div class="form-group">
  48. <label for="video-embed">Video Embed Code</label>
  49. <textarea id="video-embed" class="form-control" style="height: 4em;"></textarea>
  50. </div>
  51. <div class="form-group" style="margin-top: 18px;">
  52. <label>Conference</label>
  53. <div class="form-group">
  54. <input type="text" id="conference-name" class="form-control" style="max-width: 48%; margin-right: 4px; float: left;" placeholder="Conference Name">
  55. <input type="url" id="conference-url" class="form-control" style="max-width: 48%; margin-right: 4px; float: left;" placeholder="https://example.com">
  56. </div>
  57. <div style="clear:both;"></div>
  58. </div>
  59. </div>
  60. <div class="form-group">
  61. <label for="note_content">Content</label>
  62. <textarea id="note_content" value="" class="form-control" rows="6"></textarea>
  63. </div>
  64. <div class="form-group hidden" id="content-type-selection">
  65. <label for="note_content_type">Content Type</label>
  66. <select class="form-control" id="note_content_type">
  67. <option value="text/plain">Text</option>
  68. <option value="text/markdown">Markdown</option>
  69. </select>
  70. </div>
  71. <div class="form-group" style="margin-top: 18px;">
  72. <label for="note_category">Tags</label>
  73. <input type="text" id="note_category" value="" class="form-control">
  74. </div>
  75. <?php if($this->channels): ?>
  76. <div class="form-group">
  77. <label for="note_channel">Channel</label>
  78. <div id="channel-container">
  79. <?php
  80. echo '<select class="form-control" id="note_channel">';
  81. echo '<option value="none"></option>';
  82. foreach($this->channels as $ch) {
  83. echo '<option value="'.htmlspecialchars($ch).'" '.($ch == 'events' ? 'selected' : '').'>'
  84. . htmlspecialchars($ch)
  85. . '</option>';
  86. }
  87. echo '</select>';
  88. ?>
  89. </div>
  90. </div>
  91. <?php endif; ?>
  92. <div style="float: right; margin-top: 6px;">
  93. <button class="btn btn-success" id="btn_post">Post</button>
  94. </div>
  95. </form>
  96. </div>
  97. <link rel="stylesheet" href="/libs/bootstrap-typeahead/typeahead.css">
  98. <script src="/libs/bootstrap-typeahead/typeahead.min.js"></script>
  99. <?php if(Config::$googleMapsAPIKey): ?>
  100. <script src="https://maps.googleapis.com/maps/api/js?key=<?= Config::$googleMapsAPIKey ?>&libraries=places"></script>
  101. <?php endif ?>
  102. <script>
  103. <?php if(Config::$googleMapsAPIKey): ?>
  104. var map = new google.maps.Map(document.getElementById('map'), {
  105. center: new google.maps.LatLng(-45,122),
  106. zoom: 15
  107. });
  108. <?php else: ?>
  109. var map = null;
  110. <?php endif ?>
  111. var d = new Date();
  112. var tzOffset = tz_seconds_to_offset(d.getTimezoneOffset() * 60 * -1);
  113. var selectedPlace;
  114. if(map) {
  115. var gservice = new google.maps.places.AutocompleteService();
  116. var gplaces = new google.maps.places.PlacesService(map);
  117. var selectedPlacePin;
  118. }
  119. $(document).bind('keydown', function(e){
  120. // Easter egg: press ctrl+shift+c to reveal a content type selection
  121. if(e.keyCode == 67 && e.ctrlKey && e.shiftKey) {
  122. $("#content-type-selection").removeClass("hidden");
  123. }
  124. // Easter egg: press ctrl+shift+m to switch to markdown
  125. if(e.keyCode == 77 && e.ctrlKey && e.shiftKey) {
  126. switchToMarkdown();
  127. }
  128. // Enable "presentation mode" which adds a few fields
  129. if(e.keyCode == 80 && e.ctrlKey && e.shiftKey) {
  130. enablePresentationMode();
  131. }
  132. });
  133. function switchToMarkdown() {
  134. $("#content-type-selection select").val("text/markdown");
  135. $("#content-type-selection").removeClass("hidden");
  136. }
  137. function enablePresentationMode() {
  138. $("#presentation-fields").removeClass("hidden");
  139. }
  140. $(function(){
  141. // Start the event timezone offset in the browser's timezone
  142. $("#start_date .timezone").attr("placeholder", tzOffset);
  143. $("#end_date .timezone").attr("placeholder", tzOffset);
  144. // As soon as a time is entered, move the placeholder offset to the value
  145. $("#start_date .time").on("keydown", function(){
  146. $("#start_date .timezone").val($("#start_date .timezone").attr("placeholder"));
  147. });
  148. $("#end_date .time").on("keydown", function(){
  149. $("#end_date .timezone").val($("#end_date .timezone").attr("placeholder"));
  150. });
  151. if(map) {
  152. $("#event_location").typeahead({
  153. minLength: 3,
  154. highlight: true
  155. }, {
  156. limit: 5,
  157. async: true,
  158. source: function(query, sync, async) {
  159. gservice.getPlacePredictions({ input: query }, function(predictions, status) {
  160. if (status == google.maps.places.PlacesServiceStatus.OK) {
  161. async(predictions);
  162. }
  163. });
  164. },
  165. display: function(item) {
  166. return item.description;
  167. },
  168. templates: {
  169. suggestion: function(item) {
  170. return '<span>'+item.description+'</span>';
  171. }
  172. }
  173. }).bind('typeahead:select', function(ev, suggestion) {
  174. gplaces.getDetails({
  175. placeId: suggestion.place_id,
  176. fields: ["geometry", "name", "address_component", "url", "utc_offset"]
  177. }, function(result, status) {
  178. if(status != google.maps.places.PlacesServiceStatus.OK) {
  179. alert('Cannot find address');
  180. return;
  181. }
  182. console.log(result);
  183. map.setCenter(result.geometry.location);
  184. if(selectedPlacePin) {
  185. selectedPlacePin.setMap(null);
  186. selectedPlacePin = null;
  187. }
  188. selectedPlacePin = new google.maps.Marker({
  189. position: result.geometry.location,
  190. map: map
  191. });
  192. selectedPlace = {
  193. type: ["h-card"],
  194. properties: {
  195. name: [result.name],
  196. latitude: [result.geometry.location.lat()],
  197. longitude: [result.geometry.location.lng()],
  198. }
  199. };
  200. address = '';
  201. locality = '';
  202. region = '';
  203. country = '';
  204. for(var i in result.address_components) {
  205. if(result.address_components[i].types.includes('street_number')) {
  206. address += ' '+result.address_components[i].short_name;
  207. }
  208. if(result.address_components[i].types.includes('route')) {
  209. address += ' '+result.address_components[i].short_name;
  210. }
  211. if(result.address_components[i].types.includes('locality')) {
  212. locality = result.address_components[i].long_name;
  213. }
  214. if(result.address_components[i].types.includes('administrative_area_level_1')) {
  215. region = result.address_components[i].long_name;
  216. }
  217. if(result.address_components[i].types.includes('country')) {
  218. country = result.address_components[i].short_name;
  219. }
  220. }
  221. if(address) {
  222. selectedPlace['properties']['street-address'] = [address.trim()];
  223. }
  224. if(locality) {
  225. selectedPlace['properties']['locality'] = [locality];
  226. }
  227. if(region) {
  228. selectedPlace['properties']['region'] = [region];
  229. }
  230. if(country) {
  231. selectedPlace['properties']['country-name'] = [country];
  232. }
  233. if(result.utc_offset) {
  234. tzOffset = tz_seconds_to_offset(result.utc_offset * 60);
  235. $("#start_date .timezone").attr("placeholder", tzOffset);
  236. $("#end_date .timezone").attr("placeholder", tzOffset);
  237. if($("#start_date .timezone").val()) {
  238. $("#start_date .timezone").val($("#start_date .timezone").attr("placeholder"));
  239. }
  240. if($("#end_date .timezone").val()) {
  241. $("#end_date .timezone").val($("#end_date .timezone").attr("placeholder"));
  242. }
  243. }
  244. $("#map").removeClass("hidden");
  245. $("#location_preview").text('');
  246. });
  247. });
  248. }
  249. });
  250. $("#note_category").tokenfield({
  251. createTokensOnBlur: true,
  252. beautify: true
  253. });
  254. $("#btn_post").click(function(){
  255. var event_start = $("#start_date .date").val();
  256. if($("#start_date .time").val()) {
  257. event_start += "T"+$("#start_date .time").val()+$("#start_date .timezone").val();
  258. }
  259. var event_end;
  260. if($("#end_date .date").val()) {
  261. event_end = $("#end_date .date").val();
  262. if($("#end_date .time").val()) {
  263. event_end += "T"+$("#end_date .time").val()+$("#end_date .timezone").val();
  264. }
  265. }
  266. var properties = {
  267. name: [$("#event_name").val()],
  268. start: [event_start],
  269. location: (selectedPlace ? selectedPlace : $("#event_location").val()),
  270. category: tokenfieldToArray("#note_category"),
  271. content: $("#note_content").val()
  272. };
  273. if(event_end) {
  274. properties.end = event_end;
  275. }
  276. if($("#note_channel").val()) {
  277. properties['p3k-channel'] = $("#note_channel").val();
  278. }
  279. if(!$("#content-type-selection").hasClass("hidden")) {
  280. properties['p3k-content-type'] = $("#note_content_type").val();
  281. }
  282. if(!$("#presentation-fields").hasClass("hidden")) {
  283. properties['slides'] = $("#slides").val();
  284. properties['slides-embed'] = $("#slides-embed").val();
  285. properties['video-link'] = $("#video-link").val();
  286. properties['video-embed'] = $("#video-embed").val();
  287. if($("#conference-name").val()) {
  288. properties['conference'] = {
  289. type: 'h-event',
  290. properties: {
  291. name: $("#conference-name").val(),
  292. url: $("#conference-url").val()
  293. }
  294. };
  295. }
  296. }
  297. $.post("/micropub/postjson", {
  298. data: JSON.stringify({
  299. "type": ["h-event"],
  300. "properties": properties
  301. })
  302. }, function(response){
  303. if(response.location != false) {
  304. $("#test_success").removeClass('hidden');
  305. $("#test_error").addClass('hidden');
  306. $("#post_href").attr("href", response.location);
  307. $("#note_form").slideUp(200, function(){
  308. $(window).scrollTop($("#test_success").position().top);
  309. });
  310. } else {
  311. $("#test_success").addClass('hidden');
  312. $("#test_error").removeClass('hidden');
  313. }
  314. });
  315. return false;
  316. });
  317. </script>