diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
index f2c9e97..e5cdbf6 100644
--- a/.github/workflows/static.yml
+++ b/.github/workflows/static.yml
@@ -31,13 +31,17 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- - name: Setup Pages
- uses: actions/configure-pages@v5
- - name: Upload artifact
- uses: actions/upload-pages-artifact@v3
+
+ - name: Write Commit Hash
+ run: |
+ cat << EOF | tee fortune_generator/json/commit_hash.json > /dev/null
+ {"commit_hash": "$(git rev-parse HEAD)"}
+ EOF
+
+ - name: Deploy
+ uses: peaceiris/actions-gh-pages@v4
+ if: github.ref == 'refs/heads/main'
with:
- # Upload entire repository
- path: '.'
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: ./
+ publish_branch: gh-pages
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 775cae2..733eb4d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -128,6 +128,7 @@ structure:
"button-hover-color": "#hexcode",
"toggle-theme-button-color": "#hexcode",
"copy-result-button-color": "#hexcode",
+ "copy-preview-result-url-button-color": "#hexcode",
"date-color": "#hexcode",
"special-event-color": "#hexcode"
}
diff --git a/fortune_generator/css/styles.css b/fortune_generator/css/styles.css
index 6ac434e..d0474a6 100644
--- a/fortune_generator/css/styles.css
+++ b/fortune_generator/css/styles.css
@@ -3,6 +3,7 @@
--button-hover-color: #459aef;
--toggle-theme-button-color: #000000;
--copy-result-button-color: #000000;
+ --copy-preview-result-url-button-color: #000000;
--bg-color: #ffffff;
--good-fortune-color: #e74c3c;
--bad-fortune-color: #000000bf;
@@ -99,10 +100,16 @@ button:hover {
#copy-result-button {
margin-top: 20px;
- font-size: 1.5rem;
+ font-size: 2.2rem;
color: var(--copy-result-button-color);
}
+#copy-preview-result-url-button {
+ margin-top: 20px;
+ font-size: 2.2rem;
+ color: var(--copy-preview-result-url-button-color);
+}
+
#themeModal {
.modal-content {
background-color: var(--bg-color) !important;
diff --git a/fortune_generator/index.html b/fortune_generator/index.html
index ca04ad8..5f0faee 100644
--- a/fortune_generator/index.html
+++ b/fortune_generator/index.html
@@ -121,7 +121,12 @@
點擊打卡
+
diff --git a/fortune_generator/js/fortune.js b/fortune_generator/js/fortune.js
index 714d259..b74af1b 100644
--- a/fortune_generator/js/fortune.js
+++ b/fortune_generator/js/fortune.js
@@ -24,16 +24,25 @@ fetch("https://api.ipify.org?format=json").then((response) => {
let goodFortunes = [];
let badFortunes = [];
let special_events = [];
-let fortune_generated = false;
+let commit_hash = "";
// using async and await to prevent fetching the data too late...
-async function fetch_data() {
- await fetch("./json/fortune.json")
+async function fetch_data(commit_hash) {
+ let prefix = "";
+ if (commit_hash) {
+ prefix = `https://raw.githubusercontent.com/LifeAdventurer/generators/${commit_hash}/fortune_generator/`;
+ }
+ await fetch(`${prefix}./json/fortune.json`)
.then((response) => response.json())
.then((data) => {
goodFortunes = data.goodFortunes;
badFortunes = data.badFortunes;
});
+ await fetch('./json/commit_hash.json')
+ .then((response) => response.json())
+ .then((data) => {
+ commit_hash = data.commit_hash;
+ });
async function fetch_events(path) {
await fetch(path)
@@ -43,9 +52,9 @@ async function fetch_data() {
});
}
- await fetch_events("./json/custom_special.json");
- await fetch_events("./json/static_special.json");
- await fetch_events("./json/cyclical_special.json");
+ await fetch_events(`${prefix}./json/custom_special.json`);
+ await fetch_events(`${prefix}./json/static_special.json`);
+ await fetch_events(`${prefix}./json/cyclical_special.json`);
}
const textColorClass = [
@@ -267,13 +276,35 @@ const J_r_2_desc = $("#r-2-desc");
const J_ip_to_fortune = $("#ip-to-fortune");
let special = false;
-let special_events_index = 0;
+let special_events_index = -1;
+let l1 = -1, l2 = -1, r1 = -1, r2 = -1;
+let status_index = -1;
+let seed1 = -1, seed2 = -1;
+let fortune_generated = false;
+let preview_result = false;
let current_day_special_events = [];
// init page
async function init_page() {
+ let urlParams = new URLSearchParams(window.location.search);
+ let commit_hash = null;
+ if (urlParams.has('fi') && urlParams.has('si') && urlParams.has('ei'), urlParams.has('ch')) { // fortune_index, status_index, event_index, commit_hash
+ status_index = parseInt(urlParams.get('si'));
+ special_events_index = parseInt(urlParams.get('ei'));
+ [l1, l2, r1, r2] = urlParams.get('fi').split(':').map(num => parseInt(num));
+ commit_hash = urlParams.get('ch');
+ if (isNaN(status_index) || isNaN(special_events_index) || isNaN(l1) || isNaN(l2) || isNaN(r1) || isNaN(r2)) {
+ special_events_index = -1;
+ l1 = -1, l2 = -1, r1 = -1, r2 = -1;
+ status_index = -1;
+ commit_hash = null;
+ } else {
+ preview_result = true;
+ if (special_events_index != -1) special = true;
+ }
+ }
// fetch data from `fortune.json`
- await fetch_data();
+ await fetch_data(commit_hash);
// hide the elements of show fortune page
$("#result-page").hide();
@@ -295,68 +326,71 @@ async function init_page() {
$("#date").html(showDate);
$("#weekday").html(showDay);
- const showSpecialEventCount = 2;
- let eventIndexList = Array(showSpecialEventCount).fill(-1);
- let eventDiffDaysIndexList = Array(showSpecialEventCount).fill(
- Number.MAX_SAFE_INTEGER,
- );
+ if (preview_result) Appear();
+ if (!preview_result) {
+ const showSpecialEventCount = 2;
+ let eventIndexList = Array(showSpecialEventCount).fill(-1);
+ let eventDiffDaysIndexList = Array(showSpecialEventCount).fill(
+ Number.MAX_SAFE_INTEGER,
+ );
- // check if there is special event today
- for (let i = 0; i < special_events.length; i++) {
- let diffCount = daysDiff(i);
- if (diffCount > 0) {
- let j = 0;
- for (; j < showSpecialEventCount; j++) {
- if (diffCount < eventDiffDaysIndexList[j]) {
- break;
+ // check if there is special event today
+ for (let i = 0; i < special_events.length; i++) {
+ let diffCount = daysDiff(i);
+ if (diffCount > 0) {
+ let j = 0;
+ for (; j < showSpecialEventCount; j++) {
+ if (diffCount < eventDiffDaysIndexList[j]) {
+ break;
+ }
}
+
+ eventDiffDaysIndexList[j] = diffCount;
+ eventIndexList[j] = i;
+ } else if (diffCount === 0) {
+ special = true;
+ current_day_special_events.push(i);
}
-
- eventDiffDaysIndexList[j] = diffCount;
- eventIndexList[j] = i;
- } else if (diffCount === 0) {
- special = true;
- current_day_special_events.push(i);
}
- }
- special_events_index = ip.split(".").map(num => parseInt(num)).reduce((acc, cur) => acc + cur);
- special_events_index %= current_day_special_events.length;
- special_events_index = current_day_special_events[special_events_index];
+ special_events_index = ip.split(".").map(num => parseInt(num)).reduce((acc, cur) => acc + cur);
+ special_events_index %= current_day_special_events.length;
+ special_events_index = current_day_special_events[special_events_index];
- // if there is upcoming event then show
- 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);
+ // if there is upcoming event then show
+ 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);
+ }
}
- }
- // 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);
- }
+ // 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 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);
+ 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()
- ) {
- fortune_generated = true;
- Update();
+ if (
+ now_date.getFullYear() === last_date.getFullYear() &&
+ now_date.getMonth() === last_date.getMonth() &&
+ now_date.getDate() === last_date.getDate()
+ ) {
+ fortune_generated = true;
+ Update();
+ }
}
}
}
@@ -383,11 +417,7 @@ function Appear() {
const badLen = badFortunes.length;
const statusLen = fortuneStatus.length;
- let status_index = -1;
- let seed1 = -1;
- let seed2 = -1;
-
- if (!fortune_generated) {
+ if (!fortune_generated && !preview_result) {
// transform ip to four numbers
const num = ip.split(".").map((num) => parseInt(num));
@@ -430,7 +460,7 @@ function Appear() {
localStorage.setItem("last_status_index", status_index.toString());
localStorage.setItem("last_seed1", seed1.toString());
localStorage.setItem("last_seed2", seed2.toString());
- } else {
+ } else if (!preview_result) {
status_index = parseInt(localStorage.getItem("last_status_index"));
seed1 = parseInt(localStorage.getItem("last_seed1"));
seed2 = parseInt(localStorage.getItem("last_seed2"));
@@ -453,41 +483,43 @@ function Appear() {
}
// make sure the events won't collide
- const set = new Set();
- const l1 = (seed1 % goodLen + goodLen) % goodLen;
- set.add(goodFortunes[l1].event);
- 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 >> 2) + ((month * 42 + year) << 3 + 3) + 19) % badLen + badLen) %
- badLen;
- if (
- r1 == 0 &&
- (Math.abs(seed1) % 2 === Math.abs(seed2) % 2 || seed1 % 2 === 0 ||
- seed2 % 3 === 1)
- ) {
- r1 = (r1 + (Math.abs(seed1 - seed2) % 100) >> 4) % badLen;
- }
- while (set.has(badFortunes[r1].event)) {
- r1 = (r1 + 7) % badLen;
- }
- set.add(badFortunes[r1].event);
- let r2 = (((((seed1 << 3 + 7) + (year >> 5) * (date << 2 + 3)) *
- seed2) >> 4 + seed2 % 42) % badLen + badLen) % badLen;
- if (
- r2 == 0 &&
- (Math.abs(seed1) % 3 % 2 === Math.abs(seed2) % 3 % 2 ||
- seed1 % 3 === seed2 % 2 || (month % 3 === 1 && year % 2 === 1) ||
- month % 4 === 3 || date % 7 === 2)
- ) {
- r2 = ((r2 - (Math.abs(seed1 + seed2) % 10) >> 1) % badLen + badLen) %
+ if (!preview_result) {
+ const set = new Set();
+ l1 = (seed1 % goodLen + goodLen) % goodLen;
+ set.add(goodFortunes[l1].event);
+ l2 = (((seed1 << 1) + date) % goodLen + goodLen) % goodLen;
+ while (set.has(goodFortunes[l2].event)) {
+ l2 = (l2 + 1) % goodLen;
+ }
+ set.add(goodFortunes[l2].event);
+ r1 =
+ (((seed1 >> 2) + ((month * 42 + year) << 3 + 3) + 19) % badLen + badLen) %
badLen;
- }
- while (set.has(badFortunes[r2].event)) {
- r2 = (r2 + 17) % badLen;
+ if (
+ r1 == 0 &&
+ (Math.abs(seed1) % 2 === Math.abs(seed2) % 2 || seed1 % 2 === 0 ||
+ seed2 % 3 === 1)
+ ) {
+ r1 = (r1 + (Math.abs(seed1 - seed2) % 100) >> 4) % badLen;
+ }
+ while (set.has(badFortunes[r1].event)) {
+ r1 = (r1 + 7) % badLen;
+ }
+ set.add(badFortunes[r1].event);
+ r2 = (((((seed1 << 3 + 7) + (year >> 5) * (date << 2 + 3)) *
+ seed2) >> 4 + seed2 % 42) % badLen + badLen) % badLen;
+ if (
+ r2 == 0 &&
+ (Math.abs(seed1) % 3 % 2 === Math.abs(seed2) % 3 % 2 ||
+ seed1 % 3 === seed2 % 2 || (month % 3 === 1 && year % 2 === 1) ||
+ month % 4 === 3 || date % 7 === 2)
+ ) {
+ r2 = ((r2 - (Math.abs(seed1 + seed2) % 10) >> 1) % badLen + badLen) %
+ badLen;
+ }
+ while (set.has(badFortunes[r2].event)) {
+ r2 = (r2 + 17) % badLen;
+ }
}
// organize the stuffs below this line...
@@ -569,6 +601,14 @@ function Appear() {
}
}
$("#copy-result-button").removeClass("d-none");
+ $("#copy-preview-result-url-button").removeClass("d-none");
+}
+
+function copyPreviewResultUrlToClipboard() {
+ let baseUrl = location.href.split("?")[0];
+ let url = `${baseUrl}?si=${status_index}&ei=${special_events_index}&fi=${[l1,l2,r1,r2].join(":")}&ch=${commit_hash.substr(0, 7)}`;
+ navigator.clipboard.writeText(url);
+ showCopiedNotice();
}
function getLuck() {
diff --git a/fortune_generator/json/themes.json b/fortune_generator/json/themes.json
index 91f8fe1..ab39ff6 100644
--- a/fortune_generator/json/themes.json
+++ b/fortune_generator/json/themes.json
@@ -13,6 +13,7 @@
"button-hover-color": "#459aef",
"toggle-theme-button-color": "#000000",
"copy-result-button-color": "#000000",
+ "copy-preview-result-url-button-color": "#000000",
"date-color": "#096e1bc9",
"special-event-color": "#3e4fbb"
}
@@ -30,6 +31,7 @@
"button-hover-color": "#9ac6f1",
"toggle-theme-button-color": "#ffffff",
"copy-result-button-color": "#ffffff",
+ "copy-preview-result-url-button-color": "#ffffff",
"date-color": "#0ed64aed",
"special-event-color": "#6477f3"
}
@@ -47,6 +49,7 @@
"button-hover-color": "#a6e3a1",
"toggle-theme-button-color": "#f9e2af",
"copy-result-button-color": "#f38ba8",
+ "copy-preview-result-url-button-color": "#f38ba8",
"date-color": "#f5c2e7",
"special-event-color": "#fab387"
}
@@ -64,6 +67,7 @@
"button-hover-color": "#5a5b7f",
"toggle-theme-button-color": "#7dcfff",
"copy-result-button-color": "#ff5c8d",
+ "copy-preview-result-url-button-color": "#ff5c8d",
"date-color": "#ffbb93",
"special-event-color": "#f7768e"
}
@@ -81,6 +85,7 @@
"button-hover-color": "#ffb347",
"toggle-theme-button-color": "#ff6f61",
"copy-result-button-color": "#6d597a",
+ "copy-preview-result-url-button-color": "#6d597a",
"date-color": "#ff9f80",
"special-event-color": "#ffb6b9"
}
@@ -98,6 +103,7 @@
"button-hover-color": "#ff8500",
"toggle-theme-button-color": "#34ace0",
"copy-result-button-color": "#ffcc29",
+ "copy-preview-result-url-button-color": "#ffcc29",
"date-color": "#ffd32a",
"special-event-color": "#f7b731"
}
@@ -115,6 +121,7 @@
"button-hover-color": "#b9896e",
"toggle-theme-button-color": "#a74c3c",
"copy-result-button-color": "#7a6e61",
+ "copy-preview-result-url-button-color": "#7a6e61",
"date-color": "#e6b89c",
"special-event-color": "#e8a87c"
}
@@ -132,6 +139,7 @@
"button-hover-color": "#a29bfe",
"toggle-theme-button-color": "#00b894",
"copy-result-button-color": "#0984e3",
+ "copy-preview-result-url-button-color": "#0984e3",
"date-color": "#74b9ff",
"special-event-color": "#fdcb6e"
}
@@ -149,6 +157,7 @@
"button-hover-color": "#535c88",
"toggle-theme-button-color": "#7ed6df",
"copy-result-button-color": "#ffeaa7",
+ "copy-preview-result-url-button-color": "#ffeaa7",
"date-color": "#dcdde1",
"special-event-color": "#ff9ff3"
}
@@ -166,6 +175,7 @@
"button-hover-color": "#646b8a",
"toggle-theme-button-color": "#7289da",
"copy-result-button-color": "#b56576",
+ "copy-preview-result-url-button-color": "#b56576",
"date-color": "#d4d4dc",
"special-event-color": "#ffb86c"
}
@@ -183,6 +193,7 @@
"button-hover-color": "#52577a",
"toggle-theme-button-color": "#00eaff",
"copy-result-button-color": "#ff5555",
+ "copy-preview-result-url-button-color": "#ff5555",
"date-color": "#9aedfe",
"special-event-color": "#ffa07a"
}
@@ -200,6 +211,7 @@
"button-hover-color": "#6a9a76",
"toggle-theme-button-color": "#a1e887",
"copy-result-button-color": "#d94e3b",
+ "copy-preview-result-url-button-color": "#d94e3b",
"date-color": "#e4f9e0",
"special-event-color": "#9fd9b7"
}
@@ -217,6 +229,7 @@
"button-hover-color": "#b98b6f",
"toggle-theme-button-color": "#8b5e3c",
"copy-result-button-color": "#d4a373",
+ "copy-preview-result-url-button-color": "#d4a373",
"date-color": "#7f6a5d",
"special-event-color": "#c7ab93"
}
@@ -234,6 +247,7 @@
"button-hover-color": "#2980b9",
"toggle-theme-button-color": "#4e8c47",
"copy-result-button-color": "#d9534f",
+ "copy-preview-result-url-button-color": "#d9534f",
"date-color": "#bdc3c7",
"special-event-color": "#f39c12"
}
@@ -251,6 +265,7 @@
"button-hover-color": "#ff6347",
"toggle-theme-button-color": "#00bfae",
"copy-result-button-color": "#ff6347",
+ "copy-preview-result-url-button-color": "#ff6347",
"date-color": "#2e8b57",
"special-event-color": "#ff8c00"
}
@@ -268,6 +283,7 @@
"button-hover-color": "#fc4f48",
"toggle-theme-button-color": "#e1b1e3",
"copy-result-button-color": "#c93f36",
+ "copy-preview-result-url-button-color": "#c93f36",
"date-color": "#cf63a1",
"special-event-color": "#f6c6d4"
}
@@ -285,6 +301,7 @@
"button-hover-color": "#b0b098",
"toggle-theme-button-color": "#8c9f6f",
"copy-result-button-color": "#e18e8b",
+ "copy-preview-result-url-button-color": "#e18e8b",
"date-color": "#4f5049",
"special-event-color": "#b7c7b5"
}
@@ -302,6 +319,7 @@
"button-hover-color": "#5072b3",
"toggle-theme-button-color": "#00d084",
"copy-result-button-color": "#455a64",
+ "copy-preview-result-url-button-color": "#455a64",
"date-color": "#cfd8dc",
"special-event-color": "#a1d6ff"
}
@@ -319,6 +337,7 @@
"button-hover-color": "#005f87",
"toggle-theme-button-color": "#00f5d4",
"copy-result-button-color": "#293462",
+ "copy-preview-result-url-button-color": "#293462",
"date-color": "#72efdd",
"special-event-color": "#72ddf7"
}
diff --git a/scripts/check-theme.py b/scripts/check-theme.py
index b6b1584..eafba31 100644
--- a/scripts/check-theme.py
+++ b/scripts/check-theme.py
@@ -117,6 +117,7 @@ def check_theme(theme, idx: int):
("button-hover-color", str),
("toggle-theme-button-color", str),
("copy-result-button-color", str),
+ ("copy-preview-result-url-button-color", str),
("date-color", str),
("special-event-color", str),
]