Skip to content

Commit f1b283b

Browse files
authored
Add files via upload
1 parent 3d4cb35 commit f1b283b

3 files changed

Lines changed: 78 additions & 22 deletions

File tree

app.js

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ const els = {
11661166
yarnEditTitle: document.querySelector("#yarnEditTitle"),
11671167
stashList: document.querySelector("#stashList"),
11681168
stockTypeTabs: document.querySelector("#stockTypeTabs"),
1169+
importStashBtn: document.querySelector("#importStashBtn"),
11691170
colorCardYarnBtn: document.querySelector("#colorCardYarnBtn"),
11701171
bulkYarnBtn: document.querySelector("#bulkYarnBtn"),
11711172
newYarnBtn: document.querySelector("#newYarnBtn"),
@@ -3033,13 +3034,21 @@ async function signOutGoogle() {
30333034
await firebaseAuth.signOut();
30343035
}
30353036

3036-
function patternCloudShareUrl(dataUrl) {
3037-
const url = new URL(location.href);
3037+
function shareBaseUrl() {
3038+
return PUBLIC_ASSET_BASE;
3039+
}
3040+
3041+
function shareUrlWithParam(key, value) {
3042+
const url = new URL(shareBaseUrl());
30383043
url.hash = "";
3039-
url.searchParams.set("importPatternUrl", dataUrl);
3044+
url.searchParams.set(key, value);
30403045
return url.toString();
30413046
}
30423047

3048+
function patternCloudShareUrl(dataUrl) {
3049+
return shareUrlWithParam("importPatternUrl", dataUrl);
3050+
}
3051+
30433052
function extractPatternImportUrl(text) {
30443053
const value = String(text || "").trim();
30453054
if (!value) return "";
@@ -3116,7 +3125,7 @@ async function checkSharedPatternImportUrl() {
31163125

31173126
async function sharePattern(pattern) {
31183127
const payload = patternSharePackage(pattern);
3119-
const shareUrl = `${location.origin}${location.pathname}#pattern=${encodeSharePayload(payload)}`;
3128+
const shareUrl = `${shareBaseUrl()}#pattern=${encodeSharePayload(payload)}`;
31203129
const text = `匯入「${pattern.name}」織圖:${shareUrl}`;
31213130
const canUseLink = shareUrl.length < 1800;
31223131
if (canUseLink && navigator.share) {
@@ -3149,6 +3158,30 @@ function stashSharePackage(items) {
31493158
};
31503159
}
31513160

3161+
function stashCloudShareUrl(dataUrl) {
3162+
return shareUrlWithParam("importStashUrl", dataUrl);
3163+
}
3164+
3165+
function extractStashImportUrl(text) {
3166+
const value = String(text || "").trim();
3167+
if (!value) return "";
3168+
try {
3169+
const url = new URL(value);
3170+
const embedded = url.searchParams.get("importStashUrl") || url.searchParams.get("stashUrl");
3171+
if (embedded) return embedded;
3172+
if (url.hostname.includes("res.cloudinary.com")) return url.toString();
3173+
} catch {}
3174+
return "";
3175+
}
3176+
3177+
async function readStashImportText(textOrUrl) {
3178+
const importUrl = extractStashImportUrl(textOrUrl);
3179+
if (!importUrl) return normalizeClipboardJsonText(textOrUrl);
3180+
const response = await fetch(importUrl);
3181+
if (!response.ok) throw new Error("無法讀取庫存分享資料");
3182+
return normalizeClipboardJsonText(await response.text());
3183+
}
3184+
31523185
function importStashPackage(payload) {
31533186
const items = payload?.type === "gogo-stash" ? payload.items : payload?.items || [];
31543187
if (!Array.isArray(items) || !items.length) throw new Error("不是可匯入的庫存連結");
@@ -3163,27 +3196,41 @@ function importStashPackage(payload) {
31633196
return normalized;
31643197
}
31653198

3199+
function finishImportedStash(imported) {
3200+
activeStockType = imported[0]?.stockType || activeStockType;
3201+
selectedYarnId = imported[0]?.id || selectedYarnId;
3202+
selectedYarnIds.clear();
3203+
switchView("stash");
3204+
alert(`已匯入 ${imported.length} 個庫存項目。`);
3205+
}
3206+
3207+
async function importStashText(textOrUrl) {
3208+
const text = await readStashImportText(textOrUrl);
3209+
const imported = importStashPackage(JSON.parse(text));
3210+
finishImportedStash(imported);
3211+
}
3212+
3213+
async function importStashFromClipboard() {
3214+
try {
3215+
const text = await navigator.clipboard.readText();
3216+
await importStashText(text);
3217+
} catch (error) {
3218+
alert(`剪貼簿內容不是可匯入的庫存資料:${error.message || "請確認已複製庫存分享連結"}`);
3219+
}
3220+
}
3221+
31663222
async function shareStashItems(items) {
31673223
const payload = stashSharePackage(items);
3168-
const shareUrl = `${location.origin}${location.pathname}#stash=${encodeSharePayload(payload)}`;
31693224
const title = items.length === 1 ? `匯入「${items[0].colorName}」庫存` : `匯入 ${items.length} 個庫存項目`;
3170-
if (shareUrl.length > 6000) {
3171-
alert("選取的庫存資料太多或含圖片,連結會太長。請少選幾個,或先移除圖片後再分享。");
3172-
return;
3173-
}
3174-
if (navigator.share) {
3175-
try {
3176-
await navigator.share({ title, text: title, url: shareUrl });
3177-
return;
3178-
} catch (error) {
3179-
if (error.name === "AbortError") return;
3180-
}
3181-
}
3225+
const text = JSON.stringify(payload, null, 2);
3226+
const filename = items.length === 1 ? `${items[0]?.colorName || "gogo-stash"}.txt` : `${items.length}-stash-items.txt`;
31823227
try {
3183-
await navigator.clipboard?.writeText(shareUrl);
3184-
alert("分享連結已複製。");
3185-
} catch {
3186-
prompt("複製這個庫存分享連結:", shareUrl);
3228+
const dataUrl = await uploadTextToCloudinary(text, filename);
3229+
const shareUrl = stashCloudShareUrl(dataUrl);
3230+
await navigator.clipboard.writeText(shareUrl);
3231+
alert(`${title}的連結已複製,可以貼到 LINE 或其他裝置匯入。`);
3232+
} catch (error) {
3233+
alert(`庫存分享失敗:${error.message || "請稍後再試"}`);
31873234
}
31883235
}
31893236

@@ -3207,6 +3254,13 @@ function checkSharedPatternFromUrl() {
32073254
}
32083255

32093256
function checkSharedStashFromUrl() {
3257+
const importUrl = new URLSearchParams(location.search).get("importStashUrl");
3258+
if (importUrl) {
3259+
importStashText(importUrl)
3260+
.catch((error) => alert(`庫存分享連結無法匯入:${error.message || "請確認連結是否正確"}`))
3261+
.finally(() => history.replaceState(null, "", location.pathname + location.hash));
3262+
return;
3263+
}
32103264
const match = location.hash.match(/^#stash=(.+)$/);
32113265
if (!match) return;
32123266
try {
@@ -5732,6 +5786,7 @@ els.stockTypeTabs.addEventListener("click", (event) => {
57325786
selectedYarnIds.clear();
57335787
render();
57345788
});
5789+
els.importStashBtn?.addEventListener("click", importStashFromClipboard);
57355790
els.yarnImageInput.addEventListener("change", () => readImages(els.yarnImageInput.files, addYarnImage));
57365791
attachCoverImageHandlers(els.yarnImagePreview, "[data-yarn-image]", () => state.yarns.find((item) => item.id === selectedYarnId), "yarn");
57375792
els.yarnImagePreview.addEventListener("click", (event) => {

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ <h2 id="partEditTitle">編輯部分</h2>
240240
<div class="section-header">
241241
<h2>庫存</h2>
242242
<div class="inline-actions">
243+
<button class="outline-button compact" id="importStashBtn">匯入</button>
243244
<button class="primary-button compact" id="newYarnBtn">+ 新增</button>
244245
</div>
245246
</div>

service-worker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const VERSION = "135";
1+
const VERSION = "137";
22
const CACHE_NAME = `free-knit-workbench-v${VERSION}`;
33
const ASSETS = [
44
"./",

0 commit comments

Comments
 (0)