diff --git a/.gitignore b/.gitignore
index 2c74cbb..9bc33e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -65,3 +65,4 @@ vendor/canary/logs/*
components/*
mailhog.log
uploads/*
+images/qr-codes/
diff --git a/app/controllers/admin/images.php b/app/controllers/admin/images.php
index 690cdaf..20ca7b1 100644
--- a/app/controllers/admin/images.php
+++ b/app/controllers/admin/images.php
@@ -76,25 +76,6 @@ class Images extends AdminController {
Views::view( 'admin.images.upload' );
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
private function getFolderObject( $folder, $subdirs = '' ) {
$names = explode( DIRECTORY_SEPARATOR, $folder );
$folderName = array_pop( $names );
@@ -155,28 +136,6 @@ class Images extends AdminController {
return $dirs;
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public function __construct() {
parent::__construct();
self::$title = 'Admin - Images';
@@ -204,25 +163,6 @@ class Images extends AdminController {
Debug::error( 'There was an error with your upload.');
Issues::add( 'error', [ 'There was an error with your upload.' => Check::userErrors() ] );
}
-
-
-
-
-
-
-
-
-
- // if ( self::$token->create(
- // Input::post( 'name' ),
- // Input::post( 'notes' ),
- // Input::post( 'token_type' )
- // ) ) {
- // Session::flash( 'success', 'Token Created' );
- // Redirect::to( 'admin/images' );
- // }
-
-
}
Views::view( 'admin.images.create' );
}
@@ -261,7 +201,6 @@ class Images extends AdminController {
}
public function rename() {
-
if ( ! Input::exists( 'fileLocation' ) ) {
Session::flash( 'warning', 'Unknown image.' );
Redirect::to( 'admin/images' );
@@ -274,7 +213,6 @@ class Images extends AdminController {
Issues::add( 'error', [ 'There was an error renaming the image.' => Check::userErrors() ] );
} else {
$result = $this->renameFile( Input::post( 'filelocation' ), Input::post( 'newname' ) );
-
if ( ! empty( $result ) ) {
Session::flash( 'success', 'Image has been renamed.' );
Redirect::to( 'admin/images' );
diff --git a/app/js/main.js b/app/js/main.js
index c22fc1f..052d3b9 100644
--- a/app/js/main.js
+++ b/app/js/main.js
@@ -8,6 +8,61 @@
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
+
+let deferredPrompt;
+const installPrompt = document.getElementById("install-prompt");
+const installButton = document.getElementById("install-button");
+const dismissButton = document.querySelector("#install-prompt .btn-close");
+
+// Check if the user previously dismissed the prompt
+if (!localStorage.getItem("pwaInstallDismissed")) {
+ window.addEventListener("beforeinstallprompt", (event) => {
+ event.preventDefault();
+ deferredPrompt = event;
+ installPrompt.classList.add("show"); // Show the prompt
+ });
+}
+
+// Handle Install Button Click
+if ( installButton ) {
+ installButton.addEventListener("click", async () => {
+ if (deferredPrompt) {
+ deferredPrompt.prompt();
+ const { outcome } = await deferredPrompt.userChoice;
+
+ if (outcome === "dismissed") {
+ setInstallDismissed(); // Store that the user dismissed the prompt
+ }
+
+ deferredPrompt = null; // Reset prompt
+ installPrompt.classList.remove("show"); // Hide the prompt
+ }
+ });
+}
+
+// Handle Close Button Click
+if ( dismissButton ) {
+ dismissButton.addEventListener("click", () => {
+ setInstallDismissed(); // Store that the user dismissed the prompt
+ });
+}
+
+// Function to remember user choice for 7 days
+function setInstallDismissed() {
+ localStorage.setItem("pwaInstallDismissed", Date.now() + 7 * 24 * 60 * 60 * 1000);
+ installPrompt.classList.remove("show"); // Hide the prompt
+}
+
+// Check if the 7-day period has passed
+if (localStorage.getItem("pwaInstallDismissed")) {
+ const dismissUntil = parseInt(localStorage.getItem("pwaInstallDismissed"), 10);
+ if (Date.now() < dismissUntil) {
+ installPrompt.classList.remove("show"); // Ensure it's hidden
+ } else {
+ localStorage.removeItem("pwaInstallDismissed"); // Reset after 7 days
+ }
+}
+
/**
* Automatically selects/de-selects all check boxes associated with that field
**/
diff --git a/app/templates/default/default.inc.php b/app/templates/default/default.inc.php
index 95ff8c6..6747556 100644
--- a/app/templates/default/default.inc.php
+++ b/app/templates/default/default.inc.php
@@ -19,6 +19,15 @@ use TheTempusProject\Houdini\Classes\Components;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\TheTempusProject as App;
+use Endroid\QrCode\Builder\Builder;
+use Endroid\QrCode\Encoding\Encoding;
+use Endroid\QrCode\ErrorCorrectionLevel;
+use Endroid\QrCode\Label\LabelAlignment;
+use Endroid\QrCode\Label\Font\OpenSans;
+use Endroid\QrCode\RoundBlockSizeMode;
+use Endroid\QrCode\Writer\PngWriter;
+use TheTempusProject\Hermes\Functions\Route as Routes;
+use TheTempusProject\Canary\Bin\Canary as Debug;
class DefaultLoader extends Loader {
private static $loaded = false;
@@ -41,12 +50,61 @@ class DefaultLoader extends Loader {
}
$this->addJs( '' );
Components::setIfNull( 'LOGO', Config::getValue( 'main/logo' ) ?? TP_DEFAULT_LOGO );
+
+ if ( ! empty( Config::getValue( 'share/enabled' ) ) ) {
+ $currentUrl = Routes::getAddress() . Input::get( 'url' );
+ $folder = IMAGE_DIRECTORY . 'qr-codes' . DIRECTORY_SEPARATOR ;
+ $filename = md5( $currentUrl ) . '.png';
+
+ if ( ! file_exists( $folder ) ) {
+ Debug::Info( 'Creating Directory because it does not exist' );
+ mkdir( $folder, 0777, true );
+ }
+ if ( ! empty( Config::getValue( 'share/qr' ) ) ) {
+ if ( ! file_exists( $folder . $filename ) ) {
+ Debug::Info( 'Creating qr-image because it does not exist' );
+ $builder = new Builder(
+ writer: new PngWriter(),
+ writerOptions: [],
+ validateResult: false,
+ data: Routes::getAddress() . Input::get( 'url' ),
+ encoding: new Encoding('UTF-8'),
+ errorCorrectionLevel: ErrorCorrectionLevel::High,
+ size: 200,
+ margin: 10,
+ roundBlockSizeMode: RoundBlockSizeMode::Margin,
+ logoPath: APP_ROOT_DIRECTORY . DIRECTORY_SEPARATOR . Config::getValue( 'main/logo' ),
+ logoResizeToWidth: 30,
+ logoPunchoutBackground: true,
+ labelText: Config::getValue( 'main/name' ),
+ labelFont: new OpenSans(14),
+ labelAlignment: LabelAlignment::Center
+ );
+ $result = $builder->build();
+ $result->saveToFile( $folder . $filename );
+ }
+ Components::set( 'QR_CODE','' );
+ } else {
+ Components::setIfNull( 'QR_CODE', '' );
+ }
+ Components::setIfNull( 'SHARE_IMAGE', Views::simpleView( 'footer.share' ) );
+ } else {
+ Components::setIfNull( 'SHARE_IMAGE', '' );
+ }
+
+ if ( ! empty( Config::getValue( 'main/pwa' ) ) ) {
+ Components::setIfNull( 'PWA', Views::simpleView( 'pwa') );
+ } else {
+ Components::setIfNull( 'PWA', '' );
+ }
+
Components::setIfNull( 'COPY', Views::simpleView( 'footer.copy') );
Components::setIfNull( 'SOCIAL', Views::simpleView( 'footer.social') );
Components::prepend( 'FOOTER_LEFT', Views::simpleView( 'footer.left', Navigation::getMenuLinks( App::CONTACT_FOOTER_MENU_NAME ) ) );
Components::prepend( 'FOOTER_CENTER', Views::simpleView( 'footer.center', Navigation::getMenuLinks( App::INFO_FOOTER_MENU_NAME ) ) );
Components::prepend( 'FOOTER_RIGHT', Views::simpleView( 'footer.right') );
Components::setIfNull( 'FOOT', Views::simpleView( 'footer.container') );
+
/**
* Top-Nav
*/
diff --git a/app/templates/default/default.tpl b/app/templates/default/default.tpl
index 2cda303..0e9aa7a 100644
--- a/app/templates/default/default.tpl
+++ b/app/templates/default/default.tpl
@@ -91,6 +91,7 @@
{/ISSUES}
+ {PWA}
{CONTENT}
diff --git a/app/views/footer/right.html b/app/views/footer/right.html
index 351f1e5..b17317d 100644
--- a/app/views/footer/right.html
+++ b/app/views/footer/right.html
@@ -1,4 +1,5 @@