🎨 Adds publishing service settings page on mobile (#16228)

fix https://github.com/siyuan-note/siyuan/issues/16224
This commit is contained in:
Jeffrey Chen 2025-10-28 20:43:58 +08:00 committed by GitHub
parent 992ab53f4b
commit 3d50e40177
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 109 additions and 61 deletions

View file

@ -210,7 +210,7 @@ ${checkUpdateHTML}
<div class="b3-label__text"> <div class="b3-label__text">
${window.siyuan.languages.about17} ${window.siyuan.languages.about17}
</div> </div>
<div class="b3-label__text fn__flex config__item" style="padding: 4px 0 4px 4px;"> <div class="b3-label__text fn__flex config__item">
<select id="aboutScheme" class="b3-select"> <select id="aboutScheme" class="b3-select">
<option value="" ${window.siyuan.config.system.networkProxy.scheme === "" ? "selected" : ""}>${window.siyuan.languages.directConnection}</option> <option value="" ${window.siyuan.config.system.networkProxy.scheme === "" ? "selected" : ""}>${window.siyuan.languages.directConnection}</option>
<option value="socks5" ${window.siyuan.config.system.networkProxy.scheme === "socks5" ? "selected" : ""}>SOCKS5</option> <option value="socks5" ${window.siyuan.config.system.networkProxy.scheme === "socks5" ? "selected" : ""}>SOCKS5</option>

View file

@ -10,7 +10,7 @@ export const ai = {
<div class="b3-label__text"> <div class="b3-label__text">
${window.siyuan.languages.apiProviderTip} ${window.siyuan.languages.apiProviderTip}
</div> </div>
<div class="b3-label__text fn__flex config__item" style="padding: 4px 0 4px 4px;"> <div class="b3-label__text fn__flex config__item">
<select id="apiProvider" class="b3-select"> <select id="apiProvider" class="b3-select">
<option value="OpenAI" ${window.siyuan.config.ai.openAI.apiProvider === "OpenAI" ? "selected" : ""}>OpenAI</option> <option value="OpenAI" ${window.siyuan.config.ai.openAI.apiProvider === "OpenAI" ? "selected" : ""}>OpenAI</option>
<option value="Azure" ${window.siyuan.config.ai.openAI.apiProvider === "Azure" ? "selected" : ""}>Azure</option> <option value="Azure" ${window.siyuan.config.ai.openAI.apiProvider === "Azure" ? "selected" : ""}>Azure</option>

View file

@ -1,11 +1,12 @@
import {fetchPost} from "../util/fetch"; import {fetchPost} from "../util/fetch";
import {hasClosestByTag} from "../protyle/util/hasClosest"; import {hasClosestByTag} from "../protyle/util/hasClosest";
import {isMobile} from "../util/functions";
export const publish = { export const publish = {
element: undefined as Element, element: undefined as Element,
genHTML: () => { genHTML: () => {
const mobile = isMobile();
return ` return `
<!-- publish service -->
<label class="fn__flex b3-label"> <label class="fn__flex b3-label">
<div class="fn__flex-1"> <div class="fn__flex-1">
${window.siyuan.languages.publishService} ${window.siyuan.languages.publishService}
@ -14,34 +15,40 @@ export const publish = {
<span class="fn__space"></span> <span class="fn__space"></span>
<input class="b3-switch fn__flex-center" id="publishEnable" type="checkbox"${window.siyuan.config.publish.enable ? " checked" : ""}/> <input class="b3-switch fn__flex-center" id="publishEnable" type="checkbox"${window.siyuan.config.publish.enable ? " checked" : ""}/>
</label> </label>
<div class="b3-label"> <div class="b3-label">
<!-- publish service port --> ${(()=>{
if (mobile) {
return `
${window.siyuan.languages.publishServicePort}
<span class="fn__hr"></span>
<input class="b3-text-field fn__block" id="publishPort" type="number" min="0" max="65535" value="${window.siyuan.config.publish.port}">
<div class="b3-label__text">${window.siyuan.languages.publishServicePortTip}</div>`;
} else {
return `
<div class="fn__flex">
<div class="fn__flex-1">
${window.siyuan.languages.publishServicePort}
<div class="b3-label__text">${window.siyuan.languages.publishServicePortTip}</div>
</div>
<span class="fn__space"></span>
<input class="b3-text-field fn__flex-center fn__size200" id="publishPort" type="number" min="0" max="65535" value="${window.siyuan.config.publish.port}">
</div>`;
}
})()}
</div>
<div class="b3-label">
<div class="fn__flex"> <div class="fn__flex">
<div class="fn__flex-1"> <div class="fn__flex-1">
${window.siyuan.languages.publishServicePort} ${window.siyuan.languages.publishServiceAddresses}
<div class="b3-label__text">${window.siyuan.languages.publishServicePortTip}</div> <div class="b3-label__text">${window.siyuan.languages.publishServiceAddressesTip}</div>
</div> </div>
<span class="fn__space"></span> <div class="fn__space"></div>
<input class="b3-text-field fn__flex-center fn__size200" id="publishPort" type="number" min="0" max="65535" value="${window.siyuan.config.publish.port}">
</div> </div>
<div class="fn__hr"></div>
<!-- publish service address list --> <div id="publishAddresses">
<div class="b3-label">
<div class="fn__flex config__item">
<div class="fn__flex-1">
${window.siyuan.languages.publishServiceAddresses}
<div class="b3-label__text">${window.siyuan.languages.publishServiceAddressesTip}</div>
</div>
<div class="fn__space"></div>
</div>
<div class="b3-label" id="publishAddresses">
</div>
</div> </div>
</div> </div>
<div class="b3-label"> <div class="b3-label">
<!-- publish service auth -->
<label class="fn__flex"> <label class="fn__flex">
<div class="fn__flex-1"> <div class="fn__flex-1">
${window.siyuan.languages.publishServiceAuth} ${window.siyuan.languages.publishServiceAuth}
@ -50,21 +57,34 @@ export const publish = {
<span class="fn__space"></span> <span class="fn__space"></span>
<input class="b3-switch fn__flex-center" id="publishAuthEnable" type="checkbox"${window.siyuan.config.publish.auth.enable ? " checked" : ""}/> <input class="b3-switch fn__flex-center" id="publishAuthEnable" type="checkbox"${window.siyuan.config.publish.auth.enable ? " checked" : ""}/>
</label> </label>
</div>
<!-- publish service auth accounts --> <div class="b3-label">
<div class="b3-label"> ${(()=>{
<div class="fn__flex config__item"> if (mobile) {
<div class="fn__flex-1"> return `
${window.siyuan.languages.publishServiceAuthAccounts} ${window.siyuan.languages.publishServiceAuthAccounts}
<div class="b3-label__text">${window.siyuan.languages.publishServiceAuthAccountsTip}</div> <div class="b3-label__text">${window.siyuan.languages.publishServiceAuthAccountsTip}</div>
</div> <div class="b3-label b3-label--inner fn__flex">
<div class="fn__space"></div> <span class="fn__flex-1"></span>
<button class="b3-button b3-button--outline fn__size200 fn__flex-center" id="publishAuthAccountAdd"> <button class="b3-button b3-button--outline fn__size200 fn__flex-center" id="publishAuthAccountAdd">
<svg><use xlink:href="#iconAdd"></use></svg>${window.siyuan.languages.publishServiceAuthAccountAdd} <svg><use xlink:href="#iconAdd"></use></svg>${window.siyuan.languages.publishServiceAuthAccountAdd}
</button> </button>
</div> </div>`;
<div class="fn__flex" id="publishAuthAccounts"> } else {
</div> return `
<div class="fn__flex">
<div class="fn__flex-1">
${window.siyuan.languages.publishServiceAuthAccounts}
<div class="b3-label__text">${window.siyuan.languages.publishServiceAuthAccountsTip}</div>
</div>
<div class="fn__space"></div>
<button class="b3-button b3-button--outline fn__size200 fn__flex-center" id="publishAuthAccountAdd">
<svg><use xlink:href="#iconAdd"></use></svg>${window.siyuan.languages.publishServiceAuthAccountAdd}
</button>
</div>`;
}
})()}
<div class="fn__flex-1" id="publishAuthAccounts">
</div> </div>
</div> </div>
`; `;
@ -72,7 +92,7 @@ export const publish = {
bindEvent: () => { bindEvent: () => {
const publishAuthAccountAdd = publish.element.querySelector<HTMLButtonElement>("#publishAuthAccountAdd"); const publishAuthAccountAdd = publish.element.querySelector<HTMLButtonElement>("#publishAuthAccountAdd");
/* add account */ // add account
publishAuthAccountAdd.addEventListener("click", () => { publishAuthAccountAdd.addEventListener("click", () => {
window.siyuan.config.publish.auth.accounts.push({ window.siyuan.config.publish.auth.accounts.push({
username: "", username: "",
@ -82,7 +102,7 @@ export const publish = {
publish._renderPublishAuthAccounts(publish.element); publish._renderPublishAuthAccounts(publish.element);
}); });
/* input change */ // input change
publish.element.querySelectorAll("input").forEach(item => { publish.element.querySelectorAll("input").forEach(item => {
item.addEventListener("change", () => { item.addEventListener("change", () => {
publish._savePublish(); publish._savePublish();
@ -126,29 +146,40 @@ export const publish = {
element: Element, element: Element,
accounts: Config.IPublishAuthAccount[] = window.siyuan.config.publish.auth.accounts, accounts: Config.IPublishAuthAccount[] = window.siyuan.config.publish.auth.accounts,
) => { ) => {
const mobile = isMobile();
const publishAuthAccounts = element.querySelector<HTMLDivElement>("#publishAuthAccounts"); const publishAuthAccounts = element.querySelector<HTMLDivElement>("#publishAuthAccounts");
publishAuthAccounts.innerHTML = `<ul class="fn__flex-1" style="margin-top: 16px">${ publishAuthAccounts.innerHTML = `<div class="fn__hr"></div><ul class="fn__flex-1">${
accounts accounts
.map((account, index) => ` .map((account, index) => `
<li class="b3-label--inner fn__flex" data-index="${index}"> <li class="b3-label b3-label--inner fn__flex" data-index="${index}">
<input class="b3-text-field fn__block" data-name="username" value="${account.username}" placeholder="${window.siyuan.languages.userName}"> <input class="b3-text-field fn__block" data-name="username" value="${account.username}" placeholder="${window.siyuan.languages.userName}">
<span class="fn__space"></span> <span class="fn__space"></span>
<div class="b3-form__icona fn__block"> <div class="b3-form__icona fn__block">
<input class="b3-text-field fn__block b3-form__icona-input" type="password" data-name="password" value="${account.password}" placeholder="${window.siyuan.languages.password}"> <input class="b3-text-field fn__block b3-form__icona-input" type="password" data-name="password" value="${account.password}" placeholder="${window.siyuan.languages.password}">
<svg class="b3-form__icona-icon" data-action="togglePassword"><use xlink:href="#iconEye"></use></svg> <svg class="b3-form__icona-icon" data-action="togglePassword"><use xlink:href="#iconEye"></use></svg>
</div> </div>
<span class="fn__space"></span> <span class="fn__space"></span>
<input class="b3-text-field fn__block" data-name="memo" value="${account.memo}" placeholder="${window.siyuan.languages.memo}"> <input class="b3-text-field fn__block" data-name="memo" value="${account.memo}" placeholder="${window.siyuan.languages.memo}">
<span class="fn__space"></span> <span class="fn__space"></span>
<span data-action="remove" class="block__icon block__icon--show"> ${(()=>{
<svg><use xlink:href="#iconTrashcan"></use></svg> if (mobile) {
</span> return `
</li>` <button class="b3-button b3-button--outline fn__block" data-action="remove">
) <svg><use xlink:href="#iconTrashcan"></use></svg>${window.siyuan.languages.delete}
</button>`;
} else {
return `
<span data-action="remove" class="block__icon block__icon--show">
<svg><use xlink:href="#iconTrashcan"></use></svg>
</span>`;
}
})()}
</li>
`)
.join("") .join("")
}</ul>`; }</ul>`;
/* account field changed */ // account field changed
publishAuthAccounts publishAuthAccounts
.querySelectorAll("input") .querySelectorAll("input")
.forEach(input => { .forEach(input => {
@ -165,9 +196,9 @@ export const publish = {
}); });
}); });
/* delete account */ // delete account
publishAuthAccounts publishAuthAccounts
.querySelectorAll('.block__icon[data-action="remove"]') .querySelectorAll('[data-action="remove"]')
.forEach(remove => { .forEach(remove => {
remove.addEventListener("click", () => { remove.addEventListener("click", () => {
const li = hasClosestByTag(remove, "LI"); const li = hasClosestByTag(remove, "LI");
@ -179,7 +210,7 @@ export const publish = {
}); });
}); });
/* Toggle the password display status */ // Toggle the password display status
publishAuthAccounts publishAuthAccounts
.querySelectorAll('.b3-form__icona-icon[data-action="togglePassword"]') .querySelectorAll('.b3-form__icona-icon[data-action="togglePassword"]')
.forEach(togglePassword => { .forEach(togglePassword => {
@ -198,7 +229,7 @@ export const publish = {
if (port === 0) { if (port === 0) {
publishAddresses.innerText = window.siyuan.languages.publishServiceNotStarted; publishAddresses.innerText = window.siyuan.languages.publishServiceNotStarted;
} else { } else {
publishAddresses.innerHTML = `<ul class="b3-list b3-list--background fn__flex-1">${ publishAddresses.innerHTML = `<ul class="b3-list fn__flex-1" style="padding: 2px 0;">${
window.siyuan.config.localIPs window.siyuan.config.localIPs
.filter(ip => !(ip.startsWith("[") && ip.endsWith("]"))) .filter(ip => !(ip.startsWith("[") && ip.endsWith("]")))
.map(ip => `<li><code class="fn__code">${ip}:${port}</code></li>`) .map(ip => `<li><code class="fn__code">${ip}:${port}</code></li>`)

View file

@ -4,6 +4,7 @@ import {initAssets} from "../settings/assets";
import {closePanel} from "../util/closePanel"; import {closePanel} from "../util/closePanel";
import {mountHelp, newDailyNote, newNotebook} from "../../util/mount"; import {mountHelp, newDailyNote, newNotebook} from "../../util/mount";
import {repos} from "../../config/repos"; import {repos} from "../../config/repos";
import {publish} from "../../config/publish";
import {exitSiYuan, lockScreen, processSync} from "../../dialog/processSystem"; import {exitSiYuan, lockScreen, processSync} from "../../dialog/processSystem";
import {openHistory} from "../../history/history"; import {openHistory} from "../../history/history";
import {syncGuide} from "../../sync/syncGuide"; import {syncGuide} from "../../sync/syncGuide";
@ -120,6 +121,9 @@ export const initRightMenu = (app: App) => {
<div id="menuSync" class="b3-menu__item${window.siyuan.config.readonly ? " fn__none" : ""}"> <div id="menuSync" class="b3-menu__item${window.siyuan.config.readonly ? " fn__none" : ""}">
<svg class="b3-menu__icon"><use xlink:href="#iconCloud"></use></svg><span class="b3-menu__label">${window.siyuan.languages.cloud}</span> <svg class="b3-menu__icon"><use xlink:href="#iconCloud"></use></svg><span class="b3-menu__label">${window.siyuan.languages.cloud}</span>
</div> </div>
<div class="b3-menu__item${window.siyuan.config.readonly ? " fn__none" : ""}" id="menuPublish">
<svg class="b3-menu__icon"><use xlink:href="#iconLanguage"></use></svg><span class="b3-menu__label">${window.siyuan.languages.publish}</span>
</div>
<div class="b3-menu__item" id="menuAbout"> <div class="b3-menu__item" id="menuAbout">
<svg class="b3-menu__icon"><use xlink:href="#iconInfo"></use></svg><span class="b3-menu__label">${window.siyuan.languages.about}</span> <svg class="b3-menu__icon"><use xlink:href="#iconInfo"></use></svg><span class="b3-menu__label">${window.siyuan.languages.about}</span>
</div> </div>
@ -259,6 +263,19 @@ export const initRightMenu = (app: App) => {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
break; break;
} else if (target.id === "menuPublish") {
openModel({
title: window.siyuan.languages.publish,
icon: "iconLanguage",
html: publish.genHTML(),
bindEvent(modelMainElement: HTMLElement) {
publish.element = modelMainElement;
publish.bindEvent();
}
});
event.preventDefault();
event.stopPropagation();
break;
} else if (target.id === "menuSyncNow") { } else if (target.id === "menuSyncNow") {
syncGuide(); syncGuide();
event.preventDefault(); event.preventDefault();