mirror of
https://github.com/eondrcode/obsidian-manager.git
synced 2026-07-22 11:40:24 +00:00
pref(UI): 优化移动端UI
This commit is contained in:
parent
1cb87e02ba
commit
a1978d3c1c
9 changed files with 493 additions and 85 deletions
|
|
@ -15,8 +15,9 @@ export default {
|
|||
通用_禁用_文本: 'Disable',
|
||||
通用_关闭_文本: 'Disable',
|
||||
通用_开启_文本: 'Enable',
|
||||
通用_保存_文本: 'Save settings',
|
||||
通用_取消_文本: 'Cancel',
|
||||
通用_保存_文本: 'Save settings',
|
||||
通用_取消_文本: 'Cancel',
|
||||
通用_返回_文本: 'Back',
|
||||
|
||||
导出_正文提示: 'Body section: you can edit or replace this content.',
|
||||
|
||||
|
|
@ -90,13 +91,14 @@ export default {
|
|||
管理器_重载插件_描述: 'Reload plugins to take effect immediately',
|
||||
管理器_重载插件_开始提示: 'Refreshing plugin manifests…',
|
||||
管理器_重载插件_失败提示: 'Reload failed. Please try again (see console for details).',
|
||||
管理器_检查更新_描述: 'Check for plugin updates',
|
||||
管理器_一键禁用_描述: 'Disable all plugins at once',
|
||||
管理器_一键启用_描述: 'Enable all plugins at once',
|
||||
管理器_插件设置_描述: 'Manage plugin settings',
|
||||
管理器_仅启用_描述: 'Only display enabled plugins',
|
||||
管理器_未分组_描述: 'Filter all ungrouped plugins',
|
||||
管理器_打开设置_描述: 'Open the settings interface',
|
||||
管理器_检查更新_描述: 'Check for plugin updates',
|
||||
管理器_更多操作_描述: 'More actions',
|
||||
管理器_一键禁用_描述: 'Disable all plugins at once',
|
||||
管理器_一键启用_描述: 'Enable all plugins at once',
|
||||
管理器_插件设置_描述: 'Manage plugin settings',
|
||||
管理器_仅启用_描述: 'Only display enabled plugins',
|
||||
管理器_未分组_描述: 'Filter all ungrouped plugins',
|
||||
管理器_打开设置_描述: 'Open the settings interface',
|
||||
管理器_还原内容_描述: 'Restore to the initial state',
|
||||
管理器_打开目录_描述: 'Open the plugin directory',
|
||||
管理器_删除插件_描述: 'Completely delete the plugin',
|
||||
|
|
@ -106,6 +108,7 @@ export default {
|
|||
管理器_重启中_提示: 'Restarting… please wait',
|
||||
管理器_仓库检测中_提示: 'Detecting repository…',
|
||||
管理器_打开仓库_提示: 'Open repo: {repo}',
|
||||
管理器_打开仓库_标题: 'Open repository',
|
||||
管理器_仓库未记录_提示: 'Repository not recorded',
|
||||
管理器_仓库需手动添加_提示: 'This plugin is not installed via official/BPM. Please set the source manually.',
|
||||
下载更新_缺少仓库提示: 'Missing repository source; cannot download update.',
|
||||
|
|
|
|||
|
|
@ -11,15 +11,17 @@ export default {
|
|||
通用_无延迟_文本: 'Sin retraso',
|
||||
通用_过滤_文本: 'Filtrar',
|
||||
通用_总计_文本: 'Total',
|
||||
通用_启用_文本: 'Habilitar',
|
||||
通用_禁用_文本: 'Deshabilitar',
|
||||
通用_启用_文本: 'Habilitar',
|
||||
通用_禁用_文本: 'Deshabilitar',
|
||||
通用_返回_文本: 'Volver',
|
||||
|
||||
|
||||
管理器_GITHUB_描述: 'Visite la página de GitHub del autor para ver detalles del proyecto, registros de actualizaciones, participar en discusiones y contribuir con código.',
|
||||
管理器_视频教程_描述: 'Acceder a tutoriales en video',
|
||||
管理器_编辑模式_描述: 'Habilitar modo de edición para una personalización profunda de la configuración del plugin',
|
||||
管理器_重载插件_描述: 'Recargar plugins para que surtan efecto inmediatamente',
|
||||
管理器_检查更新_描述: 'Comprobar actualizaciones de plugins',
|
||||
管理器_检查更新_描述: 'Comprobar actualizaciones de plugins',
|
||||
管理器_更多操作_描述: 'Más acciones',
|
||||
管理器_一键禁用_描述: 'Deshabilitar todos los plugins a la vez',
|
||||
管理器_一键启用_描述: 'Habilitar todos los plugins a la vez',
|
||||
管理器_插件设置_描述: 'Administrar configuración de plugins',
|
||||
|
|
@ -64,6 +66,7 @@ export default {
|
|||
管理器_重启中_提示: 'Reiniciando… espera un momento',
|
||||
管理器_仓库检测中_提示: 'Detectando repositorio…',
|
||||
管理器_打开仓库_提示: 'Abrir repo: {repo}',
|
||||
管理器_打开仓库_标题: 'Abrir repositorio',
|
||||
管理器_仓库未记录_提示: 'Repositorio no registrado',
|
||||
管理器_仓库需手动添加_提示: 'Este plugin no es oficial/instalado por BPM. Añade el origen manualmente.',
|
||||
下载更新_缺少仓库提示: 'Falta el repositorio; no se puede descargar la actualización.',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export default {
|
|||
通用_开启_文本: 'Ouvrir',
|
||||
通用_保存_文本: 'Enregistrer',
|
||||
通用_取消_文本: 'Annuler',
|
||||
通用_返回_文本: 'Retour',
|
||||
|
||||
导出_正文提示: 'Section corps : vous pouvez modifier ou remplacer ce contenu.',
|
||||
|
||||
|
|
@ -196,4 +197,6 @@ export default {
|
|||
安装_错误_通用: 'Échec de l’installation. Vérifiez dépôt/version ou réseau.',
|
||||
设置_基础设置_调试模式_标题: 'Mode debug',
|
||||
设置_基础设置_调试模式_描述: 'Désactivé : erreurs uniquement. Activé : logs de debug.',
|
||||
管理器_更多操作_描述: 'Plus d’actions',
|
||||
管理器_打开仓库_标题: 'Ouvrir le dépôt',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ export default {
|
|||
通用_过滤_文本: 'フィルター',
|
||||
通用_总计_文本: '合計',
|
||||
通用_启用_文本: '有効',
|
||||
通用_禁用_文本: '無効',
|
||||
通用_禁用_文本: '無効',
|
||||
通用_返回_文本: '戻る',
|
||||
|
||||
|
||||
管理器_GITHUB_描述: '著者のGitHubページを訪れ、プロジェクトの詳細、更新ログ、議論への参加、コードへの貢献を確認してください。',
|
||||
|
|
@ -125,6 +126,8 @@ export default {
|
|||
筛选_分组_全部: 'グループ:全部',
|
||||
筛选_标签_全部: 'タグ:全部',
|
||||
筛选_延迟_全部: '遅延:全部',
|
||||
|
||||
命令_管理面板_描述: 'プラグインマネージャーを開く',
|
||||
}
|
||||
|
||||
命令_管理面板_描述: 'プラグインマネージャーを開く',
|
||||
管理器_更多操作_描述: 'その他の操作',
|
||||
管理器_打开仓库_标题: 'リポジトリを開く',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
export default {
|
||||
export default {
|
||||
通用_管理器_文本: '플러그인 관리자',
|
||||
通用_成功_文本: '성공',
|
||||
通用_失败_文本: '실패',
|
||||
|
|
@ -12,7 +12,8 @@ export default {
|
|||
通用_过滤_文本: '필터',
|
||||
通用_总计_文本: '총계',
|
||||
通用_启用_文本: '활성화',
|
||||
通用_禁用_文本: '비활성화',
|
||||
通用_禁用_文本: '비활성화',
|
||||
通用_返回_文本: '뒤로',
|
||||
|
||||
|
||||
管理器_GITHUB_描述: '저자의 GitHub 페이지를 방문하여 프로젝트 세부 정보, 업데이트 로그, 토론 참여, 코드 기여를 확인하세요.',
|
||||
|
|
@ -125,4 +126,6 @@ export default {
|
|||
管理器_仓库未记录_提示: '저장소가 기록되지 않았습니다',
|
||||
管理器_仓库需手动添加_提示: '이 플러그인은 공식/BPM 설치가 아닙니다. 소스를 수동으로 설정하세요.',
|
||||
下载更新_缺少仓库提示: '저장소 정보가 없어 업데이트를 다운로드할 수 없습니다.',
|
||||
管理器_更多操作_描述: '더 많은 작업',
|
||||
管理器_打开仓库_标题: '저장소 열기',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ export default {
|
|||
通用_开启_文本: 'Открыть',
|
||||
通用_保存_文本: 'Сохранить',
|
||||
通用_取消_文本: 'Отмена',
|
||||
通用_返回_文本: 'Назад',
|
||||
|
||||
导出_正文提示: 'Основной текст: вы можете изменить или заменить этот контент.',
|
||||
|
||||
|
|
@ -195,4 +196,6 @@ export default {
|
|||
管理器_仓库未记录_提示: 'Репозиторий не указан',
|
||||
管理器_仓库需手动添加_提示: 'Плагин не из официального/BPM источника. Укажите источник вручную.',
|
||||
下载更新_缺少仓库提示: 'Нет источника репозитория — невозможно скачать обновление.',
|
||||
管理器_更多操作_描述: 'Дополнительные действия',
|
||||
管理器_打开仓库_标题: 'Открыть репозиторий',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ export default {
|
|||
通用_禁用_文本: '禁用',
|
||||
通用_关闭_文本: '关闭',
|
||||
通用_开启_文本: '开启',
|
||||
通用_保存_文本: '保存设置',
|
||||
通用_取消_文本: '取消',
|
||||
通用_保存_文本: '保存设置',
|
||||
通用_取消_文本: '取消',
|
||||
通用_返回_文本: '返回',
|
||||
|
||||
导出_正文提示: '正文区:这里的内容可自行编辑或替换。',
|
||||
|
||||
|
|
@ -32,12 +33,13 @@ export default {
|
|||
管理器_重载插件_描述: '重载插件,即时生效',
|
||||
管理器_重载插件_开始提示: '正在重新读取插件清单…',
|
||||
管理器_重载插件_失败提示: '重载失败,请稍后重试(详情见控制台)。',
|
||||
管理器_检查更新_描述: '检查插件更新',
|
||||
管理器_一键禁用_描述: '一键禁用所有插件',
|
||||
管理器_一键启用_描述: '一键启用所有插件',
|
||||
管理器_插件设置_描述: '管理插件设置',
|
||||
管理器_仅启用_描述: '仅显示已启用插件',
|
||||
管理器_未分组_描述: '筛选所有未分组插件',
|
||||
管理器_检查更新_描述: '检查插件更新',
|
||||
管理器_更多操作_描述: '更多操作',
|
||||
管理器_一键禁用_描述: '一键禁用所有插件',
|
||||
管理器_一键启用_描述: '一键启用所有插件',
|
||||
管理器_插件设置_描述: '管理插件设置',
|
||||
管理器_仅启用_描述: '仅显示已启用插件',
|
||||
管理器_未分组_描述: '筛选所有未分组插件',
|
||||
管理器_打开设置_描述: '打开设置界面',
|
||||
管理器_还原内容_描述: '还原初始状态',
|
||||
管理器_打开目录_描述: '打开插件目录',
|
||||
|
|
@ -48,6 +50,7 @@ export default {
|
|||
管理器_重启中_提示: '重启中,请稍等',
|
||||
管理器_仓库检测中_提示: '正在检测仓库地址...',
|
||||
管理器_打开仓库_提示: '打开仓库:{repo}',
|
||||
管理器_打开仓库_标题: '打开仓库',
|
||||
管理器_仓库未记录_提示: '未记录仓库地址',
|
||||
管理器_仓库需手动添加_提示: '本插件非官方/bpm安装,请手动添加来源',
|
||||
下载更新_缺少仓库提示: '缺少仓库来源,无法下载更新',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export class ManagerModal extends Modal {
|
|||
actionCollapsed = false;
|
||||
filterCollapsed = false;
|
||||
private reloadingManifests = false;
|
||||
private mobileFiltersCollapsed = true;
|
||||
|
||||
private showInlineProgress(text: string, subText?: string) {
|
||||
const notice = new Notice("", 0);
|
||||
|
|
@ -184,12 +185,12 @@ export class ManagerModal extends Modal {
|
|||
return plugins;
|
||||
}
|
||||
|
||||
public async showHead() {
|
||||
//@ts-ignore
|
||||
const modalEl: HTMLElement = this.contentEl.parentElement;
|
||||
this.modalContainer = modalEl;
|
||||
modalEl.addClass("manager-container");
|
||||
if (Platform.isMobileApp) modalEl.addClass("manager-container--mobile");
|
||||
public async showHead() {
|
||||
//@ts-ignore
|
||||
const modalEl: HTMLElement = this.contentEl.parentElement;
|
||||
this.modalContainer = modalEl;
|
||||
modalEl.addClass("manager-container");
|
||||
if (Platform.isMobileApp) modalEl.addClass("manager-container--mobile");
|
||||
// 靠上
|
||||
if (!this.settings.CENTER && !Platform.isMobileApp) modalEl.addClass("manager-container__top");
|
||||
if (this.editorMode) modalEl.addClass("manager-container--editing");
|
||||
|
|
@ -200,10 +201,15 @@ export class ManagerModal extends Modal {
|
|||
// 添加页尾
|
||||
this.footEl = document.createElement("div");
|
||||
this.footEl.addClass("manager-food");
|
||||
this.modalEl.appendChild(this.footEl);
|
||||
|
||||
// [操作行]
|
||||
const actionWrapper = this.titleEl.createDiv("manager-section manager-section--row");
|
||||
this.modalEl.appendChild(this.footEl);
|
||||
|
||||
if (Platform.isMobileApp) {
|
||||
this.showHeadMobile();
|
||||
return;
|
||||
}
|
||||
|
||||
// [操作行]
|
||||
const actionWrapper = this.titleEl.createDiv("manager-section manager-section--row");
|
||||
const actionHeader = actionWrapper.createDiv("manager-section__header");
|
||||
const actionArrow = actionHeader.createSpan({ text: this.actionCollapsed ? "▼" : "▲" });
|
||||
actionArrow.addClass("manager-section__arrow");
|
||||
|
|
@ -414,7 +420,7 @@ export class ManagerModal extends Modal {
|
|||
});
|
||||
|
||||
// [操作行] 插件设置
|
||||
const settingsButton = new ButtonComponent(actionBar.controlEl);
|
||||
const settingsButton = new ButtonComponent(actionBar.controlEl);
|
||||
settingsButton.setIcon("settings");
|
||||
settingsButton.setTooltip(this.manager.translator.t("管理器_插件设置_描述"));
|
||||
this.bindLongPressTooltip(settingsButton.buttonEl, this.manager.translator.t("管理器_插件设置_描述"));
|
||||
|
|
@ -568,8 +574,182 @@ export class ManagerModal extends Modal {
|
|||
this.reloadShowData();
|
||||
});
|
||||
}
|
||||
|
||||
private showHeadMobile() {
|
||||
const t = (k: any) => this.manager.translator.t(k);
|
||||
this.titleEl.empty();
|
||||
|
||||
const header = this.titleEl.createDiv("bpm-mobile-header");
|
||||
const topRow = header.createDiv("bpm-mobile-header__top");
|
||||
const title = topRow.createDiv("bpm-mobile-header__title");
|
||||
title.setText(this.manager.manifest.name);
|
||||
|
||||
const topActions = topRow.createDiv("bpm-mobile-header__actions");
|
||||
|
||||
// 编辑模式(常驻)
|
||||
const editorBtn = new ButtonComponent(topActions);
|
||||
editorBtn.setIcon(this.editorMode ? "pen-off" : "pen");
|
||||
editorBtn.setTooltip(t("管理器_编辑模式_描述"));
|
||||
this.bindLongPressTooltip(editorBtn.buttonEl, t("管理器_编辑模式_描述"));
|
||||
editorBtn.onClick(async () => {
|
||||
this.editorMode = !this.editorMode;
|
||||
this.applyEditingStyle();
|
||||
// 退出编辑模式需要刷新筛选项统计,但要保留滚动位置
|
||||
if (!this.editorMode) {
|
||||
await this.refreshFilterOptions(true);
|
||||
} else {
|
||||
this.renderContent();
|
||||
}
|
||||
this.showHeadMobile();
|
||||
});
|
||||
|
||||
// 安装/返回(切换安装模式)
|
||||
const installBtn = new ButtonComponent(topActions);
|
||||
installBtn.setIcon(this.installMode ? "arrow-left" : "download");
|
||||
installBtn.setTooltip(this.installMode ? t("通用_返回_文本") : t("管理器_安装_GITHUB_描述"));
|
||||
this.bindLongPressTooltip(installBtn.buttonEl, this.installMode ? t("通用_返回_文本") : t("管理器_安装_GITHUB_描述"));
|
||||
installBtn.onClick(() => {
|
||||
this.installMode = !this.installMode;
|
||||
if (this.searchBarEl) {
|
||||
this.installMode ? this.searchBarEl.addClass("manager-display-none") : this.searchBarEl.removeClass("manager-display-none");
|
||||
}
|
||||
this.renderContent();
|
||||
this.showHeadMobile();
|
||||
});
|
||||
|
||||
// 更多操作菜单
|
||||
const moreBtn = new ButtonComponent(topActions);
|
||||
moreBtn.setIcon("more-vertical");
|
||||
moreBtn.setTooltip(t("管理器_更多操作_描述"));
|
||||
this.bindLongPressTooltip(moreBtn.buttonEl, t("管理器_更多操作_描述"));
|
||||
moreBtn.buttonEl.addEventListener("click", (ev) => {
|
||||
const menu = new Menu();
|
||||
menu.addItem((item) => item.setTitle(t("管理器_检查更新_描述")).setIcon("rss").onClick(async () => {
|
||||
await this.manager.checkUpdatesWithNotice();
|
||||
await this.reloadShowData();
|
||||
}));
|
||||
menu.addItem((item) => item.setTitle(t("管理器_重载插件_描述")).setIcon("refresh-ccw").onClick(async () => {
|
||||
await this.appPlugins.loadManifests();
|
||||
await this.reloadShowData();
|
||||
}));
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => item.setTitle(t("管理器_插件设置_描述")).setIcon("settings").onClick(() => {
|
||||
this.appSetting.open();
|
||||
this.appSetting.openTabById(this.manager.manifest.id);
|
||||
}));
|
||||
menu.addItem((item) => item.setTitle(t("管理器_GITHUB_描述")).setIcon("github").onClick(() => {
|
||||
window.open("https://github.com/zenozero-dev/obsidian-manager");
|
||||
}));
|
||||
menu.addItem((item) => item.setTitle(t("管理器_视频教程_描述")).setIcon("book-open").onClick(() => {
|
||||
window.open("https://www.bilibili.com/video/BV1WyrkYMEce/");
|
||||
}));
|
||||
menu.showAtMouseEvent(ev as MouseEvent);
|
||||
});
|
||||
|
||||
const searchWrap = header.createDiv("bpm-mobile-header__search");
|
||||
this.searchEl = new SearchComponent(searchWrap);
|
||||
if (this.settings.PERSISTENCE && typeof this.settings.FILTER_SEARCH === "string") {
|
||||
this.searchText = this.settings.FILTER_SEARCH;
|
||||
this.searchEl.inputEl.value = this.searchText;
|
||||
}
|
||||
this.searchEl.onChange((value: string) => {
|
||||
this.searchText = value;
|
||||
if (this.settings.PERSISTENCE) {
|
||||
this.settings.FILTER_SEARCH = value;
|
||||
this.manager.saveSettings();
|
||||
}
|
||||
this.reloadShowData();
|
||||
});
|
||||
|
||||
const filterHeader = header.createDiv("bpm-mobile-header__filters-toggle");
|
||||
const arrow = filterHeader.createSpan({ cls: "bpm-mobile-header__filters-arrow" });
|
||||
arrow.setText(this.mobileFiltersCollapsed ? "▼" : "▲");
|
||||
filterHeader.createSpan({ text: t("通用_过滤_文本") });
|
||||
filterHeader.toggleClass("is-open", !this.mobileFiltersCollapsed);
|
||||
filterHeader.addEventListener("click", () => {
|
||||
this.mobileFiltersCollapsed = !this.mobileFiltersCollapsed;
|
||||
filterPanel.toggleClass("is-collapsed", this.mobileFiltersCollapsed);
|
||||
filterHeader.toggleClass("is-open", !this.mobileFiltersCollapsed);
|
||||
arrow.setText(this.mobileFiltersCollapsed ? "▼" : "▲");
|
||||
});
|
||||
|
||||
const filterPanel = header.createDiv(`bpm-mobile-header__filters${this.mobileFiltersCollapsed ? " is-collapsed" : ""}`);
|
||||
|
||||
// 状态
|
||||
const statusSetting = new Setting(filterPanel).setName(t("筛选_状态_全部"));
|
||||
statusSetting.addDropdown((dd) => {
|
||||
dd.addOptions({
|
||||
"all": t("筛选_状态_全部"),
|
||||
"enabled": t("筛选_仅启用_描述"),
|
||||
"disabled": t("筛选_仅禁用_描述"),
|
||||
"grouped": t("筛选_已分组_描述"),
|
||||
"ungrouped": t("筛选_未分组_描述"),
|
||||
"tagged": t("筛选_有标签_描述"),
|
||||
"untagged": t("筛选_无标签_描述"),
|
||||
"noted": t("筛选_有笔记_描述"),
|
||||
});
|
||||
dd.setValue(this.filter || "all");
|
||||
dd.onChange((v) => { this.filter = v; this.reloadShowData(); });
|
||||
});
|
||||
|
||||
// 分组
|
||||
const groupCounts = this.settings.Plugins.reduce((acc: { [key: string]: number }, plugin) => { const groupId = plugin.group || ""; acc[groupId] = (acc[groupId] || 0) + 1; return acc; }, { "": 0 });
|
||||
const groups = this.settings.GROUPS.reduce((acc: { [key: string]: string }, item) => { acc[item.id] = `${item.name} [${groupCounts[item.id] || 0}]`; return acc; }, { "": t("筛选_分组_全部") });
|
||||
const groupSetting = new Setting(filterPanel).setName(t("筛选_分组_全部"));
|
||||
groupSetting.addDropdown((dd) => {
|
||||
dd.addOptions(groups);
|
||||
dd.setValue(this.settings.PERSISTENCE ? this.settings.FILTER_GROUP : this.group);
|
||||
dd.onChange((value) => {
|
||||
if (this.settings.PERSISTENCE) {
|
||||
this.settings.FILTER_GROUP = value;
|
||||
this.manager.saveSettings();
|
||||
} else {
|
||||
this.group = value;
|
||||
}
|
||||
this.reloadShowData();
|
||||
});
|
||||
});
|
||||
|
||||
// 标签
|
||||
const tagCounts: { [key: string]: number } = this.settings.Plugins.reduce((acc, plugin) => { plugin.tags.forEach((tag) => { acc[tag] = (acc[tag] || 0) + 1; }); return acc; }, {} as { [key: string]: number });
|
||||
const tags = this.settings.TAGS.reduce((acc: { [key: string]: string }, item) => { acc[item.id] = `${item.name} [${tagCounts[item.id] || 0}]`; return acc; }, { "": t("筛选_标签_全部") });
|
||||
const tagSetting = new Setting(filterPanel).setName(t("筛选_标签_全部"));
|
||||
tagSetting.addDropdown((dd) => {
|
||||
dd.addOptions(tags);
|
||||
dd.setValue(this.settings.PERSISTENCE ? this.settings.FILTER_TAG : this.tag);
|
||||
dd.onChange((value) => {
|
||||
if (this.settings.PERSISTENCE) {
|
||||
this.settings.FILTER_TAG = value;
|
||||
this.manager.saveSettings();
|
||||
} else {
|
||||
this.tag = value;
|
||||
}
|
||||
this.reloadShowData();
|
||||
});
|
||||
});
|
||||
|
||||
// 延迟
|
||||
if (this.settings.DELAY) {
|
||||
const delayCounts = this.settings.Plugins.reduce((acc: { [key: string]: number }, plugin) => { const delay = plugin.delay || ""; acc[delay] = (acc[delay] || 0) + 1; return acc; }, { "": 0 });
|
||||
const delays = this.settings.DELAYS.reduce((acc: { [key: string]: string }, item) => { acc[item.id] = `${item.name} (${delayCounts[item.id] || 0})`; return acc; }, { "": t("筛选_延迟_全部") });
|
||||
const delaySetting = new Setting(filterPanel).setName(t("筛选_延迟_全部"));
|
||||
delaySetting.addDropdown((dd) => {
|
||||
dd.addOptions(delays);
|
||||
dd.setValue(this.settings.PERSISTENCE ? this.settings.FILTER_DELAY : this.delay);
|
||||
dd.onChange((value) => {
|
||||
if (this.settings.PERSISTENCE) {
|
||||
this.settings.FILTER_DELAY = value;
|
||||
this.manager.saveSettings();
|
||||
} else {
|
||||
this.delay = value;
|
||||
}
|
||||
this.reloadShowData();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async showData() {
|
||||
public async showData() {
|
||||
// 使用 manifests 按 id 去重,防止重复渲染
|
||||
const manifestMap = this.appPlugins.manifests;
|
||||
if (this.settings.DEBUG) console.log("[BPM] render showData manifests size:", Object.keys(manifestMap).length);
|
||||
|
|
@ -922,20 +1102,20 @@ export class ManagerModal extends Modal {
|
|||
const arrow = createSpan({ text: "→", cls: ["manager-item__name-remote-arrow"] });
|
||||
versionWrap.appendChild(arrow);
|
||||
const remote = createSpan({ text: `${updateInfo.remoteVersion}`, cls: ["manager-item__name-remote"] });
|
||||
versionWrap.appendChild(remote);
|
||||
if (!this.editorMode) {
|
||||
const downloadBtn = new ExtraButtonComponent(itemEl.controlEl);
|
||||
downloadBtn.setIcon("download");
|
||||
downloadBtn.setTooltip(this.manager.translator.t("管理器_下载更新_描述"));
|
||||
downloadBtn.onClick(() => {
|
||||
const versions = updateInfo.versions && updateInfo.versions.length > 0
|
||||
? updateInfo.versions
|
||||
: [{ version: updateInfo.remoteVersion!, prerelease: false }];
|
||||
new UpdateModal(this.app, this.manager, plugin.id, versions, updateInfo.remoteVersion, updateInfo.repo || undefined).open();
|
||||
});
|
||||
}
|
||||
}
|
||||
itemEl.nameEl.appendChild(versionWrap);
|
||||
versionWrap.appendChild(remote);
|
||||
if (!this.editorMode && !Platform.isMobileApp) {
|
||||
const downloadBtn = new ExtraButtonComponent(itemEl.controlEl);
|
||||
downloadBtn.setIcon("download");
|
||||
downloadBtn.setTooltip(this.manager.translator.t("管理器_下载更新_描述"));
|
||||
downloadBtn.onClick(() => {
|
||||
const versions = updateInfo.versions && updateInfo.versions.length > 0
|
||||
? updateInfo.versions
|
||||
: [{ version: updateInfo.remoteVersion!, prerelease: false }];
|
||||
new UpdateModal(this.app, this.manager, plugin.id, versions, updateInfo.remoteVersion, updateInfo.repo || undefined).open();
|
||||
});
|
||||
}
|
||||
}
|
||||
itemEl.nameEl.appendChild(versionWrap);
|
||||
|
||||
// [默认] 笔记图标
|
||||
if (ManagerPlugin.note?.length > 0) {
|
||||
|
|
@ -993,8 +1173,89 @@ export class ManagerModal extends Modal {
|
|||
tags.appendChild(tag);
|
||||
}
|
||||
|
||||
if (!this.editorMode) {
|
||||
// [按钮] 打开仓库
|
||||
if (!this.editorMode) {
|
||||
const isMobile = Platform.isMobileApp;
|
||||
|
||||
let openPluginSetting: ExtraButtonComponent | null = null;
|
||||
let openPluginSettingEl: HTMLElement | undefined;
|
||||
|
||||
if (isMobile) {
|
||||
const moreButton = new ExtraButtonComponent(itemEl.controlEl);
|
||||
moreButton.setIcon("more-vertical");
|
||||
moreButton.setTooltip(this.manager.translator.t("管理器_更多操作_描述"));
|
||||
const moreEl = ((moreButton as any).extraSettingsEl || (moreButton as any).buttonEl) as HTMLElement | undefined;
|
||||
this.bindLongPressTooltip(moreEl, this.manager.translator.t("管理器_更多操作_描述"));
|
||||
moreEl?.addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
const menu = new Menu();
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_检查更新_描述"))
|
||||
.setIcon("rss")
|
||||
.onClick(async () => {
|
||||
await this.manager.checkUpdateForPlugin(plugin.id);
|
||||
await this.reloadShowData();
|
||||
}));
|
||||
if (updateInfo?.hasUpdate && updateInfo.remoteVersion) {
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_下载更新_描述"))
|
||||
.setIcon("download")
|
||||
.onClick(() => {
|
||||
const versions = updateInfo.versions && updateInfo.versions.length > 0
|
||||
? updateInfo.versions
|
||||
: [{ version: updateInfo.remoteVersion!, prerelease: false }];
|
||||
new UpdateModal(this.app, this.manager, plugin.id, versions, updateInfo.remoteVersion, updateInfo.repo || undefined).open();
|
||||
}));
|
||||
}
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_打开设置_描述"))
|
||||
.setIcon("settings")
|
||||
.setDisabled(!isEnabled)
|
||||
.onClick(() => {
|
||||
this.appSetting.open();
|
||||
this.appSetting.openTabById(plugin.id);
|
||||
}));
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_打开目录_描述"))
|
||||
.setIcon("folder-open")
|
||||
.onClick(() => {
|
||||
managerOpen(pluginDir, this.manager);
|
||||
}));
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_打开仓库_标题"))
|
||||
.setIcon("github")
|
||||
.onClick(async () => {
|
||||
const repo = await this.manager.repoResolver.resolveRepo(plugin.id);
|
||||
if (repo) {
|
||||
window.open(`https://github.com/${repo}`);
|
||||
} else {
|
||||
const isBpmInstall = this.manager.settings.BPM_INSTALLED.includes(plugin.id);
|
||||
new Notice(isBpmInstall
|
||||
? this.manager.translator.t("管理器_仓库未记录_提示")
|
||||
: this.manager.translator.t("管理器_仓库需手动添加_提示"));
|
||||
}
|
||||
}));
|
||||
menu.addSeparator();
|
||||
menu.addItem((item) => item
|
||||
.setTitle(this.manager.translator.t("管理器_删除插件_描述"))
|
||||
.setIcon("trash")
|
||||
.setDisabled(isSelf)
|
||||
.onClick(async () => {
|
||||
if (isSelf) return;
|
||||
new DeleteModal(this.app, this.manager, async () => {
|
||||
await this.appPlugins.uninstallPlugin(plugin.id);
|
||||
await this.appPlugins.loadManifests();
|
||||
this.reloadShowData();
|
||||
Commands(this.app, this.manager);
|
||||
this.manager.synchronizePlugins(Object.values(this.appPlugins.manifests).filter((pm: PluginManifest) => pm.id !== this.manager.manifest.id) as PluginManifest[]);
|
||||
new Notice(this.manager.translator.t("卸载_通知_一"));
|
||||
}).open();
|
||||
}));
|
||||
menu.showAtMouseEvent(event as MouseEvent);
|
||||
});
|
||||
} else {
|
||||
// [按钮] 打开仓库
|
||||
const openRepoButton = new ExtraButtonComponent(itemEl.controlEl);
|
||||
openRepoButton.setIcon("github");
|
||||
openRepoButton.setTooltip(this.manager.translator.t("管理器_仓库检测中_提示"));
|
||||
|
|
@ -1012,23 +1273,23 @@ export class ManagerModal extends Modal {
|
|||
}
|
||||
|
||||
// [按钮] 打开设置
|
||||
const openPluginSetting = new ExtraButtonComponent(itemEl.controlEl);
|
||||
openPluginSetting = new ExtraButtonComponent(itemEl.controlEl);
|
||||
openPluginSetting.setIcon("settings");
|
||||
openPluginSetting.setTooltip(this.manager.translator.t("管理器_打开设置_描述"));
|
||||
openPluginSetting.onClick(() => {
|
||||
openPluginSetting.setDisabled(true);
|
||||
openPluginSetting?.setDisabled(true);
|
||||
this.appSetting.open();
|
||||
this.appSetting.openTabById(plugin.id);
|
||||
openPluginSetting.setDisabled(false);
|
||||
openPluginSetting?.setDisabled(false);
|
||||
});
|
||||
const openPluginSettingEl = ((openPluginSetting as any).extraSettingsEl || (openPluginSetting as any).buttonEl) as HTMLElement | undefined;
|
||||
openPluginSettingEl = ((openPluginSetting as any).extraSettingsEl || (openPluginSetting as any).buttonEl) as HTMLElement | undefined;
|
||||
if (!isEnabled) {
|
||||
openPluginSetting.setDisabled(true);
|
||||
if (openPluginSettingEl) openPluginSettingEl.style.display = "none";
|
||||
}
|
||||
|
||||
// [按钮] 打开目录
|
||||
const openPluginDirButton = new ExtraButtonComponent(itemEl.controlEl);
|
||||
|
||||
// [按钮] 打开目录
|
||||
const openPluginDirButton = new ExtraButtonComponent(itemEl.controlEl);
|
||||
openPluginDirButton.setIcon("folder-open");
|
||||
openPluginDirButton.setTooltip(this.manager.translator.t("管理器_打开目录_描述"));
|
||||
openPluginDirButton.onClick(() => {
|
||||
|
|
@ -1052,10 +1313,11 @@ export class ManagerModal extends Modal {
|
|||
Commands(this.app, this.manager);
|
||||
// 删除同理
|
||||
this.manager.synchronizePlugins(Object.values(this.appPlugins.manifests).filter((pm: PluginManifest) => pm.id !== this.manager.manifest.id) as PluginManifest[]);
|
||||
new Notice(this.manager.translator.t("卸载_通知_一"));
|
||||
}).open();
|
||||
});
|
||||
|
||||
new Notice(this.manager.translator.t("卸载_通知_一"));
|
||||
}).open();
|
||||
});
|
||||
}
|
||||
|
||||
// [按钮] 切换状态
|
||||
const toggleSwitch = new ToggleComponent(itemEl.controlEl);
|
||||
toggleSwitch.setTooltip(this.manager.translator.t("管理器_切换状态_描述"));
|
||||
|
|
@ -1073,8 +1335,10 @@ export class ManagerModal extends Modal {
|
|||
itemEl.settingEl.toggleClass("inactive", !targetEnabled);
|
||||
}
|
||||
// 同步“打开设置”按钮(启用后出现,禁用后隐藏)
|
||||
openPluginSetting.setDisabled(!targetEnabled);
|
||||
if (openPluginSettingEl) openPluginSettingEl.style.display = targetEnabled ? "" : "none";
|
||||
if (openPluginSetting) {
|
||||
openPluginSetting.setDisabled(!targetEnabled);
|
||||
if (openPluginSettingEl) openPluginSettingEl.style.display = targetEnabled ? "" : "none";
|
||||
}
|
||||
// 按需从当前视图移除,避免全量重绘
|
||||
if (removeByFilter) {
|
||||
itemEl.settingEl.detach();
|
||||
|
|
|
|||
159
styles.css
159
styles.css
|
|
@ -217,20 +217,40 @@ body.theme-dark {
|
|||
gap: 6px;
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: clamp(10px, 2vw, 14px);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 12px;
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item__name-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.manager-container--mobile .manager-item {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
padding: clamp(10px, 2vw, 14px);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 12px;
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item__controls.setting-item-control {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item__controls .clickable-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 12px;
|
||||
background: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item__name-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.manager-container--mobile .manager-item__description-container {
|
||||
|
|
@ -390,7 +410,7 @@ body.theme-dark {
|
|||
}
|
||||
}
|
||||
|
||||
@media (min-width: 600px) and (orientation: landscape) {
|
||||
@media (min-width: 600px) and (orientation: landscape) {
|
||||
.manager-container--mobile {
|
||||
top: calc(3vh + env(safe-area-inset-top, 0px));
|
||||
height: calc(100vh - 6vh - env(safe-area-inset-top, 0px));
|
||||
|
|
@ -406,9 +426,112 @@ body.theme-dark {
|
|||
.manager-container--mobile .manager-item-container {
|
||||
max-height: calc(100vh - 200px);
|
||||
}
|
||||
}
|
||||
|
||||
/* 目录容器 */
|
||||
}
|
||||
|
||||
/* mobile header (separate UI) */
|
||||
.manager-container--mobile .bpm-mobile-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 10px 12px 8px;
|
||||
margin: 0 8px 10px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 12px;
|
||||
background: var(--background-secondary);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__title {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-normal);
|
||||
line-height: 1.2;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__actions {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__actions button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
border-radius: 12px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__actions button svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__search .search-input-container,
|
||||
.manager-container--mobile .bpm-mobile-header__search .search-input-container input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 12px;
|
||||
background: var(--background-primary);
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters-toggle.is-open {
|
||||
border-color: color-mix(in srgb, var(--text-accent) 55%, var(--background-modifier-border));
|
||||
background: var(--background-secondary-alt);
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters-arrow {
|
||||
font-size: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters {
|
||||
padding: 8px 10px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 12px;
|
||||
background: var(--background-primary);
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters.is-collapsed {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .setting-item {
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.manager-container--mobile .bpm-mobile-header__filters .setting-item + .setting-item {
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
/* 目录容器 */
|
||||
.manager-item-container {
|
||||
overflow: auto;
|
||||
padding: 8px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue