Add a HTML frontend
This commit is contained in:
parent
21aa7e2dcf
commit
15d293d9c0
|
@ -10,6 +10,7 @@ use App\Paste;
|
|||
|
||||
use Pygmentize\Pygmentize;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonInterval;
|
||||
|
||||
class PasteController extends Controller
|
||||
{
|
||||
|
@ -20,7 +21,7 @@ class PasteController extends Controller
|
|||
$paste = new Paste;
|
||||
$paste->id = Paste::create_id();
|
||||
$paste->created_at = $request->input('available_at', Carbon::now());
|
||||
$paste->expires_at = $request->input('expires_at', null);
|
||||
$paste->expires_at = $this->calculate_expiry($request->input('expire_after', null), $paste->created_at);
|
||||
$paste->language = $request->input('language', 'text');
|
||||
$paste->save();
|
||||
$paste->content = $request->input('content');
|
||||
|
@ -35,6 +36,18 @@ class PasteController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
private static function calculate_expiry($expire_after, $available_at)
|
||||
{
|
||||
if($expire_after === null || $expire_after === "never")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Carbon::parse($available_at)->copy()->addSeconds((int)$expire_after);
|
||||
}
|
||||
}
|
||||
|
||||
public function view(Request $request, Paste $paste)
|
||||
{
|
||||
$format = $request->input('format', 'html'); //TODO: Use HTTP content negotiation for the default format
|
||||
|
@ -53,6 +66,8 @@ class PasteController extends Controller
|
|||
return $this->view_png($paste);
|
||||
case 'terminal':
|
||||
return $this->view_terminal($paste);
|
||||
case 'irc':
|
||||
return $this->view_irc($paste);
|
||||
case 'terminal256':
|
||||
return $this->view_terminal256($paste);
|
||||
default:
|
||||
|
@ -165,6 +180,29 @@ class PasteController extends Controller
|
|||
}
|
||||
}
|
||||
|
||||
private function view_irc(Paste $paste)
|
||||
{
|
||||
//TODO: More informative messages
|
||||
if($paste->deleted)
|
||||
{
|
||||
response('This paste was deleted.')->header('Content-Type', 'text/plain');
|
||||
}
|
||||
else if($paste->is_future_paste)
|
||||
{
|
||||
response('This paste is not available yet.')->header('Content-Type', 'text/plain');
|
||||
}
|
||||
else if($paste->has_expired)
|
||||
{
|
||||
response('This paste has expired.')->header('Content-Type', 'text/plain');
|
||||
}
|
||||
else
|
||||
{
|
||||
$content = Pygmentize::highlight($paste->content, $paste->language, "utf-8", "irc");
|
||||
|
||||
return response($content)->header('Content-Type', 'text/plain');
|
||||
}
|
||||
}
|
||||
|
||||
private function view_json(Paste $paste)
|
||||
{
|
||||
if($paste->deleted)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Application Routes
|
||||
|
@ -11,8 +13,8 @@
|
|||
|
|
||||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
Route::get('/', function (Request $request) {
|
||||
return view('main', ['js' => $request->input('js', false)]);
|
||||
});
|
||||
|
||||
Route::post('/paste', 'PasteController@create');
|
||||
|
|
|
@ -77,6 +77,11 @@ class Paste extends Model
|
|||
return $this->created_at > Carbon::now();
|
||||
}
|
||||
|
||||
public function getIdAttribute($value)
|
||||
{
|
||||
return trim($value);
|
||||
}
|
||||
|
||||
public function getContentAttribute()
|
||||
{
|
||||
if($this->deleted)
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
pre .hll { background-color: #ffffcc }
|
||||
pre .c { color: #60a0b0; font-style: italic } /* Comment */
|
||||
pre .err { border: 1px solid #FF0000 } /* Error */
|
||||
pre .k { color: #007020; font-weight: bold } /* Keyword */
|
||||
pre .o { color: #666666 } /* Operator */
|
||||
pre .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
|
||||
pre .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
|
||||
pre .cp { color: #007020 } /* Comment.Preproc */
|
||||
pre .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
|
||||
pre .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
|
||||
pre .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
|
||||
pre .gd { color: #A00000 } /* Generic.Deleted */
|
||||
pre .ge { font-style: italic } /* Generic.Emph */
|
||||
pre .gr { color: #FF0000 } /* Generic.Error */
|
||||
pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
pre .gi { color: #00A000 } /* Generic.Inserted */
|
||||
pre .go { color: #888888 } /* Generic.Output */
|
||||
pre .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
|
||||
pre .gs { font-weight: bold } /* Generic.Strong */
|
||||
pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
pre .gt { color: #0044DD } /* Generic.Traceback */
|
||||
pre .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
|
||||
pre .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
|
||||
pre .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
|
||||
pre .kp { color: #007020 } /* Keyword.Pseudo */
|
||||
pre .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
|
||||
pre .kt { color: #902000 } /* Keyword.Type */
|
||||
pre .m { color: #40a070 } /* Literal.Number */
|
||||
pre .s { color: #4070a0 } /* Literal.String */
|
||||
pre .na { color: #4070a0 } /* Name.Attribute */
|
||||
pre .nb { color: #007020 } /* Name.Builtin */
|
||||
pre .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
|
||||
pre .no { color: #60add5 } /* Name.Constant */
|
||||
pre .nd { color: #555555; font-weight: bold } /* Name.Decorator */
|
||||
pre .ni { color: #d55537; font-weight: bold } /* Name.Entity */
|
||||
pre .ne { color: #007020 } /* Name.Exception */
|
||||
pre .nf { color: #06287e } /* Name.Function */
|
||||
pre .nl { color: #002070; font-weight: bold } /* Name.Label */
|
||||
pre .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
|
||||
pre .nt { color: #062873; font-weight: bold } /* Name.Tag */
|
||||
pre .nv { color: #bb60d5 } /* Name.Variable */
|
||||
pre .ow { color: #007020; font-weight: bold } /* Operator.Word */
|
||||
pre .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
pre .mb { color: #40a070 } /* Literal.Number.Bin */
|
||||
pre .mf { color: #40a070 } /* Literal.Number.Float */
|
||||
pre .mh { color: #40a070 } /* Literal.Number.Hex */
|
||||
pre .mi { color: #40a070 } /* Literal.Number.Integer */
|
||||
pre .mo { color: #40a070 } /* Literal.Number.Oct */
|
||||
pre .sb { color: #4070a0 } /* Literal.String.Backtick */
|
||||
pre .sc { color: #4070a0 } /* Literal.String.Char */
|
||||
pre .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
|
||||
pre .s2 { color: #4070a0 } /* Literal.String.Double */
|
||||
pre .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
|
||||
pre .sh { color: #4070a0 } /* Literal.String.Heredoc */
|
||||
pre .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
|
||||
pre .sx { color: #c65d09 } /* Literal.String.Other */
|
||||
pre .sr { color: #235388 } /* Literal.String.Regex */
|
||||
pre .s1 { color: #4070a0 } /* Literal.String.Single */
|
||||
pre .ss { color: #517918 } /* Literal.String.Symbol */
|
||||
pre .bp { color: #007020 } /* Name.Builtin.Pseudo */
|
||||
pre .vc { color: #bb60d5 } /* Name.Variable.Class */
|
||||
pre .vg { color: #bb60d5 } /* Name.Variable.Global */
|
||||
pre .vi { color: #bb60d5 } /* Name.Variable.Instance */
|
||||
pre .il { color: #40a070 } /* Literal.Number.Integer.Long */.syntax pre .hll { background-color: #ffffcc }
|
||||
.syntax pre { background: #f0f0f0; }
|
||||
.syntax pre .c { color: #60a0b0; font-style: italic } /* Comment */
|
||||
.syntax pre .err { border: 1px solid #FF0000 } /* Error */
|
||||
.syntax pre .k { color: #007020; font-weight: bold } /* Keyword */
|
||||
.syntax pre .o { color: #666666 } /* Operator */
|
||||
.syntax pre .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
|
||||
.syntax pre .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
|
||||
.syntax pre .cp { color: #007020 } /* Comment.Preproc */
|
||||
.syntax pre .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
|
||||
.syntax pre .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
|
||||
.syntax pre .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
|
||||
.syntax pre .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.syntax pre .ge { font-style: italic } /* Generic.Emph */
|
||||
.syntax pre .gr { color: #FF0000 } /* Generic.Error */
|
||||
.syntax pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.syntax pre .gi { color: #00A000 } /* Generic.Inserted */
|
||||
.syntax pre .go { color: #888888 } /* Generic.Output */
|
||||
.syntax pre .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
|
||||
.syntax pre .gs { font-weight: bold } /* Generic.Strong */
|
||||
.syntax pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.syntax pre .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.syntax pre .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
|
||||
.syntax pre .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
|
||||
.syntax pre .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
|
||||
.syntax pre .kp { color: #007020 } /* Keyword.Pseudo */
|
||||
.syntax pre .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
|
||||
.syntax pre .kt { color: #902000 } /* Keyword.Type */
|
||||
.syntax pre .m { color: #40a070 } /* Literal.Number */
|
||||
.syntax pre .s { color: #4070a0 } /* Literal.String */
|
||||
.syntax pre .na { color: #4070a0 } /* Name.Attribute */
|
||||
.syntax pre .nb { color: #007020 } /* Name.Builtin */
|
||||
.syntax pre .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
|
||||
.syntax pre .no { color: #60add5 } /* Name.Constant */
|
||||
.syntax pre .nd { color: #555555; font-weight: bold } /* Name.Decorator */
|
||||
.syntax pre .ni { color: #d55537; font-weight: bold } /* Name.Entity */
|
||||
.syntax pre .ne { color: #007020 } /* Name.Exception */
|
||||
.syntax pre .nf { color: #06287e } /* Name.Function */
|
||||
.syntax pre .nl { color: #002070; font-weight: bold } /* Name.Label */
|
||||
.syntax pre .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
|
||||
.syntax pre .nt { color: #062873; font-weight: bold } /* Name.Tag */
|
||||
.syntax pre .nv { color: #bb60d5 } /* Name.Variable */
|
||||
.syntax pre .ow { color: #007020; font-weight: bold } /* Operator.Word */
|
||||
.syntax pre .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.syntax pre .mb { color: #40a070 } /* Literal.Number.Bin */
|
||||
.syntax pre .mf { color: #40a070 } /* Literal.Number.Float */
|
||||
.syntax pre .mh { color: #40a070 } /* Literal.Number.Hex */
|
||||
.syntax pre .mi { color: #40a070 } /* Literal.Number.Integer */
|
||||
.syntax pre .mo { color: #40a070 } /* Literal.Number.Oct */
|
||||
.syntax pre .sb { color: #4070a0 } /* Literal.String.Backtick */
|
||||
.syntax pre .sc { color: #4070a0 } /* Literal.String.Char */
|
||||
.syntax pre .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
|
||||
.syntax pre .s2 { color: #4070a0 } /* Literal.String.Double */
|
||||
.syntax pre .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
|
||||
.syntax pre .sh { color: #4070a0 } /* Literal.String.Heredoc */
|
||||
.syntax pre .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
|
||||
.syntax pre .sx { color: #c65d09 } /* Literal.String.Other */
|
||||
.syntax pre .sr { color: #235388 } /* Literal.String.Regex */
|
||||
.syntax pre .s1 { color: #4070a0 } /* Literal.String.Single */
|
||||
.syntax pre .ss { color: #517918 } /* Literal.String.Symbol */
|
||||
.syntax pre .bp { color: #007020 } /* Name.Builtin.Pseudo */
|
||||
.syntax pre .vc { color: #bb60d5 } /* Name.Variable.Class */
|
||||
.syntax pre .vg { color: #bb60d5 } /* Name.Variable.Global */
|
||||
.syntax pre .vi { color: #bb60d5 } /* Name.Variable.Instance */
|
||||
.syntax pre .il { color: #40a070 } /* Literal.Number.Integer.Long */
|
|
@ -0,0 +1,162 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>pastethingy</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:300" rel="stylesheet" type="text/css">
|
||||
<link href='https://fonts.googleapis.com/css?family=Fira+Mono|Roboto+Mono:400,300' rel='stylesheet' type='text/css'>
|
||||
|
||||
|
||||
<style>
|
||||
/* how do I CSS */
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
font-family: 'Roboto Mono';
|
||||
}
|
||||
|
||||
body {
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
font-family: 'Roboto Mono';
|
||||
font-weight: 300;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
footer {
|
||||
min-height: 35px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.footer, a, p {
|
||||
display: inline-block;
|
||||
align-self: flex-end;
|
||||
font-weight: 300;
|
||||
color: #555;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
section, form {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
input, select, textarea, div, label {
|
||||
margin: 5px 0px;
|
||||
}
|
||||
|
||||
.input-box-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 0;
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 100%;
|
||||
resize: none;
|
||||
border: #ccc 1px solid;
|
||||
outline: none;
|
||||
padding: 5px 5px;
|
||||
}
|
||||
</style>
|
||||
@if($js)
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelector("textarea").addEventListener('keydown',function(e) {
|
||||
if(e.keyCode === 9) { //tab
|
||||
var start = this.selectionStart;
|
||||
var end = this.selectionEnd;
|
||||
|
||||
var target = e.target;
|
||||
var value = target.value;
|
||||
|
||||
target.value = value.substring(0, start)
|
||||
+ "\t"
|
||||
+ value.substring(end);
|
||||
|
||||
this.selectionStart = this.selectionEnd = start + 1;
|
||||
|
||||
e.preventDefault();
|
||||
}
|
||||
},false);
|
||||
};
|
||||
</script>
|
||||
@endif
|
||||
</head>
|
||||
<body>
|
||||
<header>pastethingy</header>
|
||||
|
||||
<section>
|
||||
<form action="/paste" method="post">
|
||||
<div class="input-box-container">
|
||||
<div>
|
||||
<label for="language">Language:</label>
|
||||
<select id="language" name="language">
|
||||
<option value="text">Text</option>
|
||||
<option value="c">C</option>
|
||||
<option value="d">D</option>
|
||||
<option value="fish">Fish</option>
|
||||
<option value="html">HTML</option>
|
||||
<option value="css">CSS</option>
|
||||
<option value="php">PHP</option>
|
||||
<option value="irc">IRC logs</option>
|
||||
<option value="perl">Perl</option>
|
||||
<option value="python3">Python 3</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="available_at">Available at:</label>
|
||||
<input id="available_at" name="available_at" value="{{ Carbon\Carbon::now()->format('Y-m-d H:i') }}" type="text">
|
||||
</div>
|
||||
<div>
|
||||
<label for="expire_after">Expire:</label>
|
||||
<select id="expire_after" name="expire_after">
|
||||
<option value="never">Never</option>
|
||||
<option value="10">After 10 seconds</option>
|
||||
<option value="60">After 1 minute</option>
|
||||
<option value="180">After 3 minutes</option>
|
||||
<option value="300">After 5 minutes</option>
|
||||
<option value="600">After 10 minutes</option>
|
||||
<option value="1800">After 30 minutes</option>
|
||||
<option value="3600">After 1 hour</option>
|
||||
<option value="43200">After 12 hours</option>
|
||||
<option value="86400">After 1 day</option>
|
||||
<option value="604800">After 1 week</option>
|
||||
<option value="1209600">After 2 weeks</option>
|
||||
<option value="2635200">After 1 month</option>
|
||||
<option value="15811200">After 6 months</option>
|
||||
<option value="31557600">After 1 year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<textarea name="content"></textarea>
|
||||
<input type="submit" value="Paste">
|
||||
<input type="hidden" name="redirect" value="1">
|
||||
</form>
|
||||
</section>
|
||||
<footer>
|
||||
<div class="footer">
|
||||
@if($js)
|
||||
<a href="/">No JS version</a>
|
||||
@else
|
||||
<a href="/?js=1">Tab key support (requires JS)</a>
|
||||
@endif
|
||||
<p>· Dates and times are UTC.</p>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ $id }} · pastethingy</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
display: table;
|
||||
font-weight: 100;
|
||||
font-family: 'Lato';
|
||||
}
|
||||
|
||||
.container {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 96px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link href="/pygments.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div class="title">pastethingy</div>
|
||||
<div class="paste">
|
||||
{!! $content !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue