mirror of
https://github.com/sean2077/obsidian-dynamic-theme-background.git
synced 2026-07-22 06:44:57 +00:00
fix: resolve all Required issues from official plugin review (PR #7359)
This commit is contained in:
parent
2ed4e7ebd0
commit
fd83d70519
21 changed files with 310 additions and 133 deletions
48
.gitignore
vendored
48
.gitignore
vendored
|
|
@ -1,22 +1,26 @@
|
|||
# vscode
|
||||
.vscode
|
||||
|
||||
# Intellij
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# npm
|
||||
node_modules
|
||||
|
||||
# Don't include the compiled main.js file in the repo.
|
||||
# They should be uploaded to GitHub releases instead.
|
||||
main.js
|
||||
|
||||
# Exclude sourcemaps
|
||||
*.map
|
||||
|
||||
# obsidian
|
||||
data.json
|
||||
|
||||
# Exclude macOS Finder (System Explorer) View States
|
||||
.DS_Store
|
||||
# AI tools
|
||||
.serena
|
||||
.claude
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
|
||||
# Intellij
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# npm
|
||||
node_modules
|
||||
|
||||
# Don't include the compiled main.js file in the repo.
|
||||
# They should be uploaded to GitHub releases instead.
|
||||
main.js
|
||||
|
||||
# Exclude sourcemaps
|
||||
*.map
|
||||
|
||||
# obsidian
|
||||
data.json
|
||||
|
||||
# Exclude macOS Finder (System Explorer) View States
|
||||
.DS_Store
|
||||
|
|
|
|||
97
.internal/issues.md
Normal file
97
.internal/issues.md
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +1,12 @@
|
|||
// eslint.config.js
|
||||
import obsidianmd from "eslint-plugin-obsidianmd";
|
||||
import tsParser from "@typescript-eslint/parser";
|
||||
import tseslint from "typescript-eslint";
|
||||
import obsidianmd from "eslint-plugin-obsidianmd";
|
||||
|
||||
export default [
|
||||
// TypeScript-ESLint 推荐规则(不含严格类型检查)
|
||||
...tseslint.configs.recommended,
|
||||
|
||||
{
|
||||
files: ["**/*.ts"],
|
||||
languageOptions: {
|
||||
|
|
@ -15,11 +19,21 @@ export default [
|
|||
obsidianmd,
|
||||
},
|
||||
rules: {
|
||||
// The recommended rules from eslint-plugin-obsidianmd
|
||||
// 使用 obsidianmd 官方推荐规则
|
||||
...obsidianmd.configs.recommended,
|
||||
|
||||
// Override: 降低 UI sentence case 的严格程度,因为表情符号会导致误报
|
||||
// 官方审查要求的关键规则
|
||||
"@typescript-eslint/no-floating-promises": "error",
|
||||
"@typescript-eslint/await-thenable": "error",
|
||||
"@typescript-eslint/require-await": "error",
|
||||
"@typescript-eslint/no-misused-promises": "error",
|
||||
|
||||
// 项目特定覆盖
|
||||
"obsidianmd/ui/sentence-case": ["warn", { enforceCamelCaseLower: false }],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{ argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
|||
32
package-lock.json
generated
32
package-lock.json
generated
|
|
@ -12,23 +12,23 @@
|
|||
"jsonpath-plus": "^10.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "*",
|
||||
"@typescript-eslint/eslint-plugin": "*",
|
||||
"@typescript-eslint/parser": "*",
|
||||
"all-contributors-cli": "*",
|
||||
"builtin-modules": "*",
|
||||
"esbuild": "*",
|
||||
"eslint": "*",
|
||||
"eslint-plugin-obsidianmd": "*",
|
||||
"obsidian": "*",
|
||||
"prettier": "*",
|
||||
"@types/node": "latest",
|
||||
"@typescript-eslint/eslint-plugin": "latest",
|
||||
"@typescript-eslint/parser": "latest",
|
||||
"all-contributors-cli": "^6.26.1",
|
||||
"builtin-modules": "latest",
|
||||
"esbuild": "latest",
|
||||
"eslint": "latest",
|
||||
"eslint-plugin-obsidianmd": "latest",
|
||||
"obsidian": "latest",
|
||||
"prettier": "latest",
|
||||
"stylelint": "latest",
|
||||
"stylelint-config-idiomatic-order": "*",
|
||||
"stylelint-config-recommended": "*",
|
||||
"stylelint-config-standard": "*",
|
||||
"stylelint-order": "*",
|
||||
"tslib": "*",
|
||||
"typescript": "*"
|
||||
"stylelint-config-idiomatic-order": "latest",
|
||||
"stylelint-config-recommended": "latest",
|
||||
"stylelint-config-standard": "latest",
|
||||
"stylelint-order": "latest",
|
||||
"tslib": "latest",
|
||||
"typescript": "latest"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
"@types/node": "latest",
|
||||
"@typescript-eslint/eslint-plugin": "latest",
|
||||
"@typescript-eslint/parser": "latest",
|
||||
"all-contributors-cli": "latest",
|
||||
"all-contributors-cli": "^6.26.1",
|
||||
"builtin-modules": "latest",
|
||||
"esbuild": "latest",
|
||||
"eslint": "latest",
|
||||
|
|
@ -38,4 +38,4 @@
|
|||
"dependencies": {
|
||||
"jsonpath-plus": "^10.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
export default {
|
||||
// ===== 设置标题 =====
|
||||
settings_title: "🌈 Dynamic Theme Background",
|
||||
version: "🛠️ Version: ",
|
||||
author: "🎨 Author: ",
|
||||
homepage: "🏠 Homepage: ",
|
||||
settings_title: "Dynamic Theme Background",
|
||||
version: "Version: ",
|
||||
author: "Author: ",
|
||||
homepage: "Homepage: ",
|
||||
|
||||
// ===== 基础设置 =====
|
||||
enable_plugin_name: "Enable dynamic background",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
export default {
|
||||
// ===== 设置标题 =====
|
||||
settings_title: "🌈 动态主题背景",
|
||||
version: "🛠️ 版本: ",
|
||||
author: "🎨 作者: ",
|
||||
homepage: "🏠 首页: ",
|
||||
settings_title: "Dynamic Theme Background",
|
||||
version: "Version: ",
|
||||
author: "Author: ",
|
||||
homepage: "Homepage: ",
|
||||
|
||||
// ===== 基础设置 =====
|
||||
enable_plugin_name: "启用动态背景",
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ export class BackgroundModal extends Modal {
|
|||
.onClick(() => {
|
||||
// 清空每背景覆盖,让其回退到全局
|
||||
this.blurDepth = undefined;
|
||||
this.bgItem.blurDepth = undefined as any;
|
||||
this.bgItem.blurDepth = undefined;
|
||||
this.displayAppearanceSettings(containerEl); // 重新渲染设置
|
||||
})
|
||||
);
|
||||
|
|
@ -202,7 +202,7 @@ export class BackgroundModal extends Modal {
|
|||
.onClick(() => {
|
||||
// 清空每背景覆盖,让其回退到全局
|
||||
this.brightness4Bg = undefined;
|
||||
this.bgItem.brightness4Bg = undefined as any;
|
||||
this.bgItem.brightness4Bg = undefined;
|
||||
this.displayAppearanceSettings(containerEl); // 重新渲染设置
|
||||
})
|
||||
);
|
||||
|
|
@ -226,7 +226,7 @@ export class BackgroundModal extends Modal {
|
|||
.onClick(() => {
|
||||
// 清空每背景覆盖,让其回退到全局
|
||||
this.saturate4Bg = undefined;
|
||||
this.bgItem.saturate4Bg = undefined as any;
|
||||
this.bgItem.saturate4Bg = undefined;
|
||||
this.displayAppearanceSettings(containerEl); // 重新渲染设置
|
||||
})
|
||||
);
|
||||
|
|
@ -284,10 +284,10 @@ export class BackgroundModal extends Modal {
|
|||
this.bgColorOpacityDark = undefined;
|
||||
this.bgColorLight = undefined;
|
||||
this.bgColorOpacityLight = undefined;
|
||||
this.bgItem.bgColorDark = undefined as any;
|
||||
this.bgItem.bgColorOpacityDark = undefined as any;
|
||||
this.bgItem.bgColorLight = undefined as any;
|
||||
this.bgItem.bgColorOpacityLight = undefined as any;
|
||||
this.bgItem.bgColorDark = undefined;
|
||||
this.bgItem.bgColorOpacityDark = undefined;
|
||||
this.bgItem.bgColorLight = undefined;
|
||||
this.bgItem.bgColorOpacityLight = undefined;
|
||||
this.displayAppearanceSettings(containerEl);
|
||||
})
|
||||
);
|
||||
|
|
@ -298,10 +298,10 @@ export class BackgroundModal extends Modal {
|
|||
.setDesc(t("bg_size_desc"))
|
||||
.addDropdown((dropdown) => {
|
||||
// 添加下拉选项
|
||||
dropdown.addOption("intelligent", "intelligent");
|
||||
dropdown.addOption("cover", "cover");
|
||||
dropdown.addOption("contain", "contain");
|
||||
dropdown.addOption("auto", "auto");
|
||||
dropdown.addOption("intelligent", "Intelligent");
|
||||
dropdown.addOption("cover", "Cover");
|
||||
dropdown.addOption("contain", "Contain");
|
||||
dropdown.addOption("auto", "Auto");
|
||||
// 使用专门的悬停选项方法添加 tooltip(推荐用法)
|
||||
addDropdownOptionHoverTooltip(
|
||||
dropdown,
|
||||
|
|
@ -331,7 +331,7 @@ export class BackgroundModal extends Modal {
|
|||
.onClick(() => {
|
||||
// 清空每背景覆盖,让其回退到全局
|
||||
this.bgSize = undefined;
|
||||
this.bgItem.bgSize = undefined as any;
|
||||
this.bgItem.bgSize = undefined;
|
||||
this.displayAppearanceSettings(containerEl); // 重新渲染设置
|
||||
})
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export class ImageFolderSuggestModal extends SuggestModal<string> {
|
|||
el.createEl("div", { text: folderPath });
|
||||
}
|
||||
|
||||
onChooseSuggestion(folderPath: string, evt: MouseEvent | KeyboardEvent) {
|
||||
onChooseSuggestion(folderPath: string, _evt: MouseEvent | KeyboardEvent) {
|
||||
this.onSubmit(folderPath);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export class ImagePathSuggestModal extends SuggestModal<string> {
|
|||
text.textContent = imagePath;
|
||||
}
|
||||
|
||||
onChooseSuggestion(imagePath: string, evt: MouseEvent | KeyboardEvent) {
|
||||
onChooseSuggestion(imagePath: string, _evt: MouseEvent | KeyboardEvent) {
|
||||
this.onSubmit(imagePath);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,7 +606,7 @@ export class WallpaperApiEditorModal extends Modal {
|
|||
try {
|
||||
const extraParams = JSON.parse(this.extraParamsTextarea.value);
|
||||
Object.assign(params, extraParams);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
new Notice(t("api_modal_invalid_json"));
|
||||
}
|
||||
}
|
||||
|
|
@ -657,9 +657,7 @@ export class WallpaperApiEditorModal extends Modal {
|
|||
value = selectEl.value || undefined;
|
||||
} else if (input.classList.contains("dtb-multiselect")) {
|
||||
// 多选
|
||||
const checkboxes = input.querySelectorAll(
|
||||
'input[type="checkbox"]:checked'
|
||||
) as NodeListOf<HTMLInputElement>;
|
||||
const checkboxes = input.querySelectorAll<HTMLInputElement>('input[type="checkbox"]:checked');
|
||||
const selectedValues = Array.from(checkboxes).map((cb) => cb.value);
|
||||
value = selectedValues.length > 0 ? selectedValues : undefined;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ export default class DynamicThemeBackgroundPlugin extends Plugin {
|
|||
// Wallpaper API 管理器
|
||||
// 实例化所有已配置的API
|
||||
for (const apiConfig of this.settings.wallpaperApis) {
|
||||
apiManager.createApi(apiConfig);
|
||||
void apiManager.createApi(apiConfig);
|
||||
}
|
||||
|
||||
console.debug("Dynamic Theme Background plugin loaded");
|
||||
|
|
@ -89,13 +89,13 @@ export default class DynamicThemeBackgroundPlugin extends Plugin {
|
|||
/**
|
||||
* 激活设置标签页视图
|
||||
*/
|
||||
async activateView() {
|
||||
activateView(): void {
|
||||
// 检查是否已经存在该类型的 leaf
|
||||
const existingLeaf = this.app.workspace.getLeavesOfType(DTB_SETTINGS_VIEW_TYPE)[0];
|
||||
|
||||
if (existingLeaf) {
|
||||
// 如果已存在,则聚焦它
|
||||
this.app.workspace.revealLeaf(existingLeaf);
|
||||
void this.app.workspace.revealLeaf(existingLeaf);
|
||||
} else {
|
||||
// 如果不存在,则创建新的 leaf
|
||||
const leaf = this.app.workspace.getLeaf("tab");
|
||||
|
|
@ -105,7 +105,7 @@ export default class DynamicThemeBackgroundPlugin extends Plugin {
|
|||
});
|
||||
|
||||
// 确保标签页获得焦点
|
||||
this.app.workspace.revealLeaf(leaf);
|
||||
void this.app.workspace.revealLeaf(leaf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ export default class DynamicThemeBackgroundPlugin extends Plugin {
|
|||
activateStatusBar() {
|
||||
this.deactivateStatusBar();
|
||||
this.statusBar = this.addStatusBarItem();
|
||||
this.statusBar.setText("🌈 DTB");
|
||||
this.statusBar.setText("🌈 DTB"); // eslint-disable-line obsidianmd/ui/sentence-case -- acronym
|
||||
this.statusBar.addClass("dtb-status-bar");
|
||||
this.statusBar.setAttribute("title", t("status_bar_title"));
|
||||
this.statusBar.addEventListener("click", (evt) => {
|
||||
|
|
|
|||
|
|
@ -102,8 +102,8 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
private displayHeader(containerEl: HTMLElement) {
|
||||
const headerContainer = containerEl.createDiv("dtb-section-header");
|
||||
|
||||
// 创建左侧标题容器
|
||||
const titleContainer = headerContainer.createDiv();
|
||||
// 创建左侧标题容器(预留位置)
|
||||
headerContainer.createDiv();
|
||||
// 移除顶级标题,按照Obsidian指南
|
||||
|
||||
// 创建右侧信息容器
|
||||
|
|
@ -349,10 +349,10 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
.setDesc(t("bg_size_desc"))
|
||||
.addDropdown((dropdown) => {
|
||||
// 添加下拉选项
|
||||
dropdown.addOption("intelligent", "intelligent");
|
||||
dropdown.addOption("cover", "cover");
|
||||
dropdown.addOption("contain", "contain");
|
||||
dropdown.addOption("auto", "auto");
|
||||
dropdown.addOption("intelligent", "Intelligent");
|
||||
dropdown.addOption("cover", "Cover");
|
||||
dropdown.addOption("contain", "Contain");
|
||||
dropdown.addOption("auto", "Auto");
|
||||
// 使用专门的悬停选项方法添加 tooltip(推荐用法)
|
||||
addDropdownOptionHoverTooltip(
|
||||
dropdown,
|
||||
|
|
@ -612,7 +612,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
enabled: true,
|
||||
};
|
||||
|
||||
const modal = new TimeRuleModal(this.app, editRule, async (updatedRule) => {
|
||||
const modal = new TimeRuleModal(this.app, editRule, (updatedRule) => {
|
||||
if (!updatedRule.name.trim() || !updatedRule.startTime || !updatedRule.endTime) {
|
||||
new Notice(t("notice_all_fields_required"));
|
||||
return;
|
||||
|
|
@ -643,7 +643,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
}
|
||||
|
||||
this.plugin.startBackgroundManager(); // 重新启动背景管理器以应用更改
|
||||
await this.plugin.saveSettings();
|
||||
void this.plugin.saveSettings();
|
||||
// 这里仅需刷新时间规则列表
|
||||
this.plugin.refreshActiveTimeRules();
|
||||
});
|
||||
|
|
@ -731,7 +731,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
type,
|
||||
value: "",
|
||||
};
|
||||
const modal = new BackgroundModal(this.app, this.plugin, bg, async (newBg: BackgroundItem) => {
|
||||
const modal = new BackgroundModal(this.app, this.plugin, bg, (newBg: BackgroundItem) => {
|
||||
if (!newBg.name.trim() || !newBg.value.trim()) {
|
||||
new Notice(t("notice_name_and_value_required"));
|
||||
return;
|
||||
|
|
@ -744,7 +744,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
|
||||
// 添加到设置中
|
||||
this.plugin.settings.backgrounds.push(newBg);
|
||||
await this.plugin.saveSettings();
|
||||
void this.plugin.saveSettings();
|
||||
|
||||
// 这里仅需刷新背景列表和时间规则列表
|
||||
this.displayBackgrounds();
|
||||
|
|
@ -756,7 +756,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
|
||||
// 显示编辑背景的模态窗口
|
||||
private showEditBackgroundModal(bg: BackgroundItem, index: number): void {
|
||||
const modal = new BackgroundModal(this.app, this.plugin, bg, async (newBg: BackgroundItem) => {
|
||||
const modal = new BackgroundModal(this.app, this.plugin, bg, (newBg: BackgroundItem) => {
|
||||
if (!newBg.name.trim() || !newBg.value.trim()) {
|
||||
new Notice(t("notice_name_and_value_required"));
|
||||
return;
|
||||
|
|
@ -767,7 +767,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
// 更新现有背景项
|
||||
this.plugin.settings.backgrounds[index] = newBg;
|
||||
|
||||
await this.plugin.saveSettings();
|
||||
void this.plugin.saveSettings();
|
||||
|
||||
// 如果当前正在使用这个背景,则更新显示
|
||||
if (this.plugin.background?.id === bg.id) {
|
||||
|
|
@ -792,8 +792,8 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
}, 0);
|
||||
}
|
||||
|
||||
private showAddFolderModal() {
|
||||
const modal = new ImageFolderSuggestModal(this.app, async (folderPath: string) => {
|
||||
private showAddFolderModal(): void {
|
||||
const modal = new ImageFolderSuggestModal(this.app, (folderPath: string) => {
|
||||
if (!folderPath.trim()) {
|
||||
new Notice(t("notice_valid_folder_path_required"));
|
||||
return;
|
||||
|
|
@ -806,14 +806,15 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// 处理文件夹中的图片文件
|
||||
await this.addImagesFromFolder(folderPath);
|
||||
new Notice(t("notice_folder_added_successfully", { folderPath }));
|
||||
} catch (error) {
|
||||
console.error("Error adding images from folder:", error);
|
||||
new Notice(t("notice_error_adding_folder_images"));
|
||||
}
|
||||
// 处理文件夹中的图片文件
|
||||
this.addImagesFromFolder(folderPath)
|
||||
.then(() => {
|
||||
new Notice(t("notice_folder_added_successfully", { folderPath }));
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Error adding images from folder:", error);
|
||||
new Notice(t("notice_error_adding_folder_images"));
|
||||
});
|
||||
});
|
||||
|
||||
modal.open();
|
||||
|
|
@ -916,7 +917,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
actions.createEl("button", { text: t("button_preview") }).onclick = () => {
|
||||
this.plugin.background = bg;
|
||||
this.plugin.settings.currentIndex = index; // 更新当前索引
|
||||
this.plugin.saveSettings();
|
||||
void this.plugin.saveSettings();
|
||||
this.plugin.updateStyleCss();
|
||||
this.displayBackgrounds(); // 刷新激活图标
|
||||
};
|
||||
|
|
@ -983,7 +984,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
break;
|
||||
}
|
||||
default:
|
||||
console.warn(`DTB: Unknown background type: ${bg.type}`);
|
||||
console.warn(`DTB: Unknown background type: ${bg.type as string}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1108,7 +1109,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
if (!existingApi) {
|
||||
// 如果不存在,则添加并创建 API 实例
|
||||
this.plugin.settings.wallpaperApis.push(apiConfig);
|
||||
apiManager.createApi(apiConfig);
|
||||
void apiManager.createApi(apiConfig);
|
||||
}
|
||||
}
|
||||
new Notice(t("restore_default_apis_success"));
|
||||
|
|
@ -1317,7 +1318,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
|
||||
const modal = new WallpaperApiEditorModal(this.app, emptyConfig, (apiConfig) => {
|
||||
// 创建新的API实例
|
||||
apiManager.createApi(apiConfig);
|
||||
void apiManager.createApi(apiConfig);
|
||||
// 添加到插件设置中
|
||||
this.plugin.settings.wallpaperApis.push(apiConfig);
|
||||
void this.plugin.saveSettings();
|
||||
|
|
@ -1332,7 +1333,7 @@ export class DTBSettingTab extends PluginSettingTab {
|
|||
private showEditWallpaperApiModal(apiConfig: WallpaperApiConfig, index: number) {
|
||||
const modal = new WallpaperApiEditorModal(this.app, apiConfig, (updatedConfig) => {
|
||||
// 有可能api类型也修改了,干脆重新创建API实例覆盖原来的
|
||||
apiManager.createApi(updatedConfig);
|
||||
void apiManager.createApi(updatedConfig);
|
||||
|
||||
this.plugin.settings.wallpaperApis[index] = updatedConfig;
|
||||
void this.plugin.saveSettings();
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ export class DragSort<T> {
|
|||
}
|
||||
};
|
||||
|
||||
const dropHandler = async (e: DragEvent) => {
|
||||
const dropHandler = (e: DragEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
const draggedId = e.dataTransfer?.getData("text/plain");
|
||||
|
|
@ -172,7 +172,7 @@ export class DragSort<T> {
|
|||
const midpoint = rect.top + rect.height / 2;
|
||||
const insertAfter = e.clientY >= midpoint;
|
||||
|
||||
await this.reorderItems(draggedId, targetId, insertAfter);
|
||||
void this.reorderItems(draggedId, targetId, insertAfter);
|
||||
|
||||
// 清理样式
|
||||
element.classList.remove("dtb-drag-over-top", "dtb-drag-over-bottom");
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ export abstract class BaseWallpaperApi {
|
|||
return [];
|
||||
}
|
||||
|
||||
static validateParams(params: WallpaperApiParams): { valid: boolean; errors?: string[] } {
|
||||
static validateParams(_params: WallpaperApiParams): { valid: boolean; errors?: string[] } {
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export class CustomApi extends BaseWallpaperApi {
|
|||
// 参数验证
|
||||
// ============================================================================
|
||||
|
||||
validateParams(params: WallpaperApiParams): boolean {
|
||||
validateParams(_params: WallpaperApiParams): boolean {
|
||||
if (!this.baseUrl) {
|
||||
console.warn("Custom API: baseUrl is required");
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ export class PexelsApi extends BaseWallpaperApi {
|
|||
// 更新分页信息
|
||||
this.totalPages = response.total_results ? Math.ceil(response.total_results / this.perPage) : -1;
|
||||
this.totalCount = response.total_results ?? -1;
|
||||
this.perPage = Number(this.params.per_page) ?? 15;
|
||||
this.perPage = Number(this.params.per_page) || 15;
|
||||
|
||||
new Notice(
|
||||
t("api_initialized_notice", {
|
||||
|
|
@ -387,18 +387,32 @@ export class PexelsApi extends BaseWallpaperApi {
|
|||
return response.json;
|
||||
}
|
||||
|
||||
// 安全地将未知值转换为字符串,避免对象被转换为 [object Object]
|
||||
private safeString(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "";
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 辅助方法:转换 API 返回的图片数据为 WallpaperImage
|
||||
private transformPhoto(photo: Record<string, unknown>): WallpaperImage {
|
||||
const src = (photo.src as Record<string, unknown>) ?? {};
|
||||
|
||||
return {
|
||||
id: String(photo.id || ""),
|
||||
url: String(src.large || src.original || src.large2x || ""),
|
||||
id: this.safeString(photo.id),
|
||||
url: this.safeString(src.large) || this.safeString(src.original) || this.safeString(src.large2x),
|
||||
width: Number(photo.width) || undefined,
|
||||
height: Number(photo.height) || undefined,
|
||||
author: String(photo.photographer || ""),
|
||||
description: String(photo.alt || ""),
|
||||
downloadUrl: String(src.original || src.large2x || src.large || ""),
|
||||
author: this.safeString(photo.photographer),
|
||||
description: this.safeString(photo.alt),
|
||||
downloadUrl: this.safeString(src.original) || this.safeString(src.large2x) || this.safeString(src.large),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ export class PixabayApi extends BaseWallpaperApi {
|
|||
// 更新分页信息
|
||||
this.totalPages = response.totalHits ? Math.ceil(response.totalHits / this.perPage) : -1;
|
||||
this.totalCount = response.total ?? -1;
|
||||
this.perPage = Number(this.params.per_page) ?? 20;
|
||||
this.perPage = Number(this.params.per_page) || 20;
|
||||
|
||||
new Notice(
|
||||
t("api_initialized_notice", {
|
||||
|
|
@ -439,19 +439,38 @@ export class PixabayApi extends BaseWallpaperApi {
|
|||
return response.json;
|
||||
}
|
||||
|
||||
// 安全地将未知值转换为字符串,避免对象被转换为 [object Object]
|
||||
private safeString(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "";
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 辅助方法:转换 API 返回的图片数据为 WallpaperImage
|
||||
private transformImage(image: Record<string, unknown>): WallpaperImage {
|
||||
const tagsStr = this.safeString(image.tags);
|
||||
return {
|
||||
id: String(image.id ?? ""),
|
||||
url: String(image.largeImageURL || image.fullHDURL || image.webformatURL || ""),
|
||||
id: this.safeString(image.id),
|
||||
url:
|
||||
this.safeString(image.largeImageURL) ||
|
||||
this.safeString(image.fullHDURL) ||
|
||||
this.safeString(image.webformatURL),
|
||||
width: Number(image.imageWidth) || Number(image.webformatWidth) || undefined,
|
||||
height: Number(image.imageHeight) || Number(image.webformatHeight) || undefined,
|
||||
author: String(image.user || ""),
|
||||
description: String(image.tags || ""),
|
||||
tags: String(image.tags || "")
|
||||
.split(", ")
|
||||
.filter((tag) => tag.trim()),
|
||||
downloadUrl: String(image.imageURL || image.largeImageURL || image.fullHDURL || ""),
|
||||
author: this.safeString(image.user),
|
||||
description: tagsStr,
|
||||
tags: tagsStr.split(", ").filter((tag) => tag.trim()),
|
||||
downloadUrl:
|
||||
this.safeString(image.imageURL) ||
|
||||
this.safeString(image.largeImageURL) ||
|
||||
this.safeString(image.fullHDURL),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ interface Qihoo360WallpaperResponse {
|
|||
img_800_600?: string;
|
||||
img_640_480?: string;
|
||||
// 支持更多分辨率字段
|
||||
[key: string]: any;
|
||||
[key: string]: string | undefined;
|
||||
}>;
|
||||
}
|
||||
|
||||
|
|
@ -457,7 +457,7 @@ export class Qihoo360Api extends BaseWallpaperApi {
|
|||
/**
|
||||
* 转换API响应为WallpaperImage格式
|
||||
*/
|
||||
private convertToWallpaperImage(item: any, index: number): WallpaperImage {
|
||||
private convertToWallpaperImage(item: Qihoo360WallpaperResponse["data"][number], index: number): WallpaperImage {
|
||||
// 获取首选分辨率设置
|
||||
const preferredResolution = this.params.preferredResolution || "auto";
|
||||
let imageUrl = item.url;
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ export class UnsplashApi extends BaseWallpaperApi {
|
|||
})
|
||||
);
|
||||
|
||||
this.perPage = Number(this.params.per_page) ?? 10;
|
||||
this.perPage = Number(this.params.per_page) || 10;
|
||||
|
||||
// 初始化数据缓存
|
||||
this.wallpaperImageCache = [];
|
||||
|
|
@ -389,19 +389,33 @@ export class UnsplashApi extends BaseWallpaperApi {
|
|||
return response.json;
|
||||
}
|
||||
|
||||
// 安全地将未知值转换为字符串,避免对象被转换为 [object Object]
|
||||
private safeString(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "";
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 辅助方法:转换 API 返回的图片数据为 WallpaperImage
|
||||
private transformPhoto(photo: Record<string, unknown>): WallpaperImage {
|
||||
const user = (photo.user as Record<string, unknown>) ?? {};
|
||||
const urls = (photo.urls as Record<string, unknown>) ?? {};
|
||||
|
||||
return {
|
||||
id: String(photo.id ?? ""),
|
||||
url: String(urls.regular || urls.full || urls.raw || ""),
|
||||
id: this.safeString(photo.id),
|
||||
url: this.safeString(urls.regular) || this.safeString(urls.full) || this.safeString(urls.raw),
|
||||
width: Number(photo.width) || undefined,
|
||||
height: Number(photo.height) || undefined,
|
||||
author: String(user.name || user.username || ""),
|
||||
description: String(photo.description || photo.alt_description || ""),
|
||||
downloadUrl: String(urls.full || urls.raw || ""),
|
||||
author: this.safeString(user.name) || this.safeString(user.username),
|
||||
description: this.safeString(photo.description) || this.safeString(photo.alt_description),
|
||||
downloadUrl: this.safeString(urls.full) || this.safeString(urls.raw),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,12 +117,12 @@ export class WallhavenApi extends BaseWallpaperApi {
|
|||
{ value: "nsfw", label: "NSFW (18+)" },
|
||||
],
|
||||
toApiValue: (uiValue: string[]) => {
|
||||
const arr = Array.isArray(uiValue) ? (uiValue as string[]) : [];
|
||||
const arr = Array.isArray(uiValue) ? uiValue : [];
|
||||
let result = "";
|
||||
result += arr.includes("sfw") ? "1" : "0";
|
||||
result += arr.includes("sketchy") ? "1" : "0";
|
||||
result += arr.includes("nsfw") ? "1" : "0";
|
||||
return result ?? (defaultParams.purity as string);
|
||||
return result || (defaultParams.purity as string);
|
||||
},
|
||||
fromApiValue: (apiValue: string) => {
|
||||
const str = apiValue?.toString() ?? (defaultParams.purity as string);
|
||||
|
|
@ -381,11 +381,27 @@ export class WallhavenApi extends BaseWallpaperApi {
|
|||
console.debug(`Fetching Wallhaven search results from: ${url}`);
|
||||
const response = await requestUrl({ url });
|
||||
return response.json;
|
||||
} // 辅助方法:转换 API 返回的图片数据为 WallpaperImage
|
||||
}
|
||||
|
||||
// 安全地将未知值转换为字符串,避免对象被转换为 [object Object]
|
||||
private safeString(value: unknown): string {
|
||||
if (value === null || value === undefined) {
|
||||
return "";
|
||||
}
|
||||
if (typeof value === "string") {
|
||||
return value;
|
||||
}
|
||||
if (typeof value === "number" || typeof value === "boolean") {
|
||||
return String(value);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// 辅助方法:转换 API 返回的图片数据为 WallpaperImage
|
||||
private transformImage(apiImage: Record<string, unknown>): WallpaperImage {
|
||||
return {
|
||||
id: String(apiImage.id ?? ""),
|
||||
url: String(apiImage.path ?? ""),
|
||||
id: this.safeString(apiImage.id),
|
||||
url: this.safeString(apiImage.path),
|
||||
width: Number(apiImage.dimension_x) || undefined,
|
||||
height: Number(apiImage.dimension_y) || undefined,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue