Skip to content

Commit 73a5b1c

Browse files
author
darksheep
committed
feat: add dark light mode
1 parent 8808d3c commit 73a5b1c

4 files changed

Lines changed: 109 additions & 13 deletions

File tree

doc/features.md

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
## 功能特点
66

77
### 1. 代码笔记
8-
98
- 支持在代码中选中文本并添加笔记
109
- 笔记自动关联到对应的代码位置
1110
- 可以快速跳转到笔记关联的代码处
@@ -20,7 +19,6 @@
2019
- 新笔记自动添加到列表开头并选中
2120

2221
### 2. 流程图功能
23-
2422
- 支持创建和编辑流程图,可视化代码之间的关系
2523
- 流程图节点可以关联到具体的代码笔记
2624
- 节点功能:
@@ -45,15 +43,13 @@
4543
- 支持删除连接
4644

4745
### 3. 标签管理
48-
4946
- 支持为笔记添加标签
5047
- 标签自动关联到流程图
5148
- 支持通过标签快速查找相关笔记
5249
- 标签自动去重和格式化
5350
- 支持批量添加和删除标签
5451

5552
### 4. 搜索功能
56-
5753
- 支持按标题和内容搜索笔记
5854
- 实时搜索结果展示
5955
- 可以直接从搜索结果创建流程图节点
@@ -63,7 +59,6 @@
6359
## 技术实现
6460

6561
### 前端实现
66-
6762
- 使用原生 JavaScript 和 CSS 构建界面
6863
- 采用 Apple 设计风格:
6964
- 磨砂玻璃效果(backdrop-filter)
@@ -80,7 +75,6 @@
8075
- 右键菜单支持
8176

8277
### 后端实现
83-
8478
- 基于 IntelliJ Platform Plugin SDK
8579
- 使用 JCEF (Java Chromium Embedded Framework) 实现现代化界面
8680
- 数据存储:
@@ -93,7 +87,6 @@
9387
- 异步处理避免阻塞
9488

9589
### 流程图实现
96-
9790
- 使用 jsPlumb 实现节点连接
9891
- 自定义布局算法:
9992
- 力导向图布局
@@ -107,13 +100,11 @@
107100
## 使用说明
108101

109102
### 创建笔记
110-
111103
1. 在代码中选中要做笔记的文本
112104
2. 使用快捷键或右键菜单创建笔记
113105
3. 输入笔记内容并保存
114106

115107
### 使用流程图
116-
117108
1. 点击工具栏的流程图按钮打开流程图界面
118109
2. 使用"新建节点"按钮创建节点
119110
3. 可以:
@@ -124,7 +115,6 @@
124115
5. 使用"加载流程图"按钮查看已保存的流程图
125116

126117
## 数据存储
127-
128118
- 笔记数据:
129119
- 标题、内容、代码位置
130120
- 创建和更新时间
@@ -165,5 +155,8 @@
165155
- [X] 笔记列表根据tag筛选笔记时,多选tag,应该是并集,而不是交集
166156
- [X] 当前选择tag可以筛选出笔记,但是点击列表某个笔记时,会展示笔记详情,但是列表会变为所有笔记,丢失了筛选效果
167157
- [X] 删除笔记导致tag删除时,对该tag的筛选条件没有移除,导致无法看到笔记,但是点击按照名称排序,笔记又会出现
158+
- [ ] 新建笔记默认选中时,笔记详情未更新
159+
- [ ] 把新建笔记的弹窗也改为browser 来优化UI和操作
168160
- [ ] 编辑笔记内容时会移除换行符
169161
- [ ] 新增笔记时,自由输入tag不会被保存
162+
- [ ] 增加手动主题切换功能,但是不同页面的主题选择不共享,且当前无法自动跟随IDEA主题设置dark/light

src/main/java/com/darksheep/sheepnote/ui/swing/toolWindow/NoteListToolWindowFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public class NoteListToolWindowFactory implements ToolWindowFactory {
4949

5050
private static NoteDataHandler noteDataHandler;
5151

52+
53+
5254
@Override
5355
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
5456

src/main/resources/META-INF/web/flowchart/index.html

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
<button id="refresh" class="toolbar-btn">
2929
<span class="icon"></span>Refresh
3030
</button>
31+
<button id="toggleTheme" class="toolbar-btn" onclick="toggleTheme()">
32+
<svg id="themeIcon" class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
33+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
34+
</svg>
35+
Theme
36+
</button>
3137
</div>
3238
</div>
3339

@@ -81,6 +87,15 @@ <h3>Load Flowchart</h3>
8187
<div id="flowchartContainer"></div>
8288

8389
<style>
90+
html[theme='dark-mode'] {
91+
filter: invert(1) hue-rotate(180deg);
92+
}
93+
html[theme='dark-mode'] img{
94+
filter: invert(1) hue-rotate(180deg);
95+
}
96+
html {
97+
transition: color 300ms, background-color 300ms;
98+
}
8499
/* iOS 风格的工具栏样式 */
85100
.toolbar {
86101
position: fixed;
@@ -1178,6 +1193,41 @@ <h3>Load Flowchart</h3>
11781193
}
11791194
}
11801195
});
1196+
1197+
function toggleTheme() {
1198+
const htmlElement = document.documentElement;
1199+
const isDarkMode = htmlElement.getAttribute('theme') === 'dark-mode';
1200+
1201+
if (isDarkMode) {
1202+
htmlElement.removeAttribute('theme');
1203+
localStorage.setItem('theme', 'light');
1204+
document.getElementById('themeIcon').innerHTML = `
1205+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
1206+
`;
1207+
} else {
1208+
htmlElement.setAttribute('theme', 'dark-mode');
1209+
localStorage.setItem('theme', 'dark');
1210+
document.getElementById('themeIcon').innerHTML = `
1211+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
1212+
`;
1213+
}
1214+
}
1215+
1216+
// 初始化主题
1217+
document.addEventListener('DOMContentLoaded', () => {
1218+
const savedTheme = localStorage.getItem('theme');
1219+
if (savedTheme === 'dark') {
1220+
document.documentElement.setAttribute('theme', 'dark-mode');
1221+
document.getElementById('themeIcon').innerHTML = `
1222+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
1223+
`;
1224+
} else {
1225+
document.documentElement.removeAttribute('theme');
1226+
document.getElementById('themeIcon').innerHTML = `
1227+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
1228+
`;
1229+
}
1230+
});
11811231
</script>
11821232
</body>
1183-
</html>
1233+
</html>

src/main/resources/META-INF/web/webNote.html

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!DOCTYPE html>
1+
<!DOCTYPE html>
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8">
@@ -17,7 +17,15 @@
1717
--font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell;
1818
--hover-background: rgba(0, 122, 255, 0.08);
1919
}
20-
20+
html[theme='dark-mode'] {
21+
filter: invert(1) hue-rotate(180deg);
22+
}
23+
html[theme='dark-mode'] img{
24+
filter: invert(1) hue-rotate(180deg);
25+
}
26+
html {
27+
transition: color 300ms, background-color 300ms;
28+
}
2129
body {
2230
font-family: var(--font-stack);
2331
background: var(--system-background);
@@ -766,6 +774,13 @@
766774
</svg>
767775
<span>Refresh</span>
768776
</div>
777+
<!-- Theme Toggle Button -->
778+
<div class="sort-item" onclick="toggleTheme()">
779+
<svg id="themeIcon" class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
780+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
781+
</svg>
782+
<span>Theme</span>
783+
</div>
769784
</div>
770785
<!-- 添加Tags面板 -->
771786
<div class="tags-panel" id="tagsPanel">
@@ -1087,6 +1102,41 @@
10871102
});
10881103
}
10891104

1105+
function toggleTheme() {
1106+
const htmlElement = document.documentElement;
1107+
const isDarkMode = htmlElement.getAttribute('theme') === 'dark-mode';
1108+
1109+
if (isDarkMode) {
1110+
htmlElement.removeAttribute('theme');
1111+
localStorage.setItem('theme', 'light');
1112+
document.getElementById('themeIcon').innerHTML = `
1113+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
1114+
`;
1115+
} else {
1116+
htmlElement.setAttribute('theme', 'dark-mode');
1117+
localStorage.setItem('theme', 'dark');
1118+
document.getElementById('themeIcon').innerHTML = `
1119+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
1120+
`;
1121+
}
1122+
}
1123+
1124+
// 初始化主题
1125+
document.addEventListener('DOMContentLoaded', () => {
1126+
const savedTheme = localStorage.getItem('theme');
1127+
if (savedTheme === 'dark') {
1128+
document.documentElement.setAttribute('theme', 'dark-mode');
1129+
document.getElementById('themeIcon').innerHTML = `
1130+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z"/>
1131+
`;
1132+
} else {
1133+
document.documentElement.removeAttribute('theme');
1134+
document.getElementById('themeIcon').innerHTML = `
1135+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m8.66-8.66h-1M4.34 12H3m15.07-6.93l-.7.7M6.34 17.66l-.7.7m12.02 0l-.7-.7M6.34 6.34l-.7-.7M12 5a7 7 0 100 14 7 7 0 000-14z"/>
1136+
`;
1137+
}
1138+
});
1139+
10901140
// 删除笔记
10911141
function deleteNote() {
10921142
if (!contextMenuNoteId) return;
@@ -1115,6 +1165,7 @@
11151165
selectedNoteId = newNote.id;
11161166
noteItem = newNote;
11171167
updateNoteList();
1168+
selectNote(newNote)
11181169

11191170
// 确保新笔记在列表中可见
11201171
const noteList = document.getElementById('noteList');

0 commit comments

Comments
 (0)