Skip to content

Instantly share code, notes, and snippets.

@Zerquix18
Last active June 21, 2022 20:14
Show Gist options
  • Save Zerquix18/c17cc12865351d9f74ef6d201b7f1275 to your computer and use it in GitHub Desktop.
Save Zerquix18/c17cc12865351d9f74ef6d201b7f1275 to your computer and use it in GitHub Desktop.
{{-- 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">&times;</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
/**
* 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
<?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