Skip to content

Commit

Permalink
chore: initialize project
Browse files Browse the repository at this point in the history
  • Loading branch information
luderic-blackbird committed Sep 26, 2023
1 parent ec6a449 commit fa02696
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Api/HyvaPhotoSwipeInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Blackbird\HyvaPhotoSwipe\Api;

interface HyvaPhotoSwipeInterface
{
public const HYVA_PHOTO_SWIPE = 'hyva_photo_swipe';
}
20 changes: 20 additions & 0 deletions Api/RequirementsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Blackbird\HyvaPhotoSwipe\Api;

interface RequirementsInterface
{
public const URL_PHOTO_SWIPE_MIN_JS = 'Blackbird_HyvaPhotoSwipe::js/photoswipe.esm.min.js';
public const URL_PHOTO_SWIPE_LIGHTBOX_MIN_JS = 'Blackbird_HyvaPhotoSwipe::js/photoswipe-lightbox.esm.min.js';
public const URL_PHOTO_SWIPE_MIN_CSS = 'Blackbird_HyvaPhotoSwipe::css/photoswipe.min.css';

public const HYVA_PHOTO_SWIPE_LIGHTBOX_CLASS = 'PhotoSwipeLightbox';
public const HYVA_PHOTO_SWIPE_CLASS = 'PhotoSwipe';

public const REQUIRED_CLASSES = [
self::HYVA_PHOTO_SWIPE_CLASS,
self::HYVA_PHOTO_SWIPE_LIGHTBOX_CLASS
];
}
26 changes: 26 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "blackbird/hyva-photo-swipe",
"version": "1.0.0",
"authors": [
{
"name": "Blackbird Agency",
"email": "contact@bird.eu",
"homepage": "https://black.bird.eu"
}
],
"description": "An implementation of PhotoSwipe library in Hyvä Theme for Magento 2",
"type": "magento2-module",
"require": {
"magento/framework": "*",
"hyva-themes/magento2-default-theme": "*"
},
"license": "MIT",
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Blackbird\\HyvaPhotoSwipe\\": ""
}
}
}
9 changes: 9 additions & 0 deletions etc/module.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Blackbird_HyvaPhotoSwipe">
<sequence>
<module name="Hyva_Theme"/>
</sequence>
</module>
</config>
5 changes: 5 additions & 0 deletions registration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Blackbird_HyvaPhotoSwipe', __DIR__);
9 changes: 9 additions & 0 deletions view/frontend/layout/hyva_default.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="script-alpine-js">
<block name="alpine-plugin-photo-swipe" template="Blackbird_HyvaPhotoSwipe::page/js/plugins/photoSwipe.phtml"/>
</referenceBlock>
</body>
</page>
115 changes: 115 additions & 0 deletions view/frontend/templates/page/js/plugins/photoSwipe.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php
declare(strict_types=1);

use Blackbird\HyvaPhotoSwipe\Api\HyvaPhotoSwipeInterface;
use Blackbird\HyvaPhotoSwipe\Api\RequirementsInterface;
use Magento\Framework\Escaper;
use Magento\Framework\View\Element\Template;

/** @var Escaper $escaper */
/** @var Template $block */
?>
<script>
(() => {
function loadJSLightboxLibrary() {
return import('<?=
$block->getViewFileUrl(RequirementsInterface::URL_PHOTO_SWIPE_LIGHTBOX_MIN_JS)
?>');
}
function loadJSLibrary() {
return import('<?=
$block->getViewFileUrl(RequirementsInterface::URL_PHOTO_SWIPE_MIN_JS)
?>');
}
function loadCssLibrary() {
return new Promise(resolve => {
const link = document.createElement('link');
link.rel = "stylesheet";
link.type = "text/css";
link.href = '<?= $escaper->escapeUrl(
$block->getViewFileUrl(RequirementsInterface::URL_PHOTO_SWIPE_MIN_CSS)
) ?>';
link.onload = resolve;
document.head.appendChild(link);
})
}

function loadScripts() {
if(isScriptAdded()){
return;
}

Promise.all([loadJSLightboxLibrary(), loadJSLibrary(), loadCssLibrary()])
.then((results) => setWindowVariable(results));
}
function setWindowVariable(results) {
const requiredClasses = <?= json_encode(RequirementsInterface::REQUIRED_CLASSES, JSON_THROW_ON_ERROR) ?>;
const resultsWithClasses = results.filter((current) => current.default);
const classes = resultsWithClasses
.reduce((result, current) => {
result[current.default.name] = current.default;
return result;
}, {});

let successImportedClasses = 0;

requiredClasses.forEach((requiredClass) => {
if (!Object.keys(classes).includes(requiredClass)) {
throw new Error(`[HyvaPhotoSwipe] Could not load the required class ${requiredClass}`);
}

window[requiredClass] = classes[requiredClass];
successImportedClasses++;
});

if (successImportedClasses === requiredClasses.length) {
Alpine.store('<?= HyvaPhotoSwipeInterface::HYVA_PHOTO_SWIPE ?>').is_loaded = true;
}
}
function isScriptAdded() {
const requiredClasses = <?= json_encode(RequirementsInterface::REQUIRED_CLASSES, JSON_THROW_ON_ERROR) ?>;

let successImportedClasses = 0;

requiredClasses.forEach((requiredClass) => {
if (!window[requiredClass]) {
return;
}

successImportedClasses++;
});

return successImportedClasses === requiredClasses.length;
}
function isPhotoSwipeRequired() {
const scriptElements = document.querySelectorAll('script');

return Array.from(scriptElements).filter((script) => {
const scriptContent = script.textContent || script.innerText;

// Specific string searched, compatible with JS minified, ignore this script
return scriptContent.includes('PhotoSwipeLightbox(') && !scriptContent.includes('isPhotoSwipeRequired');
}).length;
}

function initializeStoreState() {
Alpine.store('<?= HyvaPhotoSwipeInterface::HYVA_PHOTO_SWIPE ?>', {
is_loaded: false,

forceLoad() {
loadScripts();
}
});
}

document.addEventListener("alpine:init", () => {
initializeStoreState();

if (!isPhotoSwipeRequired()) {
return;
}

loadScripts();
});
})();
</script>
1 change: 1 addition & 0 deletions view/frontend/web/css/photoswipe.min.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit fa02696

Please sign in to comment.