Compare commits
1 Commits
shorten-sh
...
de37809eec
| Author | SHA1 | Date | |
|---|---|---|---|
| de37809eec |
@@ -64,16 +64,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Copy backend binary + unit file
|
- name: Copy backend binary + unit file
|
||||||
run: |
|
run: |
|
||||||
# Copy to a temp path then atomically rename into place. You can't
|
|
||||||
# overwrite a running executable in place (ETXTBSY / "Text file busy"),
|
|
||||||
# but rename(2) just swaps the directory entry while the old inode keeps
|
|
||||||
# serving the running process until the restart step picks up the new
|
|
||||||
# binary. chmod first so the exec bit survives the rename (scp doesn't
|
|
||||||
# preserve mode without -p).
|
|
||||||
scp -i ~/.ssh/deploy_key server/share-svc \
|
scp -i ~/.ssh/deploy_key server/share-svc \
|
||||||
"$DEPLOY_USER@$DEPLOY_HOST:/usr/local/bin/share-svc.new"
|
"$DEPLOY_USER@$DEPLOY_HOST:/usr/local/bin/share-svc"
|
||||||
ssh -i ~/.ssh/deploy_key "$DEPLOY_USER@$DEPLOY_HOST" \
|
|
||||||
'chmod 0755 /usr/local/bin/share-svc.new && mv -f /usr/local/bin/share-svc.new /usr/local/bin/share-svc'
|
|
||||||
scp -i ~/.ssh/deploy_key server/share-svc.service \
|
scp -i ~/.ssh/deploy_key server/share-svc.service \
|
||||||
"$DEPLOY_USER@$DEPLOY_HOST:/etc/systemd/system/share-svc.service"
|
"$DEPLOY_USER@$DEPLOY_HOST:/etc/systemd/system/share-svc.service"
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,29 @@ function apiURL(path: string) {
|
|||||||
return new URL(path, window.location.href).toString();
|
return new URL(path, window.location.href).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy text to the clipboard. navigator.clipboard is only available in a
|
||||||
|
// secure context (HTTPS or localhost); over plain HTTP it's undefined, so we
|
||||||
|
// fall back to the deprecated execCommand("copy"), which still works there.
|
||||||
|
// Must be called from within a user gesture (e.g. a click handler).
|
||||||
|
async function copyToClipboard(text: string) {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
await navigator.clipboard.writeText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ta = document.createElement("textarea");
|
||||||
|
ta.value = text;
|
||||||
|
ta.style.position = "fixed";
|
||||||
|
ta.style.opacity = "0";
|
||||||
|
document.body.appendChild(ta);
|
||||||
|
ta.focus();
|
||||||
|
ta.select();
|
||||||
|
try {
|
||||||
|
document.execCommand("copy");
|
||||||
|
} finally {
|
||||||
|
document.body.removeChild(ta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function CharacterSheet() {
|
export default function CharacterSheet() {
|
||||||
const [activeTab, setActiveTab] = useState("main");
|
const [activeTab, setActiveTab] = useState("main");
|
||||||
const [urlMode, setUrlMode] = useState(false);
|
const [urlMode, setUrlMode] = useState(false);
|
||||||
@@ -516,7 +539,7 @@ export default function CharacterSheet() {
|
|||||||
// Backend unreachable: fall back to a self-contained inline ?c= link.
|
// Backend unreachable: fall back to a self-contained inline ?c= link.
|
||||||
shareURL = base + "?c=" + (await compressToBase64(json));
|
shareURL = base + "?c=" + (await compressToBase64(json));
|
||||||
}
|
}
|
||||||
await navigator.clipboard.writeText(shareURL);
|
await copyToClipboard(shareURL);
|
||||||
setCopyStatus(true);
|
setCopyStatus(true);
|
||||||
setTimeout(() => setCopyStatus(false), 2000);
|
setTimeout(() => setCopyStatus(false), 2000);
|
||||||
}, [collectData]);
|
}, [collectData]);
|
||||||
|
|||||||
Reference in New Issue
Block a user