Browse Source

Add a HTML frontend

master
Les De Ridder 3 years ago
parent
commit
15d293d9c0

+ 39
- 1
app/Http/Controllers/PasteController.php View File

@@ -10,6 +10,7 @@ use App\Paste;
10 10
 
11 11
 use Pygmentize\Pygmentize;
12 12
 use Carbon\Carbon;
13
+use Carbon\CarbonInterval;
13 14
 
14 15
 class PasteController extends Controller
15 16
 {
@@ -20,7 +21,7 @@ class PasteController extends Controller
20 21
 		$paste = new Paste;
21 22
 		$paste->id = Paste::create_id();
22 23
 		$paste->created_at = $request->input('available_at', Carbon::now());
23
-		$paste->expires_at = $request->input('expires_at', null);
24
+		$paste->expires_at = $this->calculate_expiry($request->input('expire_after', null), $paste->created_at);
24 25
 		$paste->language = $request->input('language', 'text');
25 26
 		$paste->save();
26 27
 		$paste->content = $request->input('content');
@@ -35,6 +36,18 @@ class PasteController extends Controller
35 36
 		}
36 37
 	}
37 38
 
39
+	private static function calculate_expiry($expire_after, $available_at)
40
+	{
41
+		if($expire_after === null || $expire_after === "never")
42
+		{
43
+			return null;
44
+		}
45
+		else
46
+		{
47
+			return Carbon::parse($available_at)->copy()->addSeconds((int)$expire_after);
48
+		}
49
+	}
50
+
38 51
 	public function view(Request $request, Paste $paste)
39 52
 	{
40 53
 		$format = $request->input('format', 'html'); //TODO: Use HTTP content negotiation for the default format
@@ -53,6 +66,8 @@ class PasteController extends Controller
53 66
 				return $this->view_png($paste);
54 67
 			case 'terminal':
55 68
 				return $this->view_terminal($paste);
69
+			case 'irc':
70
+				return $this->view_irc($paste);
56 71
 			case 'terminal256':
57 72
 				return $this->view_terminal256($paste);
58 73
 			default:
@@ -165,6 +180,29 @@ class PasteController extends Controller
165 180
 		}
166 181
 	}
167 182
 
183
+	private function view_irc(Paste $paste)
184
+	{
185
+		//TODO: More informative messages
186
+		if($paste->deleted)
187
+		{
188
+			response('This paste was deleted.')->header('Content-Type', 'text/plain');	
189
+		}
190
+		else if($paste->is_future_paste)
191
+		{
192
+			response('This paste is not available yet.')->header('Content-Type', 'text/plain');	
193
+		}
194
+		else if($paste->has_expired)
195
+		{
196
+			response('This paste has expired.')->header('Content-Type', 'text/plain');	
197
+		}
198
+		else
199
+		{
200
+			$content = Pygmentize::highlight($paste->content, $paste->language, "utf-8", "irc");
201
+
202
+			return response($content)->header('Content-Type', 'text/plain');
203
+		}
204
+	}
205
+
168 206
 	private function view_json(Paste $paste)
169 207
 	{
170 208
 		if($paste->deleted)

+ 4
- 2
app/Http/routes.php View File

@@ -1,5 +1,7 @@
1 1
 <?php
2 2
 
3
+use Illuminate\Http\Request;
4
+
3 5
 /*
4 6
 |--------------------------------------------------------------------------
5 7
 | Application Routes
@@ -11,8 +13,8 @@
11 13
 |
12 14
 */
13 15
 
14
-Route::get('/', function () {
15
-    return view('welcome');
16
+Route::get('/', function (Request $request) {
17
+    return view('main', ['js' => $request->input('js', false)]);
16 18
 });
17 19
 
18 20
 Route::post('/paste', 'PasteController@create');

+ 5
- 0
app/Paste.php View File

@@ -77,6 +77,11 @@ class Paste extends Model
77 77
 		return $this->created_at > Carbon::now();
78 78
 	}
79 79
 
80
+	public function getIdAttribute($value)
81
+	{
82
+		return trim($value);
83
+	}
84
+
80 85
 	public function getContentAttribute()
81 86
 	{
82 87
 		if($this->deleted)

+ 128
- 0
public/pygments.css View File

@@ -0,0 +1,128 @@
1
+pre .hll { background-color: #ffffcc }
2
+pre .c { color: #60a0b0; font-style: italic } /* Comment */
3
+pre .err { border: 1px solid #FF0000 } /* Error */
4
+pre .k { color: #007020; font-weight: bold } /* Keyword */
5
+pre .o { color: #666666 } /* Operator */
6
+pre .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
7
+pre .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
8
+pre .cp { color: #007020 } /* Comment.Preproc */
9
+pre .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
10
+pre .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
11
+pre .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
12
+pre .gd { color: #A00000 } /* Generic.Deleted */
13
+pre .ge { font-style: italic } /* Generic.Emph */
14
+pre .gr { color: #FF0000 } /* Generic.Error */
15
+pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */
16
+pre .gi { color: #00A000 } /* Generic.Inserted */
17
+pre .go { color: #888888 } /* Generic.Output */
18
+pre .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
19
+pre .gs { font-weight: bold } /* Generic.Strong */
20
+pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
21
+pre .gt { color: #0044DD } /* Generic.Traceback */
22
+pre .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
23
+pre .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
24
+pre .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
25
+pre .kp { color: #007020 } /* Keyword.Pseudo */
26
+pre .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
27
+pre .kt { color: #902000 } /* Keyword.Type */
28
+pre .m { color: #40a070 } /* Literal.Number */
29
+pre .s { color: #4070a0 } /* Literal.String */
30
+pre .na { color: #4070a0 } /* Name.Attribute */
31
+pre .nb { color: #007020 } /* Name.Builtin */
32
+pre .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
33
+pre .no { color: #60add5 } /* Name.Constant */
34
+pre .nd { color: #555555; font-weight: bold } /* Name.Decorator */
35
+pre .ni { color: #d55537; font-weight: bold } /* Name.Entity */
36
+pre .ne { color: #007020 } /* Name.Exception */
37
+pre .nf { color: #06287e } /* Name.Function */
38
+pre .nl { color: #002070; font-weight: bold } /* Name.Label */
39
+pre .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
40
+pre .nt { color: #062873; font-weight: bold } /* Name.Tag */
41
+pre .nv { color: #bb60d5 } /* Name.Variable */
42
+pre .ow { color: #007020; font-weight: bold } /* Operator.Word */
43
+pre .w { color: #bbbbbb } /* Text.Whitespace */
44
+pre .mb { color: #40a070 } /* Literal.Number.Bin */
45
+pre .mf { color: #40a070 } /* Literal.Number.Float */
46
+pre .mh { color: #40a070 } /* Literal.Number.Hex */
47
+pre .mi { color: #40a070 } /* Literal.Number.Integer */
48
+pre .mo { color: #40a070 } /* Literal.Number.Oct */
49
+pre .sb { color: #4070a0 } /* Literal.String.Backtick */
50
+pre .sc { color: #4070a0 } /* Literal.String.Char */
51
+pre .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
52
+pre .s2 { color: #4070a0 } /* Literal.String.Double */
53
+pre .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
54
+pre .sh { color: #4070a0 } /* Literal.String.Heredoc */
55
+pre .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
56
+pre .sx { color: #c65d09 } /* Literal.String.Other */
57
+pre .sr { color: #235388 } /* Literal.String.Regex */
58
+pre .s1 { color: #4070a0 } /* Literal.String.Single */
59
+pre .ss { color: #517918 } /* Literal.String.Symbol */
60
+pre .bp { color: #007020 } /* Name.Builtin.Pseudo */
61
+pre .vc { color: #bb60d5 } /* Name.Variable.Class */
62
+pre .vg { color: #bb60d5 } /* Name.Variable.Global */
63
+pre .vi { color: #bb60d5 } /* Name.Variable.Instance */
64
+pre .il { color: #40a070 } /* Literal.Number.Integer.Long */.syntax pre .hll { background-color: #ffffcc }
65
+.syntax pre  { background: #f0f0f0; }
66
+.syntax pre .c { color: #60a0b0; font-style: italic } /* Comment */
67
+.syntax pre .err { border: 1px solid #FF0000 } /* Error */
68
+.syntax pre .k { color: #007020; font-weight: bold } /* Keyword */
69
+.syntax pre .o { color: #666666 } /* Operator */
70
+.syntax pre .ch { color: #60a0b0; font-style: italic } /* Comment.Hashbang */
71
+.syntax pre .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
72
+.syntax pre .cp { color: #007020 } /* Comment.Preproc */
73
+.syntax pre .cpf { color: #60a0b0; font-style: italic } /* Comment.PreprocFile */
74
+.syntax pre .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
75
+.syntax pre .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
76
+.syntax pre .gd { color: #A00000 } /* Generic.Deleted */
77
+.syntax pre .ge { font-style: italic } /* Generic.Emph */
78
+.syntax pre .gr { color: #FF0000 } /* Generic.Error */
79
+.syntax pre .gh { color: #000080; font-weight: bold } /* Generic.Heading */
80
+.syntax pre .gi { color: #00A000 } /* Generic.Inserted */
81
+.syntax pre .go { color: #888888 } /* Generic.Output */
82
+.syntax pre .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
83
+.syntax pre .gs { font-weight: bold } /* Generic.Strong */
84
+.syntax pre .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
85
+.syntax pre .gt { color: #0044DD } /* Generic.Traceback */
86
+.syntax pre .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
87
+.syntax pre .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
88
+.syntax pre .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
89
+.syntax pre .kp { color: #007020 } /* Keyword.Pseudo */
90
+.syntax pre .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
91
+.syntax pre .kt { color: #902000 } /* Keyword.Type */
92
+.syntax pre .m { color: #40a070 } /* Literal.Number */
93
+.syntax pre .s { color: #4070a0 } /* Literal.String */
94
+.syntax pre .na { color: #4070a0 } /* Name.Attribute */
95
+.syntax pre .nb { color: #007020 } /* Name.Builtin */
96
+.syntax pre .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
97
+.syntax pre .no { color: #60add5 } /* Name.Constant */
98
+.syntax pre .nd { color: #555555; font-weight: bold } /* Name.Decorator */
99
+.syntax pre .ni { color: #d55537; font-weight: bold } /* Name.Entity */
100
+.syntax pre .ne { color: #007020 } /* Name.Exception */
101
+.syntax pre .nf { color: #06287e } /* Name.Function */
102
+.syntax pre .nl { color: #002070; font-weight: bold } /* Name.Label */
103
+.syntax pre .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
104
+.syntax pre .nt { color: #062873; font-weight: bold } /* Name.Tag */
105
+.syntax pre .nv { color: #bb60d5 } /* Name.Variable */
106
+.syntax pre .ow { color: #007020; font-weight: bold } /* Operator.Word */
107
+.syntax pre .w { color: #bbbbbb } /* Text.Whitespace */
108
+.syntax pre .mb { color: #40a070 } /* Literal.Number.Bin */
109
+.syntax pre .mf { color: #40a070 } /* Literal.Number.Float */
110
+.syntax pre .mh { color: #40a070 } /* Literal.Number.Hex */
111
+.syntax pre .mi { color: #40a070 } /* Literal.Number.Integer */
112
+.syntax pre .mo { color: #40a070 } /* Literal.Number.Oct */
113
+.syntax pre .sb { color: #4070a0 } /* Literal.String.Backtick */
114
+.syntax pre .sc { color: #4070a0 } /* Literal.String.Char */
115
+.syntax pre .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
116
+.syntax pre .s2 { color: #4070a0 } /* Literal.String.Double */
117
+.syntax pre .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
118
+.syntax pre .sh { color: #4070a0 } /* Literal.String.Heredoc */
119
+.syntax pre .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
120
+.syntax pre .sx { color: #c65d09 } /* Literal.String.Other */
121
+.syntax pre .sr { color: #235388 } /* Literal.String.Regex */
122
+.syntax pre .s1 { color: #4070a0 } /* Literal.String.Single */
123
+.syntax pre .ss { color: #517918 } /* Literal.String.Symbol */
124
+.syntax pre .bp { color: #007020 } /* Name.Builtin.Pseudo */
125
+.syntax pre .vc { color: #bb60d5 } /* Name.Variable.Class */
126
+.syntax pre .vg { color: #bb60d5 } /* Name.Variable.Global */
127
+.syntax pre .vi { color: #bb60d5 } /* Name.Variable.Instance */
128
+.syntax pre .il { color: #40a070 } /* Literal.Number.Integer.Long */

+ 162
- 0
resources/views/main.blade.php View File

@@ -0,0 +1,162 @@
1
+<!DOCTYPE html>
2
+<html>
3
+	<head>
4
+		<title>pastethingy</title>
5
+
6
+		<link href="https://fonts.googleapis.com/css?family=Lato:300" rel="stylesheet" type="text/css">
7
+		<link href='https://fonts.googleapis.com/css?family=Fira+Mono|Roboto+Mono:400,300' rel='stylesheet' type='text/css'>
8
+
9
+
10
+		<style>
11
+			/* how do I CSS */		
12
+
13
+			html, body {
14
+				height: 100%;
15
+				margin: 0 auto;
16
+				font-family: 'Roboto Mono';
17
+			}
18
+
19
+			body {
20
+				width: 80%;
21
+				display: flex;
22
+				flex-flow: column;
23
+			}
24
+
25
+			header {
26
+				text-align: center;
27
+				font-family: 'Roboto Mono';
28
+				font-weight: 300;
29
+				font-size: 24px;
30
+			}
31
+
32
+			footer {
33
+				min-height: 35px;
34
+				display: flex;
35
+				justify-content: center;
36
+			}
37
+
38
+			.footer, a, p {
39
+				display: inline-block;
40
+				align-self: flex-end;
41
+				font-weight: 300;
42
+				color: #555;
43
+				margin-bottom: 0px;
44
+			}
45
+
46
+			section, form {
47
+				height: 100%;
48
+				display: flex;
49
+				flex-direction: column; 
50
+			}
51
+
52
+			input, select, textarea, div, label {
53
+				margin: 5px 0px;
54
+			}
55
+
56
+			.input-box-container {
57
+			    display: flex;
58
+   				justify-content: space-between;
59
+				flex-wrap: wrap;
60
+				margin: 0 0;
61
+			}
62
+			
63
+			label {
64
+				font-size: 12px;
65
+				font-weight: 400;
66
+			}
67
+
68
+			textarea {
69
+				height: 100%;
70
+				resize: none;
71
+				border: #ccc 1px solid;
72
+				outline: none;
73
+				padding: 5px 5px;
74
+			}
75
+		</style>
76
+		@if($js)
77
+			<script>
78
+				window.onload = function() {
79
+					document.querySelector("textarea").addEventListener('keydown',function(e) {
80
+						if(e.keyCode === 9) { //tab
81
+							var start = this.selectionStart;
82
+							var end = this.selectionEnd;
83
+				
84
+							var target = e.target;
85
+							var value = target.value;
86
+				
87
+							target.value = value.substring(0, start)
88
+								+ "\t"
89
+								+ value.substring(end);
90
+				
91
+							this.selectionStart = this.selectionEnd = start + 1;
92
+				
93
+							e.preventDefault();
94
+						}
95
+					},false);
96
+				};
97
+			</script>
98
+		@endif
99
+	</head>
100
+	<body>
101
+			<header>pastethingy</header>
102
+
103
+			<section>
104
+				<form action="/paste" method="post">
105
+					<div class="input-box-container">
106
+						<div>
107
+						<label for="language">Language:</label>
108
+						<select id="language" name="language">
109
+							<option value="text">Text</option>
110
+							<option value="c">C</option>
111
+							<option value="d">D</option>
112
+							<option value="fish">Fish</option>
113
+							<option value="html">HTML</option>
114
+							<option value="css">CSS</option>
115
+							<option value="php">PHP</option>
116
+							<option value="irc">IRC logs</option>
117
+							<option value="perl">Perl</option>
118
+							<option value="python3">Python 3</option>
119
+						</select>
120
+						</div>
121
+						<div>
122
+						<label for="available_at">Available at:</label>
123
+						<input id="available_at" name="available_at" value="{{ Carbon\Carbon::now()->format('Y-m-d H:i') }}" type="text">
124
+						</div>
125
+						<div>
126
+						<label for="expire_after">Expire:</label>
127
+						<select id="expire_after"  name="expire_after">
128
+							<option value="never">Never</option>
129
+							<option value="10">After 10 seconds</option>
130
+							<option value="60">After 1 minute</option>
131
+							<option value="180">After 3 minutes</option>
132
+							<option value="300">After 5 minutes</option>
133
+							<option value="600">After 10 minutes</option>
134
+							<option value="1800">After 30 minutes</option>
135
+							<option value="3600">After 1 hour</option>
136
+							<option value="43200">After 12 hours</option>
137
+							<option value="86400">After 1 day</option>
138
+							<option value="604800">After 1 week</option>
139
+							<option value="1209600">After 2 weeks</option>
140
+							<option value="2635200">After 1 month</option>
141
+							<option value="15811200">After 6 months</option>
142
+							<option value="31557600">After 1 year</option>
143
+						</select>
144
+						</div>
145
+					</div>
146
+					<textarea name="content"></textarea>
147
+					<input type="submit" value="Paste">
148
+					<input type="hidden" name="redirect" value="1">
149
+				</form>
150
+			</section>
151
+			<footer>
152
+			<div class="footer">
153
+				@if($js)
154
+					<a href="/">No JS version</a>
155
+				@else
156
+					<a href="/?js=1">Tab key support (requires JS)</a>
157
+				@endif
158
+				<p>&middot; Dates and times are UTC.</p>
159
+			</div>
160
+			</footer>
161
+	</body>
162
+</html>

+ 48
- 0
resources/views/paste/available.blade.php View File

@@ -0,0 +1,48 @@
1
+<!DOCTYPE html>
2
+<html>
3
+    <head>
4
+        <title>{{ $id }} &middot; pastethingy</title>
5
+
6
+        <link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
7
+
8
+        <style>
9
+            html, body {
10
+                height: 100%;
11
+            }
12
+
13
+            body {
14
+                margin: 0;
15
+                padding: 0;
16
+                width: 100%;
17
+                display: table;
18
+                font-weight: 100;
19
+                font-family: 'Lato';
20
+            }
21
+
22
+            .container {
23
+                display: table-cell;
24
+            }
25
+
26
+            .content {
27
+                display: inline-block;
28
+            }
29
+
30
+            .title {
31
+                text-align: center;
32
+                font-size: 96px;
33
+            }
34
+		</style>
35
+
36
+		<link href="/pygments.css" rel="stylesheet">
37
+    </head>
38
+    <body>
39
+        <div class="container">
40
+            <div class="content">
41
+				<div class="title">pastethingy</div>
42
+				<div class="paste">
43
+				{!! $content !!}
44
+				</div>
45
+            </div>
46
+        </div>
47
+    </body>
48
+</html>

Loading…
Cancel
Save