From 25f11a77cbee3e4a87b7c96d5bb5bf97a9b40aad Mon Sep 17 00:00:00 2001 From: tobiichi3227 Date: Sun, 7 Apr 2024 13:30:27 +0800 Subject: [PATCH 01/98] feat: copy result image for sharing Close #15 --- fortune_generator/index.html | 2 ++ fortune_generator/js/fortune.js | 20 +++++++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fortune_generator/index.html b/fortune_generator/index.html index 45cc805..f7c4100 100644 --- a/fortune_generator/index.html +++ b/fortune_generator/index.html @@ -12,6 +12,7 @@ + + + + + + + + Daily Fortune Generator + + + + + + + + - - - - - - -
-
-

-
- -
+ + + + + + +
-
-

+

+
+ +
+
+
+

+
+
+

+
+
+

+
-
-

+
+
+

+
-
-

+
+

+
+
+

-
-
-

+ + +
+
+

+
+
+
+
+

+
+
+

+
+
+
+
+

+
+
+

+
+
+
+
+
+
+

+
+
+

+
+
+
+
+

+
+
+

+
+
+ +
-

-
-
-

+ + +
- - -
-
-

-
-
-
-
-

-
-
-

-
-
-
-
-

-
-
-

-
-
-
-
-
-
-

-
-
-

-
-
-
-
-

-
-
-

-
-
-
-
- -
- - - -
- -
- - - - - - + + + + + diff --git a/fortune_generator/js/fortune.js b/fortune_generator/js/fortune.js index 1bcc1db..8a79751 100644 --- a/fortune_generator/js/fortune.js +++ b/fortune_generator/js/fortune.js @@ -1,20 +1,19 @@ let ip = null; -fetch("https://api.ipify.org?format=json").then(response => { +fetch("https://api.ipify.org?format=json").then((response) => { if (response.ok) { return response.json(); } throw new Error("Network response was not ok."); -}).then(res => { +}).then((res) => { ip = res.ip; - -}).catch(_error => { - if ('caches' in window) { - caches.match('https://api.ipify.org?format=json').then(response => { +}).catch((_error) => { + if ("caches" in window) { + caches.match("https://api.ipify.org?format=json").then((response) => { if (response) { return response.json(); } - }).then(data => { + }).then((data) => { if (ip === null && data !== undefined) { ip = JSON.parse(data).ip; } @@ -22,7 +21,6 @@ fetch("https://api.ipify.org?format=json").then(response => { } }); - let goodFortunes = []; let badFortunes = []; let special_events = []; @@ -31,27 +29,61 @@ let fortune_generated = false; // using async and await to prevent fetching the data too late... async function fetch_data() { await fetch("./json/fortune.json") - .then(response => response.json()) - .then(data => { - goodFortunes = data.goodFortunes; - badFortunes = data.badFortunes; - }) + .then((response) => response.json()) + .then((data) => { + goodFortunes = data.goodFortunes; + badFortunes = data.badFortunes; + }); await fetch("./json/special.json") - .then(response => response.json()) - .then(data => { - special_events = data.special_events; - }) + .then((response) => response.json()) + .then((data) => { + special_events = data.special_events; + }); } -const textColorClass = ["good-fortune", "good-fortune", "good-fortune", "good-fortune", "good-fortune", "middle-fortune", "bad-fortune", "bad-fortune"]; -const fortuneStatus = ["大吉", "中吉", "小吉", "吉", "末吉", "中平", "凶", "大凶"]; -const chineseMonth = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"]; -const week = ['日', '一', '二', '三', '四', '五', '六']; +const textColorClass = [ + "good-fortune", + "good-fortune", + "good-fortune", + "good-fortune", + "good-fortune", + "middle-fortune", + "bad-fortune", + "bad-fortune", +]; +const fortuneStatus = [ + "大吉", + "中吉", + "小吉", + "吉", + "末吉", + "中平", + "凶", + "大凶", +]; +const chineseMonth = [ + "一", + "二", + "三", + "四", + "五", + "六", + "七", + "八", + "九", + "十", + "十一", + "十二", +]; +const week = ["日", "一", "二", "三", "四", "五", "六"]; -const title = `今日運勢`; -const allGood = `萬事皆宜`; -const allBad = `諸事不宜`; +const title = + `今日運勢`; +const allGood = + `萬事皆宜`; +const allBad = + `諸事不宜`; // date const d = new Date(); @@ -63,7 +95,11 @@ const year = d.getFullYear(); function daysDiff(eventIndex) { // define the date right now and the special event date const startDate = new Date(year, month - 1, date); - const endDate = new Date(special_events[eventIndex].year, special_events[eventIndex].month - 1, special_events[eventIndex].date); + const endDate = new Date( + special_events[eventIndex].year, + special_events[eventIndex].month - 1, + special_events[eventIndex].date, + ); // calculate the difference in milliseconds and convert it to days const timeDiff = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24)); @@ -71,15 +107,15 @@ function daysDiff(eventIndex) { } // pre-search jquery - save to a variable to improve performance -const J_l_1_event = $('#l-1-event'); -const J_l_1_desc = $('#l-1-desc'); -const J_l_2_event= $('#l-2-event'); -const J_l_2_desc = $('#l-2-desc'); -const J_r_1_event = $('#r-1-event'); -const J_r_1_desc = $('#r-1-desc'); -const J_r_2_event= $('#r-2-event'); -const J_r_2_desc = $('#r-2-desc'); -const J_ip_to_fortune = $('#ip-to-fortune'); +const J_l_1_event = $("#l-1-event"); +const J_l_1_desc = $("#l-1-desc"); +const J_l_2_event = $("#l-2-event"); +const J_l_2_desc = $("#l-2-desc"); +const J_r_1_event = $("#r-1-event"); +const J_r_1_desc = $("#r-1-desc"); +const J_r_2_event = $("#r-2-event"); +const J_r_2_desc = $("#r-2-desc"); +const J_ip_to_fortune = $("#ip-to-fortune"); let special = false; let special_events_index = 0; @@ -90,23 +126,34 @@ async function init_page() { await fetch_data(); // hide the elements of show fortune page - $('#result-page').hide(); + $("#result-page").hide(); // show date before button pressed - const showMonth = `${chineseMonth[month - 1] + "月"}`; - const showDate = `${("0" + date).slice(-2)}`; - const showDay = `${"星期" + week[day]}`; + const showMonth = + `${ + chineseMonth[month - 1] + "月" + }`; + const showDate = `${ + ("0" + date).slice(-2) + }`; + const showDay = + `${ + "星期" + week[day] + }`; + + $("#month").html(showMonth); + $("#date").html(showDate); + $("#weekday").html(showDay); - $('#month').html(showMonth); - $('#date').html(showDate); - $('#weekday').html(showDay); - const showSpecialEventCount = 2; let eventIndexPtr = 0, eventIndexList = Array(showSpecialEventCount).fill(-1); // check if there is special event today for (let i = 0; i < special_events.length; i++) { if (daysDiff(i) > 0) { - if (eventIndexPtr < showSpecialEventCount && eventIndexList[eventIndexPtr] == -1) { + if ( + eventIndexPtr < showSpecialEventCount && + eventIndexList[eventIndexPtr] == -1 + ) { eventIndexList[eventIndexPtr] = i; eventIndexPtr++; } @@ -119,23 +166,33 @@ async function init_page() { for (let eventIndex = 0; eventIndex < showSpecialEventCount; eventIndex++) { if (eventIndexList[eventIndex] != -1) { const days = daysDiff(eventIndexList[eventIndex]); - const upcoming_event = `距離${special_events[eventIndexList[eventIndex]].event}還剩${days}`; - $(`#upcoming-event-${eventIndex + 1}`).html(upcoming_event) + const upcoming_event = + `距離${ + special_events[eventIndexList[eventIndex]].event + }還剩${days}`; + $(`#upcoming-event-${eventIndex + 1}`).html(upcoming_event); } } // show special event if today is a special day if (special) { - const special_event_today = `今日是${special_events[special_events_index].event}`; - $('#special-day').html(special_event_today); + const special_event_today = + `今日是${ + special_events[special_events_index].event + }`; + $("#special-day").html(special_event_today); } - const last_date_str = localStorage.getItem('last_date'); + const last_date_str = localStorage.getItem("last_date"); if (last_date_str !== null && last_date_str !== undefined) { const now_date = new Date(); const last_date = new Date(last_date_str); - - if (now_date.getFullYear() === last_date.getFullYear() && now_date.getMonth() === last_date.getMonth() && now_date.getDate() === last_date.getDate()) { + + if ( + now_date.getFullYear() === last_date.getFullYear() && + now_date.getMonth() === last_date.getMonth() && + now_date.getDate() === last_date.getDate() + ) { fortune_generated = true; Appear(); } @@ -143,59 +200,78 @@ async function init_page() { } // event bar -const good_span = event => `宜: ${event}`; -const bad_span = event => `忌: ${event}`; -const desc_span = desc => `${desc}`; +const good_span = (event) => + `宜: ${event}`; +const bad_span = (event) => + `忌: ${event}`; +const desc_span = (desc) => + `${desc}`; function Appear() { - $('#title').html(title); - $('#btn').html('打卡成功'); + $("#title").html(title); + $("#btn").html("打卡成功"); // disable the btn - $('#btn').attr("disabled", "disabled"); + $("#btn").attr("disabled", "disabled"); //change page - $('#init-page').hide(); - $('#result-page').show(); - + $("#init-page").hide(); + $("#result-page").show(); + // some lengths const goodLen = goodFortunes.length; const badLen = badFortunes.length; const statusLen = fortuneStatus.length; - + let status_index = -1; let seed1 = -1; let seed2 = -1; if (!fortune_generated) { // transform ip to four numbers - const num = ip.split(".").map(num => parseInt(num)); + const num = ip.split(".").map((num) => parseInt(num)); // TODO: improve the hash process - const hashDate = Math.round(Math.log10(year * ((month << (Math.log10(num[3]) + day - 1)) * (date << Math.log10(num[2] << day))))); - seed1 = (num[0] >> hashDate) * (num[1] >> Math.min(hashDate, 2)) + (num[2] << 1) * (num[3] >> 3) + (date << 3) * (month << hashDate) + (year * day) >> 2; - seed2 = (num[0] << (hashDate + 2)) * (num[1] << hashDate) + (num[2] << 1) * (num[3] << 2) + (date << (hashDate - 1)) * (month << 4) + year >> hashDate + (date * day) >> 1; + const hashDate = Math.round( + Math.log10( + year * + ((month << (Math.log10(num[3]) + day - 1)) * + (date << Math.log10(num[2] << day))), + ), + ); + seed1 = (num[0] >> hashDate) * (num[1] >> Math.min(hashDate, 2)) + + (num[2] << 1) * (num[3] >> 3) + (date << 3) * (month << hashDate) + + (year * day) >> 2; + seed2 = (num[0] << (hashDate + 2)) * (num[1] << hashDate) + + (num[2] << 1) * (num[3] << 2) + + (date << (hashDate - 1)) * (month << 4) + year >> + hashDate + (date * day) >> 1; // decide the status status_index = ((seed1 + seed2) % statusLen + statusLen) % statusLen; // update last record - localStorage.setItem('last_date', d.toISOString()); - localStorage.setItem('last_status_index', status_index.toString()); - localStorage.setItem('last_seed1', seed1.toString()); - localStorage.setItem('last_seed2', seed2.toString()); + localStorage.setItem("last_date", d.toISOString()); + localStorage.setItem("last_status_index", status_index.toString()); + localStorage.setItem("last_seed1", seed1.toString()); + localStorage.setItem("last_seed2", seed2.toString()); } else { - status_index = parseInt(localStorage.getItem('last_status_index')); - seed1 = parseInt(localStorage.getItem('last_seed1')); - seed2 = parseInt(localStorage.getItem('last_seed2')); + status_index = parseInt(localStorage.getItem("last_status_index")); + seed1 = parseInt(localStorage.getItem("last_seed1")); + seed2 = parseInt(localStorage.getItem("last_seed2")); } - - const status = `§ ${fortuneStatus[status_index]} §`; - + + const status = `§ ${fortuneStatus[status_index]} §`; + if (special) { status_index = special_events[special_events_index].status_index; - const special_status = `§ ${fortuneStatus[status_index]} §`; + const special_status = `§ ${ + fortuneStatus[status_index] + } §`; J_ip_to_fortune.html(special_status); - } - else { + } else { J_ip_to_fortune.html(status); } @@ -206,31 +282,40 @@ function Appear() { let l2 = (((seed1 << 1) + date) % goodLen + goodLen) % goodLen; while (set.has(goodFortunes[l2].event)) { l2 = (l2 + 1) % goodLen; - } + } set.add(goodFortunes[l2].event); let r1 = (((seed1 >> 1) + (d.getMonth() << 3)) % badLen + badLen) % badLen; while (set.has(badFortunes[r1].event)) { r1 = (r1 + 2) % badLen; - } + } set.add(badFortunes[r1].event); - let r2 = ((((((seed1 << 3) + (d.getFullYear() >> 5) * (date << 2)) % badLen) * seed2) >> 6) % badLen + badLen) % badLen; + let r2 = ((((((seed1 << 3) + (d.getFullYear() >> 5) * (date << 2)) % badLen) * + seed2) >> 6) % badLen + badLen) % badLen; while (set.has(badFortunes[r2].event)) { r2 = (r2 + 1) % badLen; - } + } - // organize the stuffs below this line... + // organize the stuffs below this line... const l1_desc_list = goodFortunes[l1].description; const l2_desc_list = goodFortunes[l2].description; const r1_desc_list = badFortunes[r1].description; const r2_desc_list = badFortunes[r2].description; const l_1_event = good_span(goodFortunes[l1].event); - const l_1_desc = desc_span(l1_desc_list[Math.abs(seed1) % l1_desc_list.length]); + const l_1_desc = desc_span( + l1_desc_list[Math.abs(seed1) % l1_desc_list.length], + ); const l_2_event = good_span(goodFortunes[l2].event); - const l_2_desc = desc_span(l2_desc_list[Math.abs(seed2) % l2_desc_list.length]); + const l_2_desc = desc_span( + l2_desc_list[Math.abs(seed2) % l2_desc_list.length], + ); const r_1_event = bad_span(badFortunes[r1].event); - const r_1_desc = desc_span(r1_desc_list[Math.abs(seed1) % r1_desc_list.length]); + const r_1_desc = desc_span( + r1_desc_list[Math.abs(seed1) % r1_desc_list.length], + ); const r_2_event = bad_span(badFortunes[r2].event); - const r_2_desc = desc_span(r2_desc_list[Math.abs(seed2) % r2_desc_list.length]); + const r_2_desc = desc_span( + r2_desc_list[Math.abs(seed2) % r2_desc_list.length], + ); if (special) { // instead clear variable name, use short variable name for here... cuz it's too repetitive @@ -242,7 +327,7 @@ function Appear() { J_r_1_desc.html(desc_span(Data.badFortunes.r_1_desc)); J_r_2_event.html(bad_span(Data.badFortunes.r_2_event)); J_r_2_desc.html(desc_span(Data.badFortunes.r_2_desc)); - + if (Data.badFortunes.r_1_event.length == 0) { J_r_1_event.html(r_1_event); J_r_1_desc.html(r_1_desc); @@ -259,7 +344,7 @@ function Appear() { J_l_1_desc.html(desc_span(Data.goodFortunes.l_1_desc)); J_l_2_event.html(good_span(Data.goodFortunes.l_2_event)); J_l_2_desc.html(desc_span(Data.goodFortunes.l_2_desc)); - + if (Data.goodFortunes.l_1_event.length == 0) { J_l_1_event.html(l_1_event); J_l_1_desc.html(l_1_desc); @@ -269,8 +354,7 @@ function Appear() { J_l_2_desc.html(l_2_desc); } } - } - else{ + } else { if (status_index == 0) { J_r_1_event.html(allGood); } else { diff --git a/fortune_generator/js/matrix.js b/fortune_generator/js/matrix.js index d0acfd0..0ee77a9 100644 --- a/fortune_generator/js/matrix.js +++ b/fortune_generator/js/matrix.js @@ -1,13 +1,14 @@ -const canvas = document.getElementById("Matrix") -const context = canvas.getContext("2d") +const canvas = document.getElementById("Matrix"); +const context = canvas.getContext("2d"); -canvas.height = window.innerHeight + 100; -canvas.width = window.innerWidth + 5; +canvas.height = globalThis.innerHeight + 100; +canvas.width = globalThis.innerWidth + 5; -const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./*-+#$%^@!~?><:;[]{}=_αβΓγΔδεζηΘθικΛλμΞξΠπρΣσςτυΦφχΨψΩω×≦≧≠∞≒≡~∩∠∪∟⊿∫∮∵∴$¥〒¢£℃€℉╩◢ⅩⅨⅧⅦⅥⅤⅣⅢⅡⅠあいうえおがぎぐげござじずぜぞだぢつでづどにぬのばひぴぶへぺぼみゃょァゐゎè"; +const chars = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./*-+#$%^@!~?><:;[]{}=_αβΓγΔδεζηΘθικΛλμΞξΠπρΣσςτυΦφχΨψΩω×≦≧≠∞≒≡~∩∠∪∟⊿∫∮∵∴$¥〒¢£℃€℉╩◢ⅩⅨⅧⅦⅥⅤⅣⅢⅡⅠあいうえおがぎぐげござじずぜぞだぢつでづどにぬのばひぴぶへぺぼみゃょァゐゎè"; const fontSize = 16; -const columns = canvas.width / fontSize; +const columns = canvas.width / fontSize; const charArr = []; for (let i = 0; i < columns; i++) { @@ -23,14 +24,14 @@ context.fillRect(0, 0, canvas.width, canvas.height); function Update() { context.fillStyle = "rgba(0, 0, 0, 0.05)"; context.fillRect(0, 0, canvas.width, canvas.height); - + if (frame == 0) { const a = parseInt(Math.random() * 255); str = `rgba(${a}, ${Math.abs(a - 127)}, ${Math.abs(a - 255)}, 0.9)`; } context.fillStyle = str; context.font = fontSize + "px monospace"; - + for (let i = 0; i < columns; i++) { const text = chars[Math.floor(Math.random() * chars.length)]; context.fillText(text, i * fontSize, charArr[i] * fontSize); @@ -39,7 +40,7 @@ function Update() { } charArr[i]++; } - + frame++; if (frame <= 40 * (Math.floor(Math.random() * 10) + 3)) { requestAnimationFrame(Update); // 40 frames a cycle diff --git a/fortune_generator/js/scripts.js b/fortune_generator/js/scripts.js index e4d7288..c3ce266 100644 --- a/fortune_generator/js/scripts.js +++ b/fortune_generator/js/scripts.js @@ -1,49 +1,50 @@ -let darkModeIcon = document.querySelector('#dark-mode-icon'); +let darkModeIcon = document.querySelector("#dark-mode-icon"); darkModeIcon.onclick = () => { - darkModeIcon.classList.toggle('bx-sun'); - document.body.classList.toggle('dark-mode'); + darkModeIcon.classList.toggle("bx-sun"); + document.body.classList.toggle("dark-mode"); }; function copyResultImageToClipboard() { try { - const $title = $('#title').clone().wrap('
'); - $('#result-page').prepend($title.parent()); + const $title = $("#title").clone().wrap('
'); + $("#result-page").prepend($title.parent()); - const backgroundColor = getComputedStyle($('.container')[0]).backgroundColor; - htmlToImage.toBlob($('#result-page')[0], { + const backgroundColor = + getComputedStyle($(".container")[0]).backgroundColor; + htmlToImage.toBlob($("#result-page")[0], { skipFonts: true, - preferredFontFormat: 'woff2', + preferredFontFormat: "woff2", backgroundColor: backgroundColor, // Set background color dynamically - }).then(blob => { + }).then((blob) => { navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]); showCopiedNotice(); $title.parent().remove(); - }).catch(error => { - console.error('Error converting result page to image:', error); + }).catch((error) => { + console.error("Error converting result page to image:", error); $title.parent().remove(); }); - } catch(error) { - console.error('Error copying result image to clipboard:', error); + } catch (error) { + console.error("Error copying result image to clipboard:", error); } } function showCopiedNotice() { - const notice = $('
', { - text: 'Copied to clipboard!', + const notice = $("
", { + text: "Copied to clipboard!", css: { - position: 'fixed', - bottom: '20px', - right: '20px', - padding: '10px 20px', - backgroundColor: 'rgba(0, 0, 0, 0.7)', - color: '#fff', - borderRadius: '5px', + position: "fixed", + bottom: "20px", + right: "20px", + padding: "10px 20px", + backgroundColor: "rgba(0, 0, 0, 0.7)", + color: "#fff", + borderRadius: "5px", zIndex: 1000, - } + }, }); - $('body').append(notice); + $("body").append(notice); setTimeout(() => { notice.fadeOut(300, () => { diff --git a/fortune_generator/js/service-worker.js b/fortune_generator/js/service-worker.js index 9812f60..24bf3f9 100644 --- a/fortune_generator/js/service-worker.js +++ b/fortune_generator/js/service-worker.js @@ -1,35 +1,35 @@ -const pre_cache_file_version = 'pre-v1.1.0'; -const auto_cache_file_version = 'auto-v1.1.0' +const pre_cache_file_version = "pre-v1.1.0"; +const auto_cache_file_version = "auto-v1.1.0"; const ASSETS = [ - '/images/lifeadventurer-192x192.png', - '/images/lifeadventurer-512x512.png', - '/images/lifeadventurer-180x180.png', - '/images/lifeadventurer-270x270.png', - '/images/lifeadventurer.jpg', + "/images/lifeadventurer-192x192.png", + "/images/lifeadventurer-512x512.png", + "/images/lifeadventurer-180x180.png", + "/images/lifeadventurer-270x270.png", + "/images/lifeadventurer.jpg", - 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css', - 'https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js' + "https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css", + "https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js", ]; const NEED_UPDATE = [ - '/fortune_generator/', - '/fortune_generator/index.html', - '/fortune_generator/css/styles.css', - '/fortune_generator/js/fortune.js', - '/fortune_generator/js/matrix.js', - '/fortune_generator/json/special.json', - '/fortune_generator/json/fortune.json', - '/fortune_generator/json/manifest.json', - 'https://api.ipify.org/?format=json', -] + "/fortune_generator/", + "/fortune_generator/index.html", + "/fortune_generator/css/styles.css", + "/fortune_generator/js/fortune.js", + "/fortune_generator/js/matrix.js", + "/fortune_generator/json/special.json", + "/fortune_generator/json/fortune.json", + "/fortune_generator/json/manifest.json", + "https://api.ipify.org/?format=json", +]; const limit_cache_size = (name, size) => { - caches.open(name).then(cache => { - cache.keys().then(keys => { + caches.open(name).then((cache) => { + cache.keys().then((keys) => { if (keys.length > size) { cache.delete(keys[0]).then(() => { - limit_cache_size(name, size) + limit_cache_size(name, size); }); } }); @@ -37,8 +37,8 @@ const limit_cache_size = (name, size) => { }; const is_in_array = (str, array) => { - let path = ''; - + let path = ""; + // Check the request's domain is the same as the current domain. if (str.indexOf(self.origin) === 0) { path = str.substring(self.origin.length); // Remove https://lifeadventurer.github.io @@ -47,56 +47,58 @@ const is_in_array = (str, array) => { } return array.indexOf(path) > -1; -} +}; -// install -self.addEventListener('install', event => { +// install +self.addEventListener("install", (event) => { self.skipWaiting(); //pre-cache files event.waitUntil( - caches.open(pre_cache_file_version).then(cache => { + caches.open(pre_cache_file_version).then((cache) => { cache.addAll(ASSETS); - }) + }), ); }); // activate -self.addEventListener('activate', event => { +self.addEventListener("activate", (event) => { event.waitUntil( - caches.keys().then(keys => { - return Promise.all(keys.map(key => { - if (pre_cache_file_version.indexOf(key) === -1 && auto_cache_file_version.indexOf(key) === -1) { + caches.keys().then((keys) => { + return Promise.all(keys.map((key) => { + if ( + pre_cache_file_version.indexOf(key) === -1 && + auto_cache_file_version.indexOf(key) === -1 + ) { return caches.delete(key); } })); - }) - ) + }), + ); }); // fetch event -self.addEventListener('fetch', event => { +self.addEventListener("fetch", (event) => { if (is_in_array(event.request.url, ASSETS)) { - // cache only strategy + // cache only strategy event.respondWith( - caches.match(event.request.url) + caches.match(event.request.url), ); } else if (is_in_array(event.request.url, NEED_UPDATE)) { event.respondWith( - fetch(event.request.url).then(async response => { + fetch(event.request.url).then(async (response) => { if (response.ok) { const cache = await caches.open(auto_cache_file_version); cache.put(event.request.url, response.clone()); - return response; + return response; } throw new Error("Network response was not ok."); - - }).catch(async _error => { + }).catch(async (_error) => { const cache = await caches.open(auto_cache_file_version); return cache.match(event.request.url); - }) - ) + }), + ); } }); diff --git a/index.html b/index.html index ac3504e..e4e3d1b 100644 --- a/index.html +++ b/index.html @@ -1,66 +1,99 @@ - - - - Generators - - - - - - - - - - -
-
-

Generators Gallery

-
-
-
-
-
+ + + + Generators + + + + + + + + + + +
-
-
- fortune generator example -
-

Fortune Generator

-

Get your daily fortune with just a click.

- Check this out -
- +
+
+
+
+
+
+ fortune generator example +
+

Fortune Generator

+

+ Get your daily fortune with just a click. +

+ Check this out +
+
-
-
-
- quote generator example -
-

Quote Generator

-

Generate inspiring and thought-provoking quotes effortlessly.

- Check this out -
-
-
-
-
- -
- - - \ No newline at end of file +
+
+ +
+ + + diff --git a/quote_generator/css/styles.css b/quote_generator/css/styles.css index 39c1b62..cc4a71b 100644 --- a/quote_generator/css/styles.css +++ b/quote_generator/css/styles.css @@ -1,5 +1,5 @@ :root { - --button-color: #9DC4FF; + --button-color: #9dc4ff; --button-hover-color: #5ca8f3; --bg-color: #ffffffd7; --text-color: #000000; @@ -18,7 +18,7 @@ html { height: 100%; text-align: center; overflow: hidden; - font-family: Georgia, 'Times New Roman', Times, serif; + font-family: Georgia, "Times New Roman", Times, serif; font-size: 24px; } @@ -66,7 +66,7 @@ button { padding: 17px 20px; border-radius: 30px; cursor: pointer; - transition: all 0.3s ease-in-out; + transition: all 0.3s ease-in-out; } button:hover { @@ -79,4 +79,4 @@ button:hover { color: var(--dark-mode-icon-color); cursor: pointer; opacity: 85%; -} \ No newline at end of file +} diff --git a/quote_generator/index.html b/quote_generator/index.html index a00b433..a8affa5 100644 --- a/quote_generator/index.html +++ b/quote_generator/index.html @@ -1,33 +1,41 @@ - - - - - - Quote Generator - - - - - - - - - -
-

Today's quote

-
-

-

-
-
- -
-
-
- - - - - - - + + + + + + Quote Generator + + + + + + + + + +
+

Today's quote

+
+

+

+
+
+ +
+
+
+ + + + + + + diff --git a/quote_generator/js/matrix.js b/quote_generator/js/matrix.js index cccfc70..d746c78 100644 --- a/quote_generator/js/matrix.js +++ b/quote_generator/js/matrix.js @@ -1,13 +1,14 @@ -const canvas = document.getElementById("Matrix") -const context = canvas.getContext("2d") +const canvas = document.getElementById("Matrix"); +const context = canvas.getContext("2d"); -canvas.height = window.innerHeight + 100; -canvas.width = window.innerWidth + 5; +canvas.height = globalThis.innerHeight + 100; +canvas.width = globalThis.innerWidth + 5; -const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./*-+#$%^@!~?><:;[]{}=_αβΓγΔδεζηΘθικΛλμΞξΠπρΣσςτυΦφχΨψΩω×≦≧≠∞≒≡~∩∠∪∟⊿∫∮∵∴$¥〒¢£℃€℉╩◢ⅩⅨⅧⅦⅥⅤⅣⅢⅡⅠあいうえおがぎぐげござじずぜぞだぢつでづどにぬのばひぴぶへぺぼみゃょァゐゎè"; +const chars = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./*-+#$%^@!~?><:;[]{}=_αβΓγΔδεζηΘθικΛλμΞξΠπρΣσςτυΦφχΨψΩω×≦≧≠∞≒≡~∩∠∪∟⊿∫∮∵∴$¥〒¢£℃€℉╩◢ⅩⅨⅧⅦⅥⅤⅣⅢⅡⅠあいうえおがぎぐげござじずぜぞだぢつでづどにぬのばひぴぶへぺぼみゃょァゐゎè"; const fontSize = 16; -const columns = canvas.width / fontSize; +const columns = canvas.width / fontSize; const charArr = []; for (let i = 0; i < columns; i++) { @@ -30,7 +31,7 @@ function Update() { } context.fillStyle = str; context.font = fontSize + "px monospace"; - + for (let i = 0; i < columns; i++) { const text = chars[Math.floor(Math.random() * chars.length)]; context.fillText(text, i * fontSize, charArr[i] * fontSize); diff --git a/quote_generator/js/quote.js b/quote_generator/js/quote.js index d8be905..35e885c 100644 --- a/quote_generator/js/quote.js +++ b/quote_generator/js/quote.js @@ -5,11 +5,10 @@ const buttonElement = document.querySelector("button"); let quotes = []; fetch("./json/quotes.json") -.then(response => response.json()) -.then(data => { - quotes = data.quotes; -}); - + .then((response) => response.json()) + .then((data) => { + quotes = data.quotes; + }); function Appear() { const index = Math.floor(Math.random() * quotes.length); @@ -24,7 +23,6 @@ function Appear() { const numDarkImages = 0; const numLightImages = 0; - if (numDarkImages && numLightImages) { const isDark = Math.random() < 0.5; let randomIndex, randomImage; @@ -33,7 +31,7 @@ function Appear() { if (isDark) { randomIndex = Math.floor(Math.random() * numDarkImages) + 1; randomImage = folderPath + "dark/" + randomIndex + ".jpg"; - darkModeIcon.onclick() + darkModeIcon.onclick(); } else { randomIndex = Math.floor(Math.random() * numLightImages) + 1; randomImage = folderPath + "light/" + randomIndex + ".jpg"; diff --git a/quote_generator/js/scripts.js b/quote_generator/js/scripts.js index ab23e11..e12cda8 100644 --- a/quote_generator/js/scripts.js +++ b/quote_generator/js/scripts.js @@ -1,7 +1,6 @@ -const darkModeIcon = document.querySelector('#dark-mode-icon'); +const darkModeIcon = document.querySelector("#dark-mode-icon"); darkModeIcon.onclick = () => { - darkModeIcon.classList.toggle('bx-sun'); - document.body.classList.toggle('dark-mode'); + darkModeIcon.classList.toggle("bx-sun"); + document.body.classList.toggle("dark-mode"); }; - diff --git a/scripts.js b/scripts.js index d856735..fbd0d42 100644 --- a/scripts.js +++ b/scripts.js @@ -1,33 +1,36 @@ // fetch all folder paths of the generators from `folders.json` -let folderPaths = [] +let folderPaths = []; async function fetch_folders() { - await fetch('./folders.json') - .then(response => response.json()) - .then(data => { - folderPaths = data.folder_paths; - }) + await fetch("./folders.json") + .then((response) => response.json()) + .then((data) => { + folderPaths = data.folder_paths; + }); } async function get_generator_card_footer() { - await fetch_folders() - const repoOwner = 'LifeAdventurer'; - const repoName = 'generators'; + await fetch_folders(); + const repoOwner = "LifeAdventurer"; + const repoName = "generators"; for (let folderIndex = 1; folderIndex <= folderPaths.length; folderIndex++) { const folderPath = folderPaths[folderIndex - 1]; - const apiUrl = `https://api.github.com/repos/${repoOwner}/${repoName}/commits?path=${folderPath}`; + const apiUrl = + `https://api.github.com/repos/${repoOwner}/${repoName}/commits?path=${folderPath}`; fetch(apiUrl) - .then(response => response.json()) - .then(data => { - // the latest commit will be at the top of the list - const lastCommit = data[0].commit.author.date; - const commitTimeStamp = new Date(lastCommit).getTime() / 1000; - const currentTimeStamp = Math.floor(new Date().getTime() / 1000); - const timeDifference = currentTimeStamp - commitTimeStamp; - - $(`#last-update-${folderIndex}`).html(`Last updated ${format_time_difference(timeDifference)} ago`) - }) + .then((response) => response.json()) + .then((data) => { + // the latest commit will be at the top of the list + const lastCommit = data[0].commit.author.date; + const commitTimeStamp = new Date(lastCommit).getTime() / 1000; + const currentTimeStamp = Math.floor(new Date().getTime() / 1000); + const timeDifference = currentTimeStamp - commitTimeStamp; + + $(`#last-update-${folderIndex}`).html( + `Last updated ${format_time_difference(timeDifference)} ago`, + ); + }); // .catch(error => console.error('Error fetching data:', error)); } } @@ -39,21 +42,21 @@ function format_time_difference(seconds) { const days = Math.floor(hours / 24); if (days > 0) { - return `${days} day${days > 1 ? 's' : ''}`; - } else if(hours > 0) { - return `${hours} hour${hours > 1 ? 's' : ''}`; - } else if(minutes > 0) { - return `${minutes} minute${minutes > 1 ? 's' : ''}`; + return `${days} day${days > 1 ? "s" : ""}`; + } else if (hours > 0) { + return `${hours} hour${hours > 1 ? "s" : ""}`; + } else if (minutes > 0) { + return `${minutes} minute${minutes > 1 ? "s" : ""}`; } else { - return `${seconds} second${seconds > 1 ? 's' : ''}`; + return `${seconds} second${seconds > 1 ? "s" : ""}`; } } -get_generator_card_footer() +get_generator_card_footer(); -const darkModeIcon = document.querySelector('#dark-mode-icon'); +const darkModeIcon = document.querySelector("#dark-mode-icon"); darkModeIcon.onclick = () => { - darkModeIcon.classList.toggle('bx-sun'); - document.body.classList.toggle('dark-mode'); + darkModeIcon.classList.toggle("bx-sun"); + document.body.classList.toggle("dark-mode"); }; diff --git a/styles.css b/styles.css index 1864dd1..75999c2 100644 --- a/styles.css +++ b/styles.css @@ -64,7 +64,7 @@ h5 { .card-footer { background-color: var(--card-footer-color); - color: var(--card-footer-text-color); + color: var(--card-footer-text-color); } #footer-author { @@ -88,4 +88,4 @@ h5 { color: var(--dark-mode-icon-color); cursor: pointer; opacity: 85%; -} \ No newline at end of file +} -- 2.49.1 From 32b7abf7fc9083bf152047e9b644f3f62d137a16 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 16:11:36 +0800 Subject: [PATCH 34/98] Impr(fortune): Add new special events for November --- fortune_generator/json/special.json | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fortune_generator/json/special.json b/fortune_generator/json/special.json index e61410d..4242a15 100644 --- a/fortune_generator/json/special.json +++ b/fortune_generator/json/special.json @@ -759,6 +759,44 @@ "r_2_event": "忽略安全", "r_2_desc": "活動時忽視安全措施可能帶來風險" } + }, + { + "event": "世界善心日", + "year": "2024", + "month": "11", + "date": "13", + "status_index": "0", + "goodFortunes": { + "l_1_event": "善待他人", + "l_1_desc": "在生活中多一些善意與寬容", + "l_2_event": "", + "l_2_desc": "" + }, + "badFortunes": { + "r_1_event": "", + "r_1_desc": "", + "r_2_event": "", + "r_2_desc": "" + } + }, + { + "event": "感恩節", + "year": "2024", + "month": "11", + "date": "28", + "status_index": "0", + "goodFortunes": { + "l_1_event": "家人團聚", + "l_1_desc": "共享寶貴時光", + "l_2_event": "", + "l_2_desc": "" + }, + "badFortunes": { + "r_1_event": "", + "r_1_desc": "", + "r_2_event": "", + "r_2_desc": "" + } } ] } -- 2.49.1 From 15d3cfb35af9e52a9c9c4fbe6107cdc1e552304d Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 21:17:14 +0800 Subject: [PATCH 35/98] Feat(fortune): Implement theme switcher (Closes #42) --- fortune_generator/css/styles.css | 47 ++++++++++++++--------- fortune_generator/index.html | 61 +++++++++++++++++++++++++----- fortune_generator/js/fortune.js | 2 +- fortune_generator/js/scripts.js | 7 ---- fortune_generator/js/theme.js | 45 ++++++++++++++++++++++ fortune_generator/json/themes.json | 38 +++++++++++++++++++ 6 files changed, 164 insertions(+), 36 deletions(-) create mode 100644 fortune_generator/js/theme.js create mode 100644 fortune_generator/json/themes.json diff --git a/fortune_generator/css/styles.css b/fortune_generator/css/styles.css index 00f5bdf..ab13334 100644 --- a/fortune_generator/css/styles.css +++ b/fortune_generator/css/styles.css @@ -1,6 +1,8 @@ :root { --button-color: #73a3eb; --button-hover-color: #459aef; + --toggle-theme-button-color: #000000; + --copy-result-button-color: #000000; --bg-color: #ffffff; --good-fortune-color: #e74c3c; --bad-fortune-color: #000000bf; @@ -11,20 +13,6 @@ --title-color: #000000cc; } -.dark-mode { - --button-color: #5d99f4; - --button-hover-color: #9ac6f1; - --bg-color: #1e1d24; - --good-fortune-color: #e74c3c; - --bad-fortune-color: #d4d4d4d9; - --middle-fortune-color: #57c857; - --desc-color: #838282; - --date-color: #0ed64aed; - --special-event-color: #6477f3; - --dark-mode-icon-color: #ffffff; - --title-color: #cdcdcd; -} - * { overflow: hidden; text-align: center; @@ -101,16 +89,39 @@ button:hover { z-index: 0; } -#dark-mode-icon { +#toggle-theme-button { margin-top: 15px; font-size: 2.4rem; - color: var(--dark-mode-icon-color); + color: var(--toggle-theme-button-color); cursor: pointer; opacity: 85%; } -#copy-result { +#copy-result-button { margin-top: 20px; font-size: 1.5rem; - color: var(--dark-mode-icon-color); + color: var(--copy-result-button-color); +} + +#themeModal { + .modal-content { + background-color: var(--bg-color) !important; + color: var(--title-color) !important; + } + + .modal-header, + .modal-footer { + background-color: var(--bg-color) !important; + color: var(--bg-color) !important; + } + + .modal-title, + .btn-close { + color: var(--title-color) !important; + } +} + +#themeItem { + background-color: var(--bg-color); + color: var(--title-color); } diff --git a/fortune_generator/index.html b/fortune_generator/index.html index 6f35bb6..ab6db38 100644 --- a/fortune_generator/index.html +++ b/fortune_generator/index.html @@ -8,17 +8,11 @@ - - - @@ -40,6 +34,7 @@ } +
@@ -116,21 +111,67 @@
- +
+ + + + + + + diff --git a/fortune_generator/js/fortune.js b/fortune_generator/js/fortune.js index 8a79751..58664cb 100644 --- a/fortune_generator/js/fortune.js +++ b/fortune_generator/js/fortune.js @@ -373,7 +373,7 @@ function Appear() { J_l_2_desc.html(l_2_desc); } } - $("#copy-result").removeClass("d-none"); + $("#copy-result-button").removeClass("d-none"); } function getLuck() { diff --git a/fortune_generator/js/scripts.js b/fortune_generator/js/scripts.js index c3ce266..55fa293 100644 --- a/fortune_generator/js/scripts.js +++ b/fortune_generator/js/scripts.js @@ -1,10 +1,3 @@ -let darkModeIcon = document.querySelector("#dark-mode-icon"); - -darkModeIcon.onclick = () => { - darkModeIcon.classList.toggle("bx-sun"); - document.body.classList.toggle("dark-mode"); -}; - function copyResultImageToClipboard() { try { const $title = $("#title").clone().wrap('
'); diff --git a/fortune_generator/js/theme.js b/fortune_generator/js/theme.js new file mode 100644 index 0000000..8b2b78d --- /dev/null +++ b/fortune_generator/js/theme.js @@ -0,0 +1,45 @@ +document.addEventListener("DOMContentLoaded", () => { + const themeListContainer = document.querySelector("#themeList"); + const root = document.documentElement; + + async function fetchThemes() { + try { + const response = await fetch("./json/themes.json"); + const themes = await response.json(); + populateThemeList(themes["themes"]); + } catch (error) { + console.error("Error fetching themes:", error); + } + } + + // Populate theme list in modal + function populateThemeList(themes) { + themeListContainer.innerHTML = ""; + themes.forEach((theme) => { + const themeItem = document.createElement("div"); + themeItem.className = + "theme-item list-group-item d-flex justify-content-between align-items-center"; + themeItem.style.cursor = "pointer"; + themeItem.id = "themeItem"; + + // Add theme name + const themeName = document.createElement("span"); + themeName.textContent = theme.name; + themeItem.appendChild(themeName); + + // Apply theme on click + themeItem.addEventListener("click", () => applyTheme(theme.properties)); + + themeListContainer.appendChild(themeItem); + }); + } + + // Apply theme by setting CSS variables + function applyTheme(properties) { + Object.entries(properties).forEach(([key, value]) => { + root.style.setProperty(`--${key}`, value); + }); + } + + fetchThemes(); +}); diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json new file mode 100644 index 0000000..dcef731 --- /dev/null +++ b/fortune_generator/json/themes.json @@ -0,0 +1,38 @@ +{ + "themes": [ + { + "name": "light", + "properties": { + "bg-color": "#ffffff", + "good-fortune-color": "#e74c3c", + "bad-fortune-color": "#000000bf", + "desc-color": "#7f7f7f", + "button-color": "#73a3eb", + "button-hover-color": "#459aef", + "toggle-theme-button-color": "#000000", + "copy-result-button-color": "#000000", + "middle-fortune-color": "#5eb95e", + "date-color": "#096e1bc9", + "special-event-color": "#3e4fbb", + "title-color": "#000000cc" + } + }, + { + "name": "dark", + "properties": { + "bg-color": "#1e1d24", + "good-fortune-color": "#e74c3c", + "bad-fortune-color": "#d4d4d4d9", + "desc-color": "#838282", + "button-color": "#5d99f4", + "button-hover-color": "#9ac6f1", + "toggle-theme-button-color": "#ffffff", + "copy-result-button-color": "#ffffff", + "middle-fortune-color": "#57c857", + "date-color": "#0ed64aed", + "special-event-color": "#6477f3", + "title-color": "#cdcdcd" + } + } + ] +} -- 2.49.1 From a345a61f25d88b418adba5f1b8d454616e1a0d71 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 22:02:03 +0800 Subject: [PATCH 36/98] Feat(fortune): Add color dots for visual preview in theme item --- fortune_generator/css/styles.css | 12 ++++++++++++ fortune_generator/js/theme.js | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/fortune_generator/css/styles.css b/fortune_generator/css/styles.css index ab13334..6f9df5e 100644 --- a/fortune_generator/css/styles.css +++ b/fortune_generator/css/styles.css @@ -125,3 +125,15 @@ button:hover { background-color: var(--bg-color); color: var(--title-color); } + +.color-preview { + display: flex; /* Use flex to align dots in a row */ +} + +.color-dot { + display: inline-block; + width: 12px; /* Dot size */ + height: 12px; /* Dot size */ + border-radius: 50%; /* Circular shape */ + margin-left: 5px; /* Spacing between dots */ +} diff --git a/fortune_generator/js/theme.js b/fortune_generator/js/theme.js index 8b2b78d..b1d53b6 100644 --- a/fortune_generator/js/theme.js +++ b/fortune_generator/js/theme.js @@ -27,6 +27,17 @@ document.addEventListener("DOMContentLoaded", () => { themeName.textContent = theme.name; themeItem.appendChild(themeName); + // Add color dots for visual preview + const colorPreview = document.createElement("div"); + colorPreview.className = "color-preview"; + Object.values(theme.properties).slice(0, 3).forEach((color) => { + const colorDot = document.createElement("span"); + colorDot.style.backgroundColor = color; + colorDot.className = "color-dot"; + colorPreview.appendChild(colorDot); + }); + themeItem.appendChild(colorPreview); + // Apply theme on click themeItem.addEventListener("click", () => applyTheme(theme.properties)); -- 2.49.1 From 9b8fbe8809fa8d5c4771912b922238a98f7cc730 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 22:36:35 +0800 Subject: [PATCH 37/98] Feat(fortune): Add colorPreviewContainer to encapsulate dots for improved clarity --- fortune_generator/css/styles.css | 7 +++++++ fortune_generator/js/theme.js | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/fortune_generator/css/styles.css b/fortune_generator/css/styles.css index 6f9df5e..2a34d14 100644 --- a/fortune_generator/css/styles.css +++ b/fortune_generator/css/styles.css @@ -126,6 +126,13 @@ button:hover { color: var(--title-color); } +.color-preview-container { + display: flex; + align-items: center; + padding: 3px; + border-radius: 25px; +} + .color-preview { display: flex; /* Use flex to align dots in a row */ } diff --git a/fortune_generator/js/theme.js b/fortune_generator/js/theme.js index b1d53b6..091b375 100644 --- a/fortune_generator/js/theme.js +++ b/fortune_generator/js/theme.js @@ -27,16 +27,26 @@ document.addEventListener("DOMContentLoaded", () => { themeName.textContent = theme.name; themeItem.appendChild(themeName); + const colorPreivewContainer = document.createElement("div"); + colorPreivewContainer.className = "color-preview-container"; + + const propertyKeys = Object.keys(theme.properties); + colorPreivewContainer.style.backgroundColor = + theme.properties[propertyKeys[3]]; + // Add color dots for visual preview const colorPreview = document.createElement("div"); colorPreview.className = "color-preview"; + Object.values(theme.properties).slice(0, 3).forEach((color) => { const colorDot = document.createElement("span"); colorDot.style.backgroundColor = color; colorDot.className = "color-dot"; colorPreview.appendChild(colorDot); }); - themeItem.appendChild(colorPreview); + + colorPreivewContainer.appendChild(colorPreview); + themeItem.appendChild(colorPreivewContainer); // Apply theme on click themeItem.addEventListener("click", () => applyTheme(theme.properties)); -- 2.49.1 From f9c74860dd4f5da624f46abec4f186a7c906b651 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 22:37:59 +0800 Subject: [PATCH 38/98] Style(fortune): Remove margin on the left for the first dot in preview container --- fortune_generator/css/styles.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fortune_generator/css/styles.css b/fortune_generator/css/styles.css index 2a34d14..805ca3b 100644 --- a/fortune_generator/css/styles.css +++ b/fortune_generator/css/styles.css @@ -144,3 +144,7 @@ button:hover { border-radius: 50%; /* Circular shape */ margin-left: 5px; /* Spacing between dots */ } + +.color-preview .color-dot:first-child { + margin-left: 0; /* No margin on the left for the first dot */ +} -- 2.49.1 From ee5b9e8ffaf15e19238bad63bd201eda569dedd2 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 23:20:49 +0800 Subject: [PATCH 39/98] Impr(theme): Add new theme - winter --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index dcef731..a3c52f2 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -33,6 +33,23 @@ "special-event-color": "#6477f3", "title-color": "#cdcdcd" } + }, + { + "name": "winter", + "properties": { + "bg-color": "#dce9ef", + "good-fortune-color": "#1683b0", + "bad-fortune-color": "#C57e4D", + "desc-color": "#726D63", + "button-color": "#9577f8", + "button-hover-color": "#9ac6f1", + "toggle-theme-button-color": "#7c6543", + "copy-result-button-color": "#63835f", + "middle-fortune-color": "#cfbbc0", + "date-color": "#cc99ff", + "special-event-color": "#8ddbf2", + "title-color": "#91c9df" + } } ] } -- 2.49.1 From 6d8017fe516480ef277fc13570492aacfb3343fb Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 23:23:30 +0800 Subject: [PATCH 40/98] Chore(theme): Rearrange the order of the properties --- fortune_generator/js/theme.js | 2 +- fortune_generator/json/themes.json | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fortune_generator/js/theme.js b/fortune_generator/js/theme.js index 091b375..f29a419 100644 --- a/fortune_generator/js/theme.js +++ b/fortune_generator/js/theme.js @@ -32,7 +32,7 @@ document.addEventListener("DOMContentLoaded", () => { const propertyKeys = Object.keys(theme.properties); colorPreivewContainer.style.backgroundColor = - theme.properties[propertyKeys[3]]; + theme.properties[propertyKeys[5]]; // Add color dots for visual preview const colorPreview = document.createElement("div"); diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index a3c52f2..d15f824 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -6,15 +6,15 @@ "bg-color": "#ffffff", "good-fortune-color": "#e74c3c", "bad-fortune-color": "#000000bf", + "middle-fortune-color": "#5eb95e", + "title-color": "#000000cc", "desc-color": "#7f7f7f", "button-color": "#73a3eb", "button-hover-color": "#459aef", "toggle-theme-button-color": "#000000", "copy-result-button-color": "#000000", - "middle-fortune-color": "#5eb95e", "date-color": "#096e1bc9", - "special-event-color": "#3e4fbb", - "title-color": "#000000cc" + "special-event-color": "#3e4fbb" } }, { @@ -23,15 +23,15 @@ "bg-color": "#1e1d24", "good-fortune-color": "#e74c3c", "bad-fortune-color": "#d4d4d4d9", + "middle-fortune-color": "#57c857", + "title-color": "#cdcdcd", "desc-color": "#838282", "button-color": "#5d99f4", "button-hover-color": "#9ac6f1", "toggle-theme-button-color": "#ffffff", "copy-result-button-color": "#ffffff", - "middle-fortune-color": "#57c857", "date-color": "#0ed64aed", - "special-event-color": "#6477f3", - "title-color": "#cdcdcd" + "special-event-color": "#6477f3" } }, { @@ -40,15 +40,15 @@ "bg-color": "#dce9ef", "good-fortune-color": "#1683b0", "bad-fortune-color": "#C57e4D", + "middle-fortune-color": "#cfbbc0", + "title-color": "#91c9df", "desc-color": "#726D63", "button-color": "#9577f8", "button-hover-color": "#9ac6f1", "toggle-theme-button-color": "#7c6543", "copy-result-button-color": "#63835f", - "middle-fortune-color": "#cfbbc0", "date-color": "#cc99ff", - "special-event-color": "#8ddbf2", - "title-color": "#91c9df" + "special-event-color": "#8ddbf2" } } ] -- 2.49.1 From 8d1e04090cfc99bfa7c0958e71e73ecfd597558f Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Fri, 1 Nov 2024 23:35:40 +0800 Subject: [PATCH 41/98] Feat(theme): Save selected theme to localStorage for persistence --- fortune_generator/js/theme.js | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/fortune_generator/js/theme.js b/fortune_generator/js/theme.js index f29a419..74d3a10 100644 --- a/fortune_generator/js/theme.js +++ b/fortune_generator/js/theme.js @@ -2,6 +2,9 @@ document.addEventListener("DOMContentLoaded", () => { const themeListContainer = document.querySelector("#themeList"); const root = document.documentElement; + // Apply the saved theme if it exists + applySavedTheme(); + async function fetchThemes() { try { const response = await fetch("./json/themes.json"); @@ -49,7 +52,10 @@ document.addEventListener("DOMContentLoaded", () => { themeItem.appendChild(colorPreivewContainer); // Apply theme on click - themeItem.addEventListener("click", () => applyTheme(theme.properties)); + themeItem.addEventListener("click", () => { + applyTheme(theme.properties); + saveThemeToLocalStorage(theme.name); + }); themeListContainer.appendChild(themeItem); }); @@ -62,5 +68,24 @@ document.addEventListener("DOMContentLoaded", () => { }); } + function saveThemeToLocalStorage(themeName) { + localStorage.setItem("selectedTheme", themeName); + } + + function applySavedTheme() { + const savedThemeName = localStorage.getItem("selectedTheme"); + if (savedThemeName) { + fetch("./json/themes.json") + .then((response) => response.json()) + .then((themes) => { + const theme = themes.themes.find((t) => t.name === savedThemeName); + if (theme) { + applyTheme(theme.properties); + } + }) + .catch((error) => console.error("Error fetching themes:", error)); + } + } + fetchThemes(); }); -- 2.49.1 From b93727e5b8e6fa0d004aeff95ac9aae8dda67747 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Sat, 2 Nov 2024 16:38:25 +0800 Subject: [PATCH 42/98] Refactor: Update theme winter --- fortune_generator/json/themes.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index d15f824..823ed68 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -38,13 +38,13 @@ "name": "winter", "properties": { "bg-color": "#dce9ef", - "good-fortune-color": "#1683b0", + "good-fortune-color": "#91c9ef", "bad-fortune-color": "#C57e4D", "middle-fortune-color": "#cfbbc0", - "title-color": "#91c9df", + "title-color": "#ffc348", "desc-color": "#726D63", - "button-color": "#9577f8", - "button-hover-color": "#9ac6f1", + "button-color": "#7567b8aa", + "button-hover-color": "#7567b8dd", "toggle-theme-button-color": "#7c6543", "copy-result-button-color": "#63835f", "date-color": "#cc99ff", -- 2.49.1 From 80df03f33704c370c02326997e5ee5d47e95c8cc Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Sat, 2 Nov 2024 16:49:10 +0800 Subject: [PATCH 43/98] Docs(CONTRIBUTING): Add guidelines for contributing new themes --- CONTRIBUTING.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0042d24..a9d9c5a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -63,6 +63,47 @@ Special events require a more detailed structure. 2. Empty Fields: If there are no fortunes to add, leave the corresponding fields as empty strings (`""`). +### Adding New Themes + +#### JSON Theme Structure + +When adding a new theme to `fortune_generator/json/themes.json`, follow this +structure: + +```json +{ + "name": "theme_name", + "properties": { + "bg-color": "#hexcode", + "good-fortune-color": "#hexcode", + "bad-fortune-color": "#hexcode", + "middle-fortune-color": "#hexcode", + "title-color": "#hexcode", + "desc-color": "#hexcode", + "button-color": "#hexcode", + "button-hover-color": "#hexcode", + "toggle-theme-button-color": "#hexcode", + "copy-result-button-color": "#hexcode", + "date-color": "#hexcode", + "special-event-color": "#hexcode" + } +} +``` + +#### Guidelines for Adding Themes + +1. Naming: Choose a unique and descriptive name for the theme. +2. Properties: + - Ensure that all property values are in valid hexadecimal format (`#rrggbb` + or `#rrggbbaa` for transparency). + - Hex Format: Use lowercase for all hex color codes for consistency. + - Make sure the colors have sufficient contrast for readability. +3. Consistency: Maintain a visually coherent set of colors. +4. Testing: Preview your theme in the app to confirm that colors display as + expected and are user-friendly. +5. Pull Request Naming: + - Use a clear PR name like `Impr(theme): Add {theme_name} theme`. + ## Quote Generator ### Quotes -- 2.49.1 From 031364c2792b81ff768cdb5f1280ffb8a626e97c Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Tue, 5 Nov 2024 14:21:51 +0800 Subject: [PATCH 44/98] Impr(theme): Add new theme - Star Wars --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 823ed68..78ef323 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -50,6 +50,23 @@ "date-color": "#cc99ff", "special-event-color": "#8ddbf2" } + }, + { + "name": "Star Wars", + "properties": { + "bg-color": "#262629", + "good-fortune-color": "#15f2fd", + "bad-fortune-color": "#ff212e", + "middle-fortune-color": "#f8ff2e", + "title-color": "#ffe81f", + "desc-color": "#c0c0c0", + "button-color": "#83e4e4", + "button-hover-color": "#449cbc", + "toggle-theme-button-color": "#15f2fd", + "copy-result-button-color": "#ff212e", + "date-color": "#ffe81f", + "special-event-color": "#fc9c43" + } } ] } -- 2.49.1 From 03a72dd1d10045f17508b8e56e20d2ed3069567d Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Tue, 5 Nov 2024 15:06:25 +0800 Subject: [PATCH 45/98] Style: Use lowercases in hex colors --- fortune_generator/json/themes.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 78ef323..047b410 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -39,10 +39,10 @@ "properties": { "bg-color": "#dce9ef", "good-fortune-color": "#91c9ef", - "bad-fortune-color": "#C57e4D", + "bad-fortune-color": "#c57e4d", "middle-fortune-color": "#cfbbc0", "title-color": "#ffc348", - "desc-color": "#726D63", + "desc-color": "#726d63", "button-color": "#7567b8aa", "button-hover-color": "#7567b8dd", "toggle-theme-button-color": "#7c6543", -- 2.49.1 From 81808b7b578cec6781ed50ef8c771a8c9cb9d957 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 00:11:17 +0800 Subject: [PATCH 46/98] Impr(theme): Add new theme - Catppuccin Dark --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 047b410..b42d82a 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -67,6 +67,23 @@ "date-color": "#ffe81f", "special-event-color": "#fc9c43" } + }, + { + "name": "Catppuccin Dark", + "properties": { + "bg-color": "#1e1e2e", + "good-fortune-color": "#94e2d5", + "bad-fortune-color": "#f38ba8", + "middle-fortune-color": "#f9e2af", + "title-color": "#f5c2e7", + "desc-color": "#cdd6f4", + "button-color": "#b9fbc0", + "button-hover-color": "#a6e3a1", + "toggle-theme-button-color": "#f9e2af", + "copy-result-button-color": "#f38ba8", + "date-color": "#f5c2e7", + "special-event-color": "#fab387" + } } ] } -- 2.49.1 From 85c294b1708b10f0b1a12a42f78107ab5963672f Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 00:16:22 +0800 Subject: [PATCH 47/98] Chore(theme): Rename theme names --- fortune_generator/json/themes.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index b42d82a..006b534 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -1,7 +1,7 @@ { "themes": [ { - "name": "light", + "name": "Classic Light", "properties": { "bg-color": "#ffffff", "good-fortune-color": "#e74c3c", @@ -18,7 +18,7 @@ } }, { - "name": "dark", + "name": "Classic Dark", "properties": { "bg-color": "#1e1d24", "good-fortune-color": "#e74c3c", @@ -35,7 +35,7 @@ } }, { - "name": "winter", + "name": "Winter", "properties": { "bg-color": "#dce9ef", "good-fortune-color": "#91c9ef", -- 2.49.1 From 99d2a23f3b452659d0c8676d265f3081810b1bb0 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 00:19:44 +0800 Subject: [PATCH 48/98] Impr(theme): Add new theme - Tokyo Night --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 006b534..0cebc9d 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -84,6 +84,23 @@ "date-color": "#f5c2e7", "special-event-color": "#fab387" } + }, + { + "name": "Tokyo Night", + "properties": { + "bg-color": "#1a1b26", + "good-fortune-color": "#7dcfff", + "bad-fortune-color": "#ff5c8d", + "middle-fortune-color": "#e0af68", + "title-color": "#bb9af7", + "desc-color": "#c0caf5", + "button-color": "#6e6f8c", + "button-hover-color": "#5a5b7f", + "toggle-theme-button-color": "#7dcfff", + "copy-result-button-color": "#ff5c8d", + "date-color": "#ffbb93", + "special-event-color": "#f7768e" + } } ] } -- 2.49.1 From 3fec297ad8849189169e43efe26e8a28fa48055a Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 15:32:46 +0800 Subject: [PATCH 49/98] Impr(theme): Add new theme - Autumn Glow --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 0cebc9d..77a13ca 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -101,6 +101,23 @@ "date-color": "#ffbb93", "special-event-color": "#f7768e" } + }, + { + "name": "Autumn Glow", + "properties": { + "bg-color": "#f4ede4", + "good-fortune-color": "#e27d60", + "bad-fortune-color": "#a23b2b", + "middle-fortune-color": "#c7a17a", + "title-color": "#5a3d31", + "desc-color": "#7a6e61", + "button-color": "#c7a17a", + "button-hover-color": "#b9896e", + "toggle-theme-button-color": "#a74c3c", + "copy-result-button-color": "#7a6e61", + "date-color": "#e6b89c", + "special-event-color": "#e8a87c" + } } ] } -- 2.49.1 From 97e8a340daa24b02af0d40377eb287a13642815e Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 15:47:48 +0800 Subject: [PATCH 50/98] Impr(theme): Refactored theme - Winter to Winter Wonderland --- fortune_generator/json/themes.json | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 77a13ca..a2204bc 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -34,23 +34,6 @@ "special-event-color": "#6477f3" } }, - { - "name": "Winter", - "properties": { - "bg-color": "#dce9ef", - "good-fortune-color": "#91c9ef", - "bad-fortune-color": "#c57e4d", - "middle-fortune-color": "#cfbbc0", - "title-color": "#ffc348", - "desc-color": "#726d63", - "button-color": "#7567b8aa", - "button-hover-color": "#7567b8dd", - "toggle-theme-button-color": "#7c6543", - "copy-result-button-color": "#63835f", - "date-color": "#cc99ff", - "special-event-color": "#8ddbf2" - } - }, { "name": "Star Wars", "properties": { @@ -118,6 +101,23 @@ "date-color": "#e6b89c", "special-event-color": "#e8a87c" } + }, + { + "name": "Winter Wonderland", + "properties": { + "bg-color": "#e3f2fd", + "good-fortune-color": "#74b9ff", + "bad-fortune-color": "#6c5ce7", + "middle-fortune-color": "#81ecec", + "title-color": "#0984e3", + "desc-color": "#636e72", + "button-color": "#74b9ff", + "button-hover-color": "#a29bfe", + "toggle-theme-button-color": "#00b894", + "copy-result-button-color": "#0984e3", + "date-color": "#74b9ff", + "special-event-color": "#fdcb6e" + } } ] } -- 2.49.1 From 1464de0ff3b6b0c73713d8558894590a712575b5 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 18:39:54 +0800 Subject: [PATCH 51/98] Impr(theme): Add new theme - Spring Blossom --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index a2204bc..f07cabc 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -85,6 +85,23 @@ "special-event-color": "#f7768e" } }, + { + "name": "Spring Blossom", + "properties": { + "bg-color": "#f7f5f2", + "good-fortune-color": "#ff6f61", + "bad-fortune-color": "#6d597a", + "middle-fortune-color": "#86a77a", + "title-color": "#ff9f80", + "desc-color": "#5a5a5a", + "button-color": "#ffd166", + "button-hover-color": "#ffb347", + "toggle-theme-button-color": "#ff6f61", + "copy-result-button-color": "#6d597a", + "date-color": "#ff9f80", + "special-event-color": "#ffb6b9" + } + }, { "name": "Autumn Glow", "properties": { -- 2.49.1 From 72a3513a70bda478fc2ec877ef6be912a94c3262 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 21:29:04 +0800 Subject: [PATCH 52/98] Impr(theme): Add new theme - Sunny Vibes --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index f07cabc..04fb522 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -102,6 +102,23 @@ "special-event-color": "#ffb6b9" } }, + { + "name": "Sunny Vibes", + "properties": { + "bg-color": "#fffbeb", + "good-fortune-color": "#ff7e67", + "bad-fortune-color": "#ffcc29", + "middle-fortune-color": "#1fab89", + "title-color": "#ff8c42", + "desc-color": "#4a4a4a", + "button-color": "#ffa41b", + "button-hover-color": "#ff8500", + "toggle-theme-button-color": "#34ace0", + "copy-result-button-color": "#ffcc29", + "date-color": "#ffd32a", + "special-event-color": "#f7b731" + } + }, { "name": "Autumn Glow", "properties": { -- 2.49.1 From 9344253ebb537bb84e73eb728a6ba0bed18cad24 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 21:39:03 +0800 Subject: [PATCH 53/98] Impr(theme): Add new theme - Moonlit Night --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 04fb522..85c6b01 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -152,6 +152,23 @@ "date-color": "#74b9ff", "special-event-color": "#fdcb6e" } + }, + { + "name": "Moonlit Night", + "properties": { + "bg-color": "#1a1a2e", + "good-fortune-color": "#7ed6df", + "bad-fortune-color": "#ffeaa7", + "middle-fortune-color": "#8c94a6", + "title-color": "#ffffff", + "desc-color": "#a4b0be", + "button-color": "#30336b", + "button-hover-color": "#535c88", + "toggle-theme-button-color": "#7ed6df", + "copy-result-button-color": "#ffeaa7", + "date-color": "#dcdde1", + "special-event-color": "#ff9ff3" + } } ] } -- 2.49.1 From 6c657ad6ab439ee8acd5fcf76f3bfe67d1a4eed9 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 21:54:37 +0800 Subject: [PATCH 54/98] Impr(theme): Add new theme - Lunar Eclipse --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 85c6b01..6643c0a 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -169,6 +169,23 @@ "date-color": "#dcdde1", "special-event-color": "#ff9ff3" } + }, + { + "name": "Lunar Eclipse", + "properties": { + "bg-color": "#0d0e1a", + "good-fortune-color": "#7289da", + "bad-fortune-color": "#b56576", + "middle-fortune-color": "#a0a8c1", + "title-color": "#e1e1e6", + "desc-color": "#8b8b97", + "button-color": "#494e6b", + "button-hover-color": "#646b8a", + "toggle-theme-button-color": "#7289da", + "copy-result-button-color": "#b56576", + "date-color": "#d4d4dc", + "special-event-color": "#ffb86c" + } } ] } -- 2.49.1 From 2d2e9b5c78fcf46cb43ea8fd37cc034602334a1b Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 22:05:18 +0800 Subject: [PATCH 55/98] Impr(theme): Refactored theme - Star Wars to Galactic Glow --- fortune_generator/json/themes.json | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 6643c0a..1f6392a 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -34,23 +34,6 @@ "special-event-color": "#6477f3" } }, - { - "name": "Star Wars", - "properties": { - "bg-color": "#262629", - "good-fortune-color": "#15f2fd", - "bad-fortune-color": "#ff212e", - "middle-fortune-color": "#f8ff2e", - "title-color": "#ffe81f", - "desc-color": "#c0c0c0", - "button-color": "#83e4e4", - "button-hover-color": "#449cbc", - "toggle-theme-button-color": "#15f2fd", - "copy-result-button-color": "#ff212e", - "date-color": "#ffe81f", - "special-event-color": "#fc9c43" - } - }, { "name": "Catppuccin Dark", "properties": { @@ -186,6 +169,23 @@ "date-color": "#d4d4dc", "special-event-color": "#ffb86c" } + }, + { + "name": "Galactic Glow", + "properties": { + "bg-color": "#1b1d2a", + "good-fortune-color": "#00eaff", + "bad-fortune-color": "#ff5555", + "middle-fortune-color": "#ffe347", + "title-color": "#ffe81f", + "desc-color": "#c4c7d1", + "button-color": "#3b3f58", + "button-hover-color": "#52577a", + "toggle-theme-button-color": "#00eaff", + "copy-result-button-color": "#ff5555", + "date-color": "#9aedfe", + "special-event-color": "#ffa07a" + } } ] } -- 2.49.1 From 15a435cc77063ab1a1e5430129c5d7879806dd6c Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 22:07:07 +0800 Subject: [PATCH 56/98] Impr(theme): Add new theme - Mystic Forest --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 1f6392a..916754d 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -186,6 +186,23 @@ "date-color": "#9aedfe", "special-event-color": "#ffa07a" } + }, + { + "name": "Mystic Forest", + "properties": { + "bg-color": "#1c3b24", + "good-fortune-color": "#a1e887", + "bad-fortune-color": "#d94e3b", + "middle-fortune-color": "#83c5a3", + "title-color": "#e4f9e0", + "desc-color": "#b5c9b4", + "button-color": "#4a7a58", + "button-hover-color": "#6a9a76", + "toggle-theme-button-color": "#a1e887", + "copy-result-button-color": "#d94e3b", + "date-color": "#e4f9e0", + "special-event-color": "#9fd9b7" + } } ] } -- 2.49.1 From ccbea6777c00f76b40f05a54ef969d9f69fb90f4 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 22:09:52 +0800 Subject: [PATCH 57/98] Impr(theme): Add new theme - Vintage Sepia --- fortune_generator/json/themes.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json index 916754d..b00faa2 100644 --- a/fortune_generator/json/themes.json +++ b/fortune_generator/json/themes.json @@ -203,6 +203,23 @@ "date-color": "#e4f9e0", "special-event-color": "#9fd9b7" } + }, + { + "name": "Vintage Sepia", + "properties": { + "bg-color": "#f5e9da", + "good-fortune-color": "#d4a373", + "bad-fortune-color": "#8b5e3c", + "middle-fortune-color": "#c3a593", + "title-color": "#3f312b", + "desc-color": "#736357", + "button-color": "#a67a5b", + "button-hover-color": "#b98b6f", + "toggle-theme-button-color": "#8b5e3c", + "copy-result-button-color": "#d4a373", + "date-color": "#7f6a5d", + "special-event-color": "#c7ab93" + } } ] } -- 2.49.1 From 5874d347a0c3a7034583fbb698782925d0fed9f4 Mon Sep 17 00:00:00 2001 From: lifeadventurer Date: Wed, 6 Nov 2024 22:18:07 +0800 Subject: [PATCH 58/98] Feat(fortune): Set dynamic max-height and overflow for theme modal body with scrollable theme items --- fortune_generator/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fortune_generator/index.html b/fortune_generator/index.html index ab6db38..ca04ad8 100644 --- a/fortune_generator/index.html +++ b/fortune_generator/index.html @@ -148,7 +148,7 @@ >
-