Last active
June 21, 2022 20:14
-
-
Save Zerquix18/c17cc12865351d9f74ef6d201b7f1275 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{{-- allow to schedule from the top --}} | |
@push('navbar_links') | |
<li class="dropdown"> | |
<a href="javascript:void(0)" data-toggle="dropdown"> | |
Schedule <span class="caret"></span> | |
</a> | |
<ul class="dropdown-menu"> | |
<!--<li> | |
<a href="javascript:void(0)" class="scheduler__post-meme" data-image_url="@{{content}}" data-page="8memesofficial" data-pagename="8Memes"> | |
Schedule on 8Memes | |
</a> | |
</li>--> | |
<li> | |
<a href="javascript:void(0)" class="scheduler__upload" data-page="8failofficial" data-pagename="8Fail"> | |
Schedule on 8Fail | |
</a> | |
</li> | |
</ul> | |
</li> | |
@endpush | |
{{-- add the schedule buttom to each meme --}} | |
@push('meme-bottom') | |
@{{#if isImage}} | |
<div class="btn-group pull-right"> | |
<button type="button" class="btn btn-xs btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
Schedule <span class="caret"></span> | |
</button> | |
<ul class="dropdown-menu"> | |
<!--<li> | |
<a href="javascript:void(0)" class="scheduler__post-meme" data-image_url="@{{content}}" data-page="8memesofficial" data-pagename="8Memes"> | |
Schedule on 8Memes | |
</a> | |
</li>--> | |
<li> | |
<a href="javascript:void(0)" class="scheduler__post-meme" data-image_url="@{{content}}" data-page="8failofficial" data-pagename="8Fail"> | |
Schedule on 8Fail | |
</a> | |
</li> | |
</ul> | |
</div> | |
@{{/if}} | |
@endpush | |
{{-- ofc, the modal to schedule stuff --}} | |
@push('meme-finder__bottom') | |
<div class="modal fade" id="scheduler__modal-meme" tabindex="-1" role="dialog"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title" id="myModalLabel">Schedule Post</h4> | |
</div> | |
<div class="modal-body"> | |
<ul class="nav nav-tabs" role="tablist"> | |
<li role="presentation" class="active"><a href="#scheduler__tab-schedule-post" aria-controls="home" role="tab" data-toggle="tab">Schedule</a></li> | |
<li role="presentation"><a href="#scheduler__tab-scheduled-posts" aria-controls="profile" role="tab" data-toggle="tab">See scheduled posts</a></li> | |
</ul> | |
<!-- Tab panes --> | |
<div class="tab-content"> | |
<div role="tabpanel" class="tab-pane fade active in text-center" id="scheduler__tab-schedule-post" style="padding-top: 20px"> | |
<img src="" style="width: auto; height: 150px; margin-bottom: 20px" id="scheduler__image-preview"> | |
<form class="form-horizontal text-center"> | |
<div class="form-group"> | |
<div class="col-sm-offset-3 col-sm-6"> | |
<textarea rows="2" id="scheduler__input-caption" | |
class="form-control" placeholder="Add an optional caption..."></textarea> | |
</div> | |
</div> | |
<div class="form-group"> | |
<div class='input-group date col-sm-offset-2 col-sm-8' id='scheduler__datetimepicker'> | |
<input type='text' class="form-control" /> | |
<span class="input-group-addon"> | |
<span class="glyphicon glyphicon-calendar"></span> | |
</span> | |
</div> | |
</div> | |
</form> | |
</div> | |
<div style="padding: 10px" class="tab-pane fade text-center" id="scheduler__tab-scheduled-posts"> | |
<div id="scheduler__state-loading"> | |
Loading... | |
</div> | |
<div id="scheduler__state-showing" style="display: none"></div> | |
</div> | |
</div> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-default" data-dismiss="modal"> | |
Close | |
</button> | |
<button type="button" class="btn btn-primary" id="scheduler__schedule"> | |
Schedule on <span id="scheduler__page-name"></span> | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
@endpush | |
{{-- some dependencies that are gonna be needed here --}} | |
@push('styles') | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/css/bootstrap-datetimepicker.min.css" rel="stylesheet"> | |
@endpush | |
@push('scripts') | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.17.47/js/bootstrap-datetimepicker.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.5/linkify.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-linkify/2.1.5/linkify-string.min.js"></script> | |
@endpush |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The uploader. | |
* This serves as a class which will prompt a modal, upload a file | |
* and then after success, will send the image URL to a certain callback. | |
* | |
* To begin, it will be useful for the scheduler, to upload an image, | |
* get the URL and pass it to the scheduler. | |
* | |
* Then it will be useful for uploading memes and 8posts. | |
*/ | |
window.uploader = { | |
/** | |
* After the file was uploaded, we'll send the URL here. | |
* @type {Function} | |
*/ | |
callback: null, | |
run: () => { | |
if (! window.uploader.callback) { | |
return; | |
} | |
// open up | |
$('#uploader__modal').modal('show'); | |
}, | |
prepare: () => { | |
const uploadedFiles = $("#uploader__file")[0].files; | |
const pastedLinks = $("#uploader__file-link").val().length; | |
$('#uploader__upload').attr('disabled', 'disabled'); | |
if (uploadedFiles.length > 0 && ! $("#uploader__file").is('[disabled]')) { | |
window.uploader.handleUploadedImage(); | |
} else { | |
window.uploader.handlePastedLink(); | |
} | |
}, | |
upload: (file) => { | |
if (! file.type.match('image*')) { | |
alert('File must be an image.'); | |
$('#uploader__upload').removeAttr('disabled'); | |
return; | |
} | |
const reader = new FileReader(); | |
reader.onload = (e) => { | |
const binary = e.target.result; | |
$.ajax({ | |
type: "POST", | |
cache: false, | |
url: ajaxUrl + '/uploader/upload', | |
data: {binary}, | |
dataType: 'json', | |
error: () => { | |
alert('There was an error. Please try again.'); | |
$('#uploader__upload').removeAttr('disabled'); | |
}, | |
success: (result) => { | |
if (! result.success) { | |
alert(result.response); | |
$('#uploader__upload').removeAttr('disabled'); | |
return; | |
} | |
window.uploader.preCallback(); | |
window.uploader.callback(result.url); | |
}, | |
}); | |
}; | |
reader.readAsDataURL(file); | |
}, | |
/** | |
* In case an image was uploaded through the file input, | |
* it will get the image blob. | |
* | |
*/ | |
handleUploadedImage: () => { | |
const file = $('#uploader__file')[0].files[0]; | |
window.uploader.upload(file); | |
}, | |
/** | |
* In case an image was pasted in the text box, | |
* it will get the image blob. | |
*/ | |
handlePastedImage: (e) => { | |
const items = (e.clipboardData || | |
e.originalEvent.clipboardData | |
).items; | |
var file; | |
for (let i in items) { | |
let item = items[i]; | |
if (item.kind === 'file') { | |
file = item.getAsFile(); | |
} | |
} | |
if (file) { | |
window.uploader.upload(file); | |
} | |
}, | |
/** | |
* In case an image URL was pasted through the box, | |
* it will validate it and open the scheduler box | |
*/ | |
handlePastedLink: () => { | |
const imageUrl = $('#uploader__file-link').val(); | |
const element = new Image(); | |
element.onerror = () => { | |
alert('Sorry, there was an error while validating that image.'); | |
$('#uploader__upload').removeAttr('disabled'); | |
}; | |
element.onload = () => { | |
window.uploader.preCallback(); | |
window.uploader.callback(imageUrl); | |
}; | |
element.src = imageUrl; | |
}, | |
// will be called before the callback function | |
// the callback will be called on success | |
preCallback: () => { | |
$('#uploader__file-label').removeAttr('disabled'); | |
$('#uploader__form')[0].reset(); | |
// prevent them from clicking again | |
$('#uploader__upload').attr('disabled', 'disabled'); | |
// hide the uploader | |
$('#uploader__modal').modal('hide'); | |
}, // .preCallback | |
} // window.uploader |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* just to upload files | |
*/ | |
namespace App\Http\Controllers; | |
use Illuminate\Http\Request; | |
use Illuminate\Support\Facades\Storage; | |
class UploaderController extends Controller | |
{ | |
/** | |
* Gets a BLOB, stores it in a file and returns the full link | |
* Javascript will upload a file through an input, | |
* and if the user pasts an image in a box, it will get the blob too. | |
* We'll only deal with a blob. | |
*/ | |
public function upload(Request $request) | |
{ | |
$binary = $request->input('binary'); | |
if (! $binary) { | |
return response()->json( | |
[ | |
'success' => false, | |
'response' => 'No binary was sent' | |
] | |
); | |
} | |
$binary = substr($binary, strpos($binary, ",") + 1); | |
$binary = base64_decode($binary, true); | |
if (! $binary) { | |
return response()->json( | |
[ | |
'success' => false, | |
'response' => 'Could not decode base64' | |
] | |
); | |
} | |
// save da file | |
$file_name = ''; | |
while (true) { | |
$file_name = str_random(5); | |
if (! Storage::exists('public/tmp/' . $file_name)) { | |
break; | |
} | |
} | |
Storage::put('public/tmp/' . $file_name, $binary); | |
// this is f*cking awful, Laravel | |
$path = Storage::disk('local')->getDriver() | |
->getAdapter() | |
->getPathPrefix(); | |
$file_path = $path . 'public/tmp/' . $file_name; | |
$image_type = exif_imagetype($file_path); | |
$available_types = [1 => 'gif', 2 => 'jpg', 3 => 'png']; | |
if (! in_array($image_type, array_keys($available_types), true)) { | |
return response()->json( | |
[ | |
'success' => false, | |
'response' => 'This is not an image or its type is invalid' | |
] | |
); | |
} | |
list($width, $height) = getimagesize($file_path); | |
if ($width > 1500 || $height > 1500) { | |
return response()->json( | |
[ | |
'success' => false, | |
'response' => 'Max width and height is 1500' | |
] | |
); | |
} | |
// rename it and add the format | |
$format = $available_types[$image_type]; | |
$new_name = sprintf('%s.%s', $file_path, $format); | |
rename($file_path, $new_name); | |
$url = asset('storage/tmp/' . $file_name . '.'. $format); | |
return response()->json( | |
[ | |
'success' => true, | |
'url' => $url | |
] | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment