Skip to content

Commit

Permalink
Image protection (#3)
Browse files Browse the repository at this point in the history
* Added close/protect on right click
* Added temporary url to images
* Added image styles and updated modal style
* Fixed missing images
* Added headers to axios calls
  • Loading branch information
lisa-fehr authored Nov 4, 2022
1 parent f66c089 commit 539f7b3
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 77 deletions.
43 changes: 43 additions & 0 deletions public/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,9 @@ Ensure the default browser behavior of the `hidden` attribute.
-webkit-animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.cursor-pointer {
cursor: pointer;
}
.cursor-not-allowed {
cursor: not-allowed;
}
Expand All @@ -497,13 +500,25 @@ Ensure the default browser behavior of the `hidden` attribute.
.rounded {
border-radius: 0.25rem;
}
.rounded-t-md {
border-top-left-radius: 0.375rem;
border-top-right-radius: 0.375rem;
}
.rounded-b-md {
border-bottom-right-radius: 0.375rem;
border-bottom-left-radius: 0.375rem;
}
.border {
border-width: 1px;
}
.border-black {
--tw-border-opacity: 1;
border-color: rgb(0 0 0 / var(--tw-border-opacity));
}
.bg-black {
--tw-bg-opacity: 1;
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
}
.bg-stone-800 {
--tw-bg-opacity: 1;
background-color: rgb(41 37 36 / var(--tw-bg-opacity));
Expand All @@ -512,6 +527,9 @@ Ensure the default browser behavior of the `hidden` attribute.
-o-object-fit: scale-down;
object-fit: scale-down;
}
.p-2 {
padding: 0.5rem;
}
.p-1 {
padding: 0.25rem;
}
Expand All @@ -532,6 +550,14 @@ Ensure the default browser behavior of the `hidden` attribute.
.pr-2 {
padding-right: 0.5rem;
}
.text-base {
font-size: 1rem;
line-height: 1.5rem;
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));
}
.text-neutral-500 {
--tw-text-opacity: 1;
color: rgb(115 115 115 / var(--tw-text-opacity));
Expand All @@ -540,6 +566,9 @@ Ensure the default browser behavior of the `hidden` attribute.
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.opacity-75 {
opacity: 0.75;
}
.shadow {
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
Expand All @@ -555,6 +584,20 @@ Ensure the default browser behavior of the `hidden` attribute.
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.delay-150 {
transition-delay: 150ms;
}
.duration-300 {
transition-duration: 300ms;
}
.ease-in-out {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.hover\:scale-90:hover {
--tw-scale-x: .9;
--tw-scale-y: .9;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.hover\:text-orange-400:hover {
--tw-text-opacity: 1;
color: rgb(251 146 60 / var(--tw-text-opacity));
Expand Down
58 changes: 44 additions & 14 deletions public/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -19576,8 +19576,8 @@ __webpack_require__.r(__webpack_exports__);
window.history.pushState({}, '', url);
},
galleryUrl: function galleryUrl(page) {
var url = _config__WEBPACK_IMPORTED_MODULE_0__.isNotProduction ? '/gallery.json' : '/gallery';
url += "?page=" + page;
var url = _config__WEBPACK_IMPORTED_MODULE_0__.isNotProduction ? '/gallery.json' : "/gallery?timestamp=".concat(new Date().getTime());
url += "&page=" + page;

if (this.filters) {
url += '&filter[tags]=' + this.filters;
Expand All @@ -19588,7 +19588,12 @@ __webpack_require__.r(__webpack_exports__);
getImages: function getImages(page) {
var _this = this;

axios.get(this.galleryUrl(page)).then(function (response) {
axios.get(this.galleryUrl(page), {
headers: {
'Content-Type': 'application/json',
'X-Robots-Tag': 'noindex, nofollow'
}
}).then(function (response) {
var _response$data = response.data,
data = _response$data.data,
current_page = _response$data.current_page,
Expand Down Expand Up @@ -19629,7 +19634,8 @@ __webpack_require__.r(__webpack_exports__);
props: {
image: {
required: false,
type: String
type: Object,
"default": null
}
}
});
Expand Down Expand Up @@ -19686,7 +19692,12 @@ __webpack_require__.r(__webpack_exports__);
_this = this;

var url = _config__WEBPACK_IMPORTED_MODULE_0__.isNotProduction ? '/tags.json' : '/tags/';
axios.get(url + ((_this$filters = this.filters) !== null && _this$filters !== void 0 ? _this$filters : '')).then(function (response) {
axios.get(url + ((_this$filters = this.filters) !== null && _this$filters !== void 0 ? _this$filters : ''), {
headers: {
'Content-Type': 'application/json',
'X-Robots-Tag': 'noindex, nofollow'
}
}).then(function (response) {
_this.navigation = response.data;

_this.removeTheAllTag();
Expand Down Expand Up @@ -19987,8 +19998,9 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
alt: image.alt,
image: image.thumbnail,
key: "image-".concat(index),
onContextmenu: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(function () {}, ["prevent"])),
onClick: function onClick($event) {
return $data.currentImage = image.image;
return $data.currentImage = image;
}
}, null, 8
/* PROPS */
Expand All @@ -20007,7 +20019,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
}, [$data.currentImage ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(_component_modal, {
key: 0,
image: $data.currentImage,
onClose: _cache[0] || (_cache[0] = function ($event) {
onClose: _cache[1] || (_cache[1] = function ($event) {
return $data.currentImage = null;
})
}, null, 8
Expand Down Expand Up @@ -20038,21 +20050,39 @@ var _withScopeId = function _withScopeId(n) {
};

var _hoisted_1 = {
key: 0,
"class": "modal"
};
var _hoisted_2 = ["src"];
var _hoisted_2 = {
"class": "rounded-t-md flex justify-between bg-black opacity-75 text-base text-gray-500 p-2"
};

var _hoisted_3 = /*#__PURE__*/_withScopeId(function () {
return /*#__PURE__*/(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", null, "Click to Close", -1
/* HOISTED */
);
});

var _hoisted_4 = ["src"];
function render(_ctx, _cache, $props, $setup, $data, $options) {
return (0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
"class": "shadow",
onClick: _cache[0] || (_cache[0] = function ($event) {
onContextmenu: _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(function ($event) {
return _ctx.$emit("close");
}, ["prevent"])),
onClick: _cache[1] || (_cache[1] = function ($event) {
return _ctx.$emit("close");
})
}, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("img", {
src: $props.image,
"class": "object-scale-down max-w-screen max-h-screen"
}, [$props.image ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [(0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.image.alt), 1
/* TEXT */
), _hoisted_3]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("img", {
src: $props.image.image,
"class": "rounded-b-md cursor-pointer object-scale-down max-w-screen max-h-screen"
}, null, 8
/* PROPS */
, _hoisted_2)])]);
, _hoisted_4)])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)], 32
/* HYDRATE_EVENTS */
);
}

/***/ }),
Expand Down Expand Up @@ -20290,7 +20320,7 @@ var _hoisted_1 = ["src", "alt"];
function render(_ctx, _cache, $props, $setup, $data, $options) {
return $props.image ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("img", {
key: 0,
"class": "w-full",
"class": "transition delay-150 duration-300 ease-in-out hover:scale-90 cursor-pointer w-full",
src: $props.image,
alt: $props.alt
}, null, 8
Expand Down
36 changes: 28 additions & 8 deletions src/Console/Commands/GenerateImages.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

class GenerateImages extends Command
{
const MISSING_IMAGE_COLOR = '#ffb52e';

const THUMBNAIL_WIDTH = 125;
const THUMBNAIL_HEIGHT = 175;
const THUMBNAIL_QUALITY = 75;
Expand Down Expand Up @@ -39,7 +41,7 @@ class GenerateImages extends Command
*
* @return int
*/
public function handle()
public function handle() : int
{
$originalImages = Storage::disk("gallery-originals")->allFiles();

Expand All @@ -58,6 +60,7 @@ public function handle()
}

$this->createMissingThumbnail();
$this->createMissingImage();

return 0;
}
Expand All @@ -82,7 +85,7 @@ private function resizeImage($originalImage)
->save($thumbPath, self::THUMBNAIL_QUALITY, pathinfo($gallery->thumb, PATHINFO_EXTENSION));

$image = Image::make($originalPath);
list($width, $height) = $this->calculateWidthHeight($image);
[$width, $height] = $this->calculateWidthHeight($image);
$image->resize($width, $height, function ($constraint) {
$constraint->aspectRatio();
})->save($imagePath);
Expand All @@ -97,7 +100,7 @@ private function resizeImage($originalImage)
* @param \Intervention\Image\Image $image
* @return array
*/
private function calculateWidthHeight(\Intervention\Image\Image $image)
private function calculateWidthHeight(\Intervention\Image\Image $image) : array
{
$width = self::MAX_IMAGE_WIDTH;
$height = self::MAX_IMAGE_HEIGHT;
Expand All @@ -116,15 +119,32 @@ private function createMissingThumbnail()
$img = Image::canvas(self::THUMBNAIL_WIDTH, self::THUMBNAIL_HEIGHT, '#ffa500');
$img
->line(0, 0, self::THUMBNAIL_WIDTH, self::THUMBNAIL_HEIGHT, function ($draw) {
$draw->color('#ffb52e');
$draw->color(self::MISSING_IMAGE_COLOR);
})
->line(self::THUMBNAIL_WIDTH, 0, 0, self::THUMBNAIL_HEIGHT, function ($draw) {
$draw->color('#ffb52e');
$draw->color(self::MISSING_IMAGE_COLOR);
})
->text('Missing Image', 28, 20, function ($font) {
->text('Missing Image', round(self::THUMBNAIL_WIDTH / 2 - 34), 20, function ($font) {
$font->color('#000');
});
$img->save(Storage::disk('gallery')->path('missing.gif'), 90, 'gif');
$this->info('Created missing image: ' . Storage::disk('gallery')->path('missing.gif'));
$img->save(Storage::disk('gallery')->path('missing-thumbnail.gif'), 90, 'gif');
$this->info('Created missing thumbnail: ' . Storage::disk('gallery')->path('missing-thumbnail.gif'));
}

private function createMissingImage()
{
$img = Image::canvas(self::MAX_IMAGE_WIDTH, self::MAX_IMAGE_HEIGHT, '#ffa500');
$img
->line(0, 0, self::MAX_IMAGE_WIDTH, self::MAX_IMAGE_HEIGHT, function ($draw) {
$draw->color(self::MISSING_IMAGE_COLOR);
})
->line(self::MAX_IMAGE_WIDTH, 0, 0, self::MAX_IMAGE_HEIGHT, function ($draw) {
$draw->color(self::MISSING_IMAGE_COLOR);
})
->text('Missing Image', round(self::MAX_IMAGE_WIDTH / 2 - 34), 20, function ($font) {
$font->color('#000');
});
$img->save(Storage::disk('gallery')->path('missing-image.gif'), 90, 'gif');
$this->info('Created missing image: ' . Storage::disk('gallery')->path('missing-image.gif'));
}
}
15 changes: 0 additions & 15 deletions src/Http/Controllers/Controller.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Http/Controllers/GalleryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;

class GalleryController extends Controller
class GalleryController
{
public function __invoke()
{
Expand Down
8 changes: 4 additions & 4 deletions src/Http/Controllers/TagController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
use LisaFehr\Gallery\Models\UberTags;
use Illuminate\Support\Facades\Route;

class TagController extends Controller
class TagController
{
public function __invoke($filters = '')
{
if (empty($filters)) {
return response()->json([
'children' =>
UberTags::where('parent', 0)
UberTags::query()->where('parent', 0)
->get()
->filter(function ($tag) {
return Route::has($tag->name);
Expand All @@ -25,11 +25,11 @@ public function __invoke($filters = '')
$childFilters = array_slice($names, 1);

return response()->json([
'current' => UberTags::where('name', $currentFilter)
'current' => UberTags::query()->where('name', $currentFilter)
->with('parent')
->first(),
'children' =>
UberTags::whereIn('name', $childFilters)
UberTags::query()->whereIn('name', $childFilters)
//->children()
->with('parent')
->orderBy('name')
Expand Down
Loading

0 comments on commit 539f7b3

Please sign in to comment.