mirror of
https://github.com/woodchen-ink/obsidian-publish-to-discourse.git
synced 2025-07-18 05:42:05 +08:00
Compare commits
2 Commits
87a903b4b5
...
6acd9bcc01
Author | SHA1 | Date | |
---|---|---|---|
|
6acd9bcc01 | ||
|
951eba6bc5 |
35
src/api.ts
35
src/api.ts
@ -303,12 +303,41 @@ export class DiscourseAPI {
|
|||||||
|
|
||||||
if (data && data.tags) {
|
if (data && data.tags) {
|
||||||
const canCreateTags = await this.checkCanCreateTags();
|
const canCreateTags = await this.checkCanCreateTags();
|
||||||
|
|
||||||
|
// 处理所有标签(包括tag_groups中的标签)
|
||||||
|
const allTags = new Map<string, { name: string; count: number }>();
|
||||||
|
|
||||||
|
// 添加普通标签
|
||||||
data.tags.forEach((tag: any) => {
|
data.tags.forEach((tag: any) => {
|
||||||
tags.push({
|
allTags.set(tag.name, { name: tag.name, count: tag.count || 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加tag_groups中的标签
|
||||||
|
if (data.extras && data.extras.tag_groups) {
|
||||||
|
data.extras.tag_groups.forEach((group: any) => {
|
||||||
|
if (group.tags) {
|
||||||
|
group.tags.forEach((tag: any) => {
|
||||||
|
// 如果标签已存在,取较大的count值
|
||||||
|
const existing = allTags.get(tag.name);
|
||||||
|
if (existing) {
|
||||||
|
existing.count = Math.max(existing.count, tag.count || 0);
|
||||||
|
} else {
|
||||||
|
allTags.set(tag.name, { name: tag.name, count: tag.count || 0 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按count数量排序,转换为最终格式
|
||||||
|
const sortedTags = Array.from(allTags.values())
|
||||||
|
.sort((a, b) => b.count - a.count)
|
||||||
|
.map(tag => ({
|
||||||
name: tag.name,
|
name: tag.name,
|
||||||
canCreate: canCreateTags
|
canCreate: canCreateTags
|
||||||
});
|
}));
|
||||||
});
|
|
||||||
|
tags.push(...sortedTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags;
|
return tags;
|
||||||
|
54
src/ui.ts
54
src/ui.ts
@ -82,6 +82,7 @@ export class SelectCategoryModal extends Modal {
|
|||||||
removeBtn.onclick = () => {
|
removeBtn.onclick = () => {
|
||||||
selectedTags.delete(tag);
|
selectedTags.delete(tag);
|
||||||
updateSelectedTags();
|
updateSelectedTags();
|
||||||
|
showDefaultTags(); // 重新显示网格,让移除的标签重新出现
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -101,18 +102,47 @@ export class SelectCategoryModal extends Modal {
|
|||||||
// 创建标签建议容器
|
// 创建标签建议容器
|
||||||
const tagSuggestions = tagInputContainer.createEl('div', { cls: 'tag-suggestions' });
|
const tagSuggestions = tagInputContainer.createEl('div', { cls: 'tag-suggestions' });
|
||||||
|
|
||||||
|
// 创建默认标签网格容器
|
||||||
|
const defaultTagsGrid = tagInputContainer.createEl('div', { cls: 'default-tags-grid' });
|
||||||
|
|
||||||
|
// 显示默认标签网格
|
||||||
|
const showDefaultTags = () => {
|
||||||
|
defaultTagsGrid.empty();
|
||||||
|
const availableTags = this.tags.filter(tag => !selectedTags.has(tag.name)).slice(0, 20);
|
||||||
|
|
||||||
|
if (availableTags.length > 0) {
|
||||||
|
availableTags.forEach(tag => {
|
||||||
|
const tagEl = defaultTagsGrid.createEl('span', {
|
||||||
|
cls: 'grid-tag',
|
||||||
|
text: tag.name
|
||||||
|
});
|
||||||
|
tagEl.onclick = () => {
|
||||||
|
selectedTags.add(tag.name);
|
||||||
|
updateSelectedTags();
|
||||||
|
showDefaultTags(); // 重新显示网格,移除已选标签
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化显示默认标签网格
|
||||||
|
showDefaultTags();
|
||||||
|
|
||||||
// 处理输入事件,显示匹配的标签
|
// 处理输入事件,显示匹配的标签
|
||||||
tagInput.oninput = () => {
|
tagInput.oninput = () => {
|
||||||
const value = tagInput.value.toLowerCase();
|
const value = tagInput.value.toLowerCase();
|
||||||
tagSuggestions.empty();
|
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
|
// 有输入时隐藏默认网格,显示搜索结果
|
||||||
|
defaultTagsGrid.style.display = 'none';
|
||||||
|
tagSuggestions.empty();
|
||||||
|
|
||||||
const matches = this.tags
|
const matches = this.tags
|
||||||
.filter(tag =>
|
.filter(tag =>
|
||||||
tag.name.toLowerCase().includes(value) &&
|
tag.name.toLowerCase().includes(value) &&
|
||||||
!selectedTags.has(tag.name)
|
!selectedTags.has(tag.name)
|
||||||
)
|
)
|
||||||
.slice(0, 10);
|
.slice(0, 20); // 搜索结果显示更多
|
||||||
|
|
||||||
if (matches.length > 0) {
|
if (matches.length > 0) {
|
||||||
// 获取输入框位置和宽度
|
// 获取输入框位置和宽度
|
||||||
@ -126,6 +156,7 @@ export class SelectCategoryModal extends Modal {
|
|||||||
tagSuggestions.style.top = `${inputRect.bottom + 4}px`;
|
tagSuggestions.style.top = `${inputRect.bottom + 4}px`;
|
||||||
tagSuggestions.style.left = `${inputRect.left}px`;
|
tagSuggestions.style.left = `${inputRect.left}px`;
|
||||||
tagSuggestions.style.width = `${Math.min(inputRect.width, maxWidth)}px`;
|
tagSuggestions.style.width = `${Math.min(inputRect.width, maxWidth)}px`;
|
||||||
|
tagSuggestions.style.display = 'block';
|
||||||
|
|
||||||
matches.forEach(tag => {
|
matches.forEach(tag => {
|
||||||
const suggestion = tagSuggestions.createEl('div', {
|
const suggestion = tagSuggestions.createEl('div', {
|
||||||
@ -135,11 +166,20 @@ export class SelectCategoryModal extends Modal {
|
|||||||
suggestion.onclick = () => {
|
suggestion.onclick = () => {
|
||||||
selectedTags.add(tag.name);
|
selectedTags.add(tag.name);
|
||||||
tagInput.value = '';
|
tagInput.value = '';
|
||||||
tagSuggestions.empty();
|
tagSuggestions.style.display = 'none';
|
||||||
|
defaultTagsGrid.style.display = 'grid';
|
||||||
updateSelectedTags();
|
updateSelectedTags();
|
||||||
|
showDefaultTags();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
tagSuggestions.style.display = 'none';
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// 无输入时显示默认网格,隐藏搜索结果
|
||||||
|
tagSuggestions.style.display = 'none';
|
||||||
|
defaultTagsGrid.style.display = 'grid';
|
||||||
|
showDefaultTags();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,16 +193,19 @@ export class SelectCategoryModal extends Modal {
|
|||||||
if (existingTag) {
|
if (existingTag) {
|
||||||
selectedTags.add(existingTag.name);
|
selectedTags.add(existingTag.name);
|
||||||
updateSelectedTags();
|
updateSelectedTags();
|
||||||
|
showDefaultTags();
|
||||||
} else if (this.canCreateTags) {
|
} else if (this.canCreateTags) {
|
||||||
selectedTags.add(value);
|
selectedTags.add(value);
|
||||||
updateSelectedTags();
|
updateSelectedTags();
|
||||||
|
showDefaultTags();
|
||||||
} else {
|
} else {
|
||||||
// 显示权限提示
|
// 显示权限提示
|
||||||
new Notice(t('PERMISSION_ERROR'), 3000);
|
new Notice(t('PERMISSION_ERROR'), 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tagInput.value = '';
|
tagInput.value = '';
|
||||||
tagSuggestions.empty();
|
tagSuggestions.style.display = 'none';
|
||||||
|
defaultTagsGrid.style.display = 'grid';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -170,7 +213,8 @@ export class SelectCategoryModal extends Modal {
|
|||||||
tagInput.onblur = () => {
|
tagInput.onblur = () => {
|
||||||
// 延迟隐藏,以便可以点击建议
|
// 延迟隐藏,以便可以点击建议
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
tagSuggestions.empty();
|
tagSuggestions.style.display = 'none';
|
||||||
|
defaultTagsGrid.style.display = 'grid';
|
||||||
}, 200);
|
}, 200);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
75
styles.css
75
styles.css
@ -199,42 +199,91 @@ If your plugin does not need CSS, delete this file.
|
|||||||
.discourse-sync-modal .tag {
|
.discourse-sync-modal .tag {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
background-color: var(--interactive-accent);
|
background-color: var(--interactive-accent);
|
||||||
color: var(--text-on-accent);
|
color: var(--text-on-accent);
|
||||||
|
padding: 4px 8px;
|
||||||
border-radius: var(--radius-s);
|
border-radius: var(--radius-s);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
border: 1px solid var(--interactive-accent);
|
max-width: 200px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discourse-sync-modal .tag:hover {
|
.discourse-sync-modal .tag:hover {
|
||||||
background-color: var(--interactive-accent-hover);
|
background-color: var(--interactive-accent-hover);
|
||||||
border-color: var(--interactive-accent-hover);
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discourse-sync-modal .remove-tag {
|
.discourse-sync-modal .remove-tag {
|
||||||
|
margin-left: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
font-weight: bold;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
width: 16px;
|
line-height: 1;
|
||||||
height: 16px;
|
opacity: 0.8;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background-color: var(--background-modifier-hover);
|
background-color: rgba(255, 255, 255, 0.2);
|
||||||
margin-left: 4px;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.discourse-sync-modal .remove-tag:hover {
|
.discourse-sync-modal .remove-tag:hover {
|
||||||
background-color: var(--background-modifier-error);
|
|
||||||
color: var(--text-on-accent);
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1.1);
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 默认标签网格样式 */
|
||||||
|
.discourse-sync-modal .default-tags-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
background-color: var(--background-secondary);
|
||||||
|
border-radius: var(--radius-s);
|
||||||
|
border: 1px solid var(--background-modifier-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.discourse-sync-modal .grid-tag {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
color: var(--text-normal);
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: var(--radius-s);
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
border: 1px solid var(--background-modifier-border);
|
||||||
|
text-align: center;
|
||||||
|
min-height: 28px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.discourse-sync-modal .grid-tag:hover {
|
||||||
|
background-color: var(--interactive-accent);
|
||||||
|
color: var(--text-on-accent);
|
||||||
|
border-color: var(--interactive-accent);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
.discourse-sync-modal .grid-tag:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: var(--shadow-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
.discourse-sync-modal input[type="text"] {
|
.discourse-sync-modal input[type="text"] {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user