Browse Source

Added setting page

Toby Chui 9 giờ trước cách đây
mục cha
commit
b35c578716

+ 8 - 8
sd_card/www/admin/post.html

@@ -53,22 +53,22 @@
           <div class="item">
             <div class="header">Media</div>
             <div class="menu">
-              <a class="item" name="library" xtab="">Convert</a>
-              <a class="item" name="paste" xtab="">Paste</a>
+              <!-- <a class="item" name="library" xtab="posteng/convt.html">Convert</a> -->
+              <a class="item" name="paste" xtab="posteng/paste.html">Image Paste</a>
             </div>
           </div>
           <div class="item">
             <div class="header">Pages</div>
             <div class="menu">
-              <a class="item" name="allpages" xtab="">All Pages</a>
-              <a class="item" name="newpage" xtab="">Add New</a>
+              <a class="item" name="allpages" xtab="posteng/pages.html">All Pages</a>
+              <a class="item" name="newpage" xtab="posteng/newpg.html">Add New</a>
             </div>
           </div>
           <div class="item">
             <div class="header">Settings</div>
             <div class="menu">
-              <a class="item" name="settings" xtab="">General</a>
-              <a class="item" name="permlinks" xtab="">Permalinks</a>
+              <a class="item" name="settings" xtab="posteng/setting.html">General</a>
+              <!-- <a class="item" name="permlinks" xtab="">Permalinks</a> -->
             </div>
           </div>
       </div>
@@ -104,8 +104,8 @@
                 case "newpost":
                     $("#postengine_tab").load("posteng/new.html");
                     break;
-                case "library":
-                    $("#postengine_tab").load("posteng/library.html");
+                case "convert":
+                    $("#postengine_tab").load("posteng/convt.html");
                     break;
                 case "paste":
                     $("#postengine_tab").load("posteng/paste.html");

+ 9 - 4
sd_card/www/admin/posteng/edit.html

@@ -36,6 +36,11 @@
     }
 </style>
 <br>
+<script>
+    if ($(".postengine_edit_media_selector").length > 1) {
+        $(".postengine_edit_media_selector").first().remove();
+    }
+</script>
 <div class="ui container" style="margin-top: 20px;">
     <div class="ui header">
         Edit Post
@@ -59,7 +64,7 @@
 </div>
 
 <!-- Media Selector -->
-<div id="postengine_media_selector" class="ui modal">
+<div class="ui modal postengine_edit_media_selector">
     <i class="close icon"></i>
     <div class="content">
         <div class="ui fluid input">
@@ -244,7 +249,7 @@
         });
 
         $(".file-item").on('dblclick', function() {
-            $("#postengine_media_selector").modal("hide");
+            $(".postengine_edit_media_selector").modal("hide");
             const path = $(this).data('path');
             const type = $(this).data('type');
             addMediaFileToEditor(path, type);
@@ -313,7 +318,7 @@
             addMediaFileToEditor(path, type);
         });
 
-        $("#postengine_media_selector").modal("hide");
+        $(".postengine_edit_media_selector").modal("hide");
     });
 
     function isWebSafeFile(fileName) {
@@ -340,7 +345,7 @@
         // Reset history
         pathHistory = []; // Reset path history
         fetchDirectoryContents(currentDir);
-        $("#postengine_media_selector").modal("show");
+        $(".postengine_edit_media_selector").modal("show");
     }
 
     function addMediaFileToEditor(mediaLink, mediaType){

+ 11 - 4
sd_card/www/admin/posteng/new.html

@@ -36,6 +36,13 @@
     }
 </style>
 <br>
+<script>
+    $(document).ready(function() {
+        if ($('.postengine_media_selector').length > 1) {
+            $('.postengine_media_selector').first().remove();
+        }
+    });
+</script>
 <div class="ui container" style="margin-top: 20px;">
     <h2 class="ui header">New Post</h2>
     <!-- Load draft message -->
@@ -62,7 +69,7 @@
 </div>
 
 <!-- Media Selector -->
-<div id="postengine_media_selector" class="ui modal">
+<div class="ui modal postengine_media_selector">
     <i class="close icon"></i>
     <div class="content">
         <div class="ui fluid input">
@@ -216,7 +223,7 @@
         });
 
         $(".file-item").on('dblclick', function() {
-            $("#postengine_media_selector").modal("hide");
+            $(".postengine_media_selector").modal("hide");
             const path = $(this).data('path');
             const type = $(this).data('type');
             addMediaFileToEditor(path, type);
@@ -285,7 +292,7 @@
             addMediaFileToEditor(path, type);
         });
 
-        $("#postengine_media_selector").modal("hide");
+        $(".postengine_media_selector").modal("hide");
     });
 
     function isWebSafeFile(fileName) {
@@ -312,7 +319,7 @@
         // Reset history
         pathHistory = []; // Reset path history
         fetchDirectoryContents(currentDir);
-        $("#postengine_media_selector").modal("show");
+        $(".postengine_media_selector").modal("show");
     }
 
     function addMediaFileToEditor(mediaLink, mediaType){

+ 0 - 0
sd_card/www/admin/posteng/newpg.html


+ 0 - 0
sd_card/www/admin/posteng/pages.html


+ 137 - 0
sd_card/www/admin/posteng/paste.html

@@ -0,0 +1,137 @@
+<style>
+    #image-preview {
+        max-width: 100%;
+        max-height: 300px;
+        display: none;
+    }
+</style>
+
+<div class="ui container" style="margin-top: 20px;">
+    <div class="ui segment" id="paste-area" tabindex="0" style="min-height: 200px; text-align: center;">
+        <h3>Paste an image here (Ctrl + V)</h3>
+        <img id="image-preview" alt="Pasted Image" style="margin: 0 auto; display: block;">
+        <div class="ui divider"></div>
+        <p id="image_properties">No pasted image</p>
+        <button class="ui basic button" onclick="uploadImage()" style="margin-top: 20px;">
+            <i class="blue upload icon"></i> Upload
+        </button>
+    </div>
+</div>
+
+<script>
+    var pasteArea = document.getElementById('paste-area');
+    var imagePreview = document.getElementById('image-preview');
+
+    pasteArea.addEventListener('paste', (event) => {
+        const items = event.clipboardData.items;
+        for (let item of items) {
+            if (item.type.startsWith('image/')) {
+                const file = item.getAsFile();
+                const reader = new FileReader();
+                reader.onload = (e) => {
+                    imagePreview.src = e.target.result;
+                    imagePreview.style.display = 'block';
+                    updateImageProperties(); // Update image properties after loading
+                };
+                reader.readAsDataURL(file);
+                break;
+            }
+        }
+    });
+
+    function updateImageProperties() {
+        const imageProperties = document.getElementById('image_properties');
+        if (imagePreview.src) {
+            const img = new Image();
+            img.src = imagePreview.src;
+            img.onload = () => {
+                imageProperties.textContent = `Width: ${img.width}px, Height: ${img.height}px`;
+            };
+        } else {
+            imageProperties.textContent = 'No pasted image';
+        }
+    }
+
+    //Upload to /site/img/{filename}.jpg
+    function uploadImage() {
+        const formData = new FormData();
+        const file = imagePreview.src; // Use the source of the image element
+
+        if (file) {
+            let filename = Date.now() + '.jpg'; // Generate a unique filename based on timestamp
+            compressImageToJpeg(filename).then((compressedFile) => {
+                formData.append("file1", compressedFile);
+
+                var ajax = new XMLHttpRequest();
+                ajax.addEventListener("load", function(event) {
+                    let responseText = event.target.responseText;
+                    if (responseText.includes("ok")){
+                        msgbox("Image uploaded successfully!", 3000);
+                        $("#image_properties").text("Image uploaded to /site/img/" + filename);
+                    }
+                }, false);
+
+                ajax.addEventListener("error", function(event) {
+                    alert("Failed to upload image: " + event.target.responseText);
+                }, false);
+
+                ajax.open("POST", "/upload?dir=/site/img");
+                ajax.send(formData);
+            }).catch(error => {
+                console.error('Error compressing image:', error);
+                alert('Failed to compress image.');
+            });
+        } else {
+            alert('No image to upload!');
+        }
+    }
+
+    function compressImageToJpeg(filename) {
+        return new Promise((resolve, reject) => {
+            const canvas = document.createElement('canvas');
+            const ctx = canvas.getContext('2d');
+            const img = new Image();
+
+            img.onload = () => {
+                const maxWidth = 1024; // Set maximum width for compression
+                const maxHeight = 1024; // Set maximum height for compression
+                let width = img.width;
+                let height = img.height;
+
+                // Maintain aspect ratio
+                if (width > maxWidth || height > maxHeight) {
+                    if (width / height > maxWidth / maxHeight) {
+                        height = Math.round((height * maxWidth) / width);
+                        width = maxWidth;
+                    } else {
+                        width = Math.round((width * maxHeight) / height);
+                        height = maxHeight;
+                    }
+                }
+
+                canvas.width = width;
+                canvas.height = height;
+                ctx.drawImage(img, 0, 0, width, height);
+
+                canvas.toBlob(
+                    (blob) => {
+                        if (blob) {
+                            const compressedFile = new File([blob], filename, {
+                                type: 'image/jpeg',
+                            });
+                            resolve(compressedFile);
+                        } else {
+                            reject(new Error('Compression failed.'));
+                        }
+                    },
+                    'image/jpeg',
+                    0.8 // Compression quality (0.0 to 1.0)
+                );
+            };
+
+            img.onerror = () => reject(new Error('Failed to load image.'));
+            img.src = imagePreview.src; // Use the source of the image element
+        });
+    }
+    
+</script>

+ 115 - 0
sd_card/www/admin/posteng/setting.html

@@ -0,0 +1,115 @@
+
+<div class="ui text container" style="margin-top: 3em;">
+    <h2 class="ui header">Site Settings</h2>
+    <form class="ui form">
+        <div class="field">
+            <label for="site-title">Site Title</label>
+            <input type="text" id="site-title" name="site-title" placeholder="Enter site title">
+        </div>
+        <div class="field">
+            <label for="site-description">Site Description</label>
+            <input type="text" id="site-description" name="site-description" placeholder="Enter site description">
+        </div>
+        <div class="field">
+            <label for="youtube-link">YouTube Link</label>
+            <input type="url" id="youtube-link" name="youtube-link" placeholder="Enter YouTube link">
+        </div>
+        <div class="field">
+            <label for="facebook-link">Facebook Link</label>
+            <input type="url" id="facebook-link" name="facebook-link" placeholder="Enter Facebook link">
+        </div>
+        <div class="field">
+            <label for="x-link">X (Twitter) Link</label>
+            <input type="url" id="x-link" name="x-link" placeholder="Enter X (Twitter) link">
+        </div>
+        <div class="field">
+            <label for="github-link">GitHub Link</label>
+            <input type="url" id="github-link" name="github-link" placeholder="Enter GitHub link">
+        </div>
+        <div class="field">
+            <label for="blog-link">Blog Link</label>
+            <input type="url" id="blog-link" name="blog-link" placeholder="Enter Blog link">
+        </div>
+        <div class="field">
+            <label for="website-link">Website Link</label>
+            <input type="url" id="website-link" name="website-link" placeholder="Enter Website link">
+        </div>
+        <div class="field">
+            <label for="email-link">Email Address</label>
+            <input type="email" id="email-link" name="email-link" placeholder="Enter Email address">
+        </div>
+        <button class="ui basic button" type="submit"><i class="blue save icon"></i> Save</button>
+    </form>
+</div>
+<script>
+    // Function to handle form submission
+    document.querySelector('form').addEventListener('submit', function(event) {
+        event.preventDefault(); // Prevent the default form submission
+        
+        // Get the values from the input fields
+        const siteTitle = document.getElementById('site-title').value;
+        const siteDescription = document.getElementById('site-description').value;
+        const youtubeLink = document.getElementById('youtube-link').value;
+        const facebookLink = document.getElementById('facebook-link').value;
+        const xLink = document.getElementById('x-link').value;
+        const githubLink = document.getElementById('github-link').value;
+        const blogLink = document.getElementById('blog-link').value;
+        const websiteLink = document.getElementById('website-link').value;
+        const emailLink = document.getElementById('email-link').value;
+
+        // Create a JSON object and encode it
+        const settingsJson = encodeURIComponent(JSON.stringify({
+            siteTitle: siteTitle,
+            siteDescription: siteDescription,
+            youtubeLink: youtubeLink,
+            facebookLink: facebookLink,
+            xLink: xLink,
+            githubLink: githubLink,
+            blogLink: blogLink,
+            websiteLink: websiteLink,
+            emailLink: emailLink
+        }));
+
+        setValue("site-info", encodeURIComponent(settingsJson), function(){
+                msgbox("Site info updated", 2000);
+                initSiteInfo();
+        });
+    });
+    
+
+    function initSiteInfo(){
+        var defaultSettings = {
+            siteTitle: "WebStick",
+            siteDescription: "A personal web server hosted on an ESP8266 using a micro SD card",
+            youtubeLink: "https://www.youtube.com/channel/UCzbcGOZHO2BH-ANX7W0MGIg",
+            facebookLink: "",
+            xLink: "",
+            githubLink: "https://github.com/tobychui/webstick",
+            blogLink: "https://blog.imuslab.com",
+            websiteLink: "https://imuslab.com",
+            emailLink: "mailto:[email protected]"
+        };
+
+        //Initiate the settings form with current values
+        loadValue("site-info", function(data){
+            if (data.error != undefined || data == ""){
+                data = defaultSettings;
+            }else{
+                data = JSON.parse(decodeURIComponent(data));
+            }
+            console.log(data);
+            document.getElementById('site-title').value = data.siteTitle;
+            document.getElementById('site-description').value = data.siteDescription;
+            document.getElementById('youtube-link').value = data.youtubeLink || '';
+            document.getElementById('facebook-link').value = data.facebookLink || '';
+            document.getElementById('x-link').value = data.xLink || '';
+            document.getElementById('github-link').value = data.githubLink || '';
+            document.getElementById('blog-link').value = data.blogLink || '';
+            document.getElementById('website-link').value = data.websiteLink || '';
+            document.getElementById('email-link').value = data.emailLink || '';
+        });
+    }
+
+    initSiteInfo();
+   
+</script>

+ 31 - 3
sd_card/www/index.html

@@ -49,14 +49,14 @@
 		<div class="ts-content " id="home">
 			<div id="banner" class="ts-content is-rounded is-padded has-top-spaced-large" style=" color: var(--ts-gray-50)">
 				<div style="max-width: 300px">
-					<div id="pageTitle" class="ts-header is-huge is-heavy">WebStick</div>
-					<p id="pageDesc">A personal web server hosted on an ESP8266 using a micro SD card</p>
+					<div id="site-title" class="ts-header is-huge is-heavy">WebStick</div>
+					<p id="site-description">A personal web server hosted on an ESP8266 using a micro SD card</p>
 					<a href="/admin" class="ts-button is-outlined" style="color: var(--ts-gray-50)">Login</a>
 				</div>
 			</div>
 
 			<!-- Contact Information, change these to yours -->
-			<div class="ts-content is-center-aligned has-top-spaced-large">
+			<div id="contacts_icon" class="ts-content is-center-aligned has-top-spaced-large">
 				<a href="https://www.youtube.com/channel/UCzbcGOZHO2BH-ANX7W0MGIg"><span class="ts-icon is-huge is-youtube-icon"></span></a>
 				<a class="has-start-spaced-large" href="https://blog.imuslab.com"><span class="ts-icon is-huge is-newspaper-icon"></span></a>
 				<a class="has-start-spaced-large" href="mailto:[email protected]"><span class="ts-icon is-huge is-envelope-icon"></span></a>
@@ -84,6 +84,34 @@
 		$("#about").load("about.html");
 		$("#posts").load("posts.html");
 		$("#qr").html('<iframe src="tool/qr.html" style="border: none; width: 100%; height: calc(100vh - 200px);"></iframe>');
+
+		/* Load the site info from pref */
+		function loadValue(key, callback){
+            $.get("/api/pref/get?key=" + key, function(data){
+                callback(data);
+            });
+        }
+
+		function initSiteInfo(){
+			var defaultSettings = {
+				siteTitle: "WebStick",
+				siteDescription: "A personal web server hosted on an ESP8266 using a micro SD card"
+			};
+
+			//Initiate the settings form with current values
+			loadValue("site-info", function(data){
+				if (data.error != undefined || data == ""){
+					data = defaultSettings;
+				}else{
+					data = JSON.parse(decodeURIComponent(data));
+				}
+				console.log(data);
+				$("#site-title").text(data.siteTitle);
+				$("#site-description").text(data.siteDescription);
+			});
+    	}
+
+    	initSiteInfo();
 	</script>
 </body>
 </html>

+ 9 - 0
sd_card/www/site/img/index.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="refresh" content="0; url='../index.html'" />
+  </head>
+  <body>
+    <p>Redirecitng to homepage</p>
+  </body>
+</html>

+ 9 - 0
sd_card/www/site/pages/index.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="refresh" content="0; url='../index.html'" />
+  </head>
+  <body>
+    <p>Redirecitng to homepage</p>
+  </body>
+</html>

+ 1 - 1
sd_card/www/site/posts/index.html

@@ -4,6 +4,6 @@
     <meta http-equiv="refresh" content="0; url='../index.html'" />
   </head>
   <body>
-    <p>Redirecitng to blog UI</p>
+    <p>Redirecitng to homepage</p>
   </body>
 </html>