Browse Source

support posting code snippets

pull/96/head
Aaron Parecki 6 years ago
parent
commit
7047fe16da
No known key found for this signature in database GPG Key ID: 276C2817346D6056
4 changed files with 226 additions and 0 deletions
  1. +102
    -0
      controllers/controllers.php
  2. +5
    -0
      public/css/style.css
  3. +116
    -0
      views/new-code.php
  4. +3
    -0
      views/partials/code-bookmarklet.php

+ 102
- 0
controllers/controllers.php View File

@ -694,6 +694,108 @@ $app->post('/repost', function() use($app) {
}
});
$app->get('/code', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
$edit_data = ['content'=>'','name'=>''];
if(array_key_exists('edit', $params)) {
$source = get_micropub_source($user, $params['edit'], ['content','name']);
if(isset($source['content']) && is_array($source['content']) && isset($source['content'][0]))
$edit_data['content'] = $source['content'][0];
if(isset($source['name']) && is_array($source['name']) && isset($source['name'][0]))
$edit_data['name'] = $source['name'][0];
$url = $params['edit'];
} else {
$url = false;
}
$languages = [
'php' => ['php'],
'ruby' => ['rb'],
'python' => ['py'],
'perl' => ['pl'],
'javascript' => ['js'],
'html' => ['html','htm'],
'css' => ['css'],
'bash' => ['sh'],
'nginx' => ['conf'],
'apache' => [],
'text' => ['txt'],
];
ksort($languages);
$language_map = [];
foreach($languages as $lang=>$exts) {
foreach($exts as $ext)
$language_map[$ext] = $lang;
}
render('new-code', array(
'title' => 'New Code Snippet',
'url' => $url,
'edit_data' => $edit_data,
'token' => generate_login_token(),
'languages' => $languages,
'language_map' => $language_map,
'my_hostname' => parse_url($user->url, PHP_URL_HOST),
'authorizing' => false,
));
}
});
$app->post('/code', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();
$error = false;
if(isset($params['edit']) && $params['edit']) {
$micropub_request = [
'action' => 'update',
'url' => $params['edit'],
'replace' => [
'content' => [$params['content']]
]
];
if(isset($params['name']) && $params['name']) {
$micropub_request['replace']['name'] = [$params['name']];
}
$r = micropub_post_for_user($user, $micropub_request, null, true);
if(isset($r['location']) && $r['location'])
$location = $r['location'];
elseif(in_array($r['code'], [200,201,204]))
$location = $params['edit'];
elseif(in_array($r['code'], [401,403])) {
$location = false;
$error = 'Your Micropub endpoint denied the request. Check that Quill is authorized to update posts.';
} else {
$location = false;
$error = 'Your Micropub endpoint did not return a location header or a recognized response code';
}
} else {
$micropub_request = array(
'p3k-content-type' => 'code/' . $params['language'],
'content' => $params['content'],
);
if(isset($params['name']) && $params['name'])
$micropub_request['name'] = $params['name'];
$r = micropub_post_for_user($user, $micropub_request);
$location = $r['location'];
}
$app->response()['Content-type'] = 'application/json';
$app->response()->body(json_encode(array(
'location' => $location,
'error' => $r['error'],
'error_details' => $error,
)));
}
});
$app->get('/reply/preview', function() use($app) {
if($user=require_login($app)) {
$params = $app->request()->params();

+ 5
- 0
public/css/style.css View File

@ -202,6 +202,11 @@ body {
margin-top: 20px;
}
textarea.code-snippet {
font-size: 12px;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
/**
* nicer file upload

+ 116
- 0
views/new-code.php View File

@ -0,0 +1,116 @@
<div class="narrow">
<?= partial('partials/header') ?>
<div style="clear: both;" class="notice-pad">
<div class="alert alert-success hidden" id="test_success"><strong>Success!</strong><br>Your post should be on your website now!<br><a href="" id="post_href">View your post</a></div>
<div class="alert alert-danger hidden" id="test_error"><strong>Your endpoint did not return a Location header.</strong><br>See <a href="/creating-a-micropub-endpoint">Creating a Micropub Endpoint</a> for more information.</div>
</div>
<form role="form" style="margin-top: 20px;" id="note_form">
<div class="form-group" id="note-name">
<label for="note_name">File Name (optional)</label>
<input type="text" id="note_name" value="<?= htmlspecialchars($this->edit_data['name']) ?>" class="form-control" placeholder="">
</div>
<div class="form-group">
<label for="note_content">Code</label>
<textarea id="note_content" value="" class="form-control code-snippet" style="height: 12em;"><?= htmlspecialchars($this->edit_data['content']) ?></textarea>
</div>
<? if(!$this->url): ?>
<label for="note_language">Language</label>
<select class="form-control" id="note_language">
<?php
foreach($this->languages as $lang=>$exts):
?>
<option value="<?= $lang ?>"<?= $lang == 'text' ? ' selected="selected"' : '' ?>><?= $lang ?></option>
<?php
endforeach;
?>
</select>
<? endif; ?>
<div style="float: right; margin-top: 6px;">
<button class="btn btn-success" id="btn_post"><?= $this->url ? 'Save' : 'Post' ?></button>
</div>
<input type="hidden" id="edit_url" value="<?= $this->url ?>">
</form>
<div style="clear: both;"></div>
<hr>
<div style="text-align: right;" id="bookmarklet">
Bookmarklet: <a href="javascript:<?= js_bookmarklet('partials/code-bookmarklet', $this) ?>" class="btn btn-default btn-xs">code</a>
</div>
</div>
<script>
$(function(){
var language_map = <?= json_encode($this->language_map) ?>;
$("#note_name").on("keyup", function(){
var name = $("#note_name").val();
if(name && (m=name.match(/\.([a-z]+)$/))) {
if(language_map[m[1]]) {
$("#note_language").val(language_map[m[1]]);
}
}
});
$("#note_content").on('keyup', function(){
var scrollHeight = document.getElementById("note_content").scrollHeight;
var currentHeight = parseInt($("#note_content").css("height"));
if(Math.abs(scrollHeight - currentHeight) > 20) {
$("#note_content").css("height", (scrollHeight+30)+"px");
}
});
$("#btn_post").click(function(){
$("#btn_post").addClass("loading disabled");
var syndications = [];
$("#syndication-container button.btn-info").each(function(i,btn){
syndications.push($(btn).data('syndication'));
});
var params = {
content: $("#note_content").val(),
};
if($("#edit_url").val() != "") {
params['edit'] = $("#edit_url").val();
} else {
params['language'] = $("#note_language").val();
}
if($("#note_name").val() != "") {
params['name'] = $("#note_name").val();
}
$.post("/code", params, function(response){
if(response.location != false) {
$("#test_success").removeClass('hidden');
$("#test_error").addClass('hidden');
$("#post_href").attr("href", response.location);
$("#note_form").addClass('hidden');
window.location = response.location;
} else {
$("#test_success").addClass('hidden');
$("#test_error").removeClass('hidden');
if(response.error_details) {
$("#test_error").text(response.error_details);
}
$("#btn_post").removeClass("loading disabled");
}
});
return false;
});
});
</script>

+ 3
- 0
views/partials/code-bookmarklet.php View File

@ -0,0 +1,3 @@
(function(){
window.open("<?= Config::$base_url ?>code?"+(window.location.hostname=='<?= $this->my_hostname ?>'?"edit="+encodeURIComponent(window.location.href)+"&":"")+"token=<?= $this->token ?>");
})();

Loading…
Cancel
Save