Skip to content

Commit 3a1e90d

Browse files
committed
Release v0.4.20-beta.4
1 parent 668abec commit 3a1e90d

9 files changed

Lines changed: 35 additions & 28 deletions

File tree

app/backend/ipc/index.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,17 +1072,6 @@ export function registerIpcHandlers(): void {
10721072
return result.canceled ? null : result.filePaths[0]
10731073
})
10741074

1075-
// 同一个选择框允许选择单个文件或文件夹,前端据此自动使用正确资源类型。
1076-
ipcMain.handle('files:pickFileOrFolder', async () => {
1077-
const result = await dialog.showOpenDialog({
1078-
title: '选择文件或文件夹',
1079-
properties: ['openFile', 'openDirectory'],
1080-
})
1081-
if (result.canceled || !result.filePaths[0]) return null
1082-
const filePath = result.filePaths[0]
1083-
return { path: filePath, isDirectory: statSync(filePath).isDirectory() }
1084-
})
1085-
10861075
// 打开图片文件选择对话框(用于设置自定义封面)
10871076
ipcMain.handle('files:pickImage', async () => {
10881077
const result = await dialog.showOpenDialog({

app/backend/preload.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ contextBridge.exposeInMainWorld('api', {
116116
getAppIcon: (filePath: string, force?: boolean): Promise<string | null> => ipcRenderer.invoke('files:getAppIcon', filePath, force),
117117
saveCover: (resourceId: string, dataUrl: string, userPicked?: boolean): Promise<string | null> => ipcRenderer.invoke('files:saveCover', resourceId, dataUrl, userPicked),
118118
pickFile: (): Promise<string | null> => ipcRenderer.invoke('files:pickFile'),
119-
pickFileOrFolder: (): Promise<{ path: string; isDirectory: boolean } | null> => ipcRenderer.invoke('files:pickFileOrFolder'),
120119
pickImage: (): Promise<string | null> => ipcRenderer.invoke('files:pickImage'),
121120
pickFolder: (): Promise<string | null> => ipcRenderer.invoke('files:pickFolder'),
122121
pickMultipleFiles: (): Promise<string[] | null> => ipcRenderer.invoke('files:pickMultipleFiles'),

app/frontend/src/components/AddResourceModal.vue

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
<div
145145
class="drop-zone"
146146
:class="{ 'has-file': !!form.file_path, 'drag-over': isDragOver }"
147-
@click="pickFileOrFolder"
147+
@click="pickFile"
148148
@dragover.prevent="isDragOver = true"
149149
@dragleave.prevent="isDragOver = false"
150150
@drop.prevent="onDrop"
@@ -167,6 +167,14 @@
167167
<span class="dz-upload-icon" v-html="uploadIcon" />
168168
<span class="dz-text">{{ t('addModal.file.dragHint') }}</span>
169169
<span class="dz-hint">{{ t('addModal.file.orBrowse') }}</span>
170+
<div class="file-choice-actions" @click.stop>
171+
<button type="button" class="file-choice-btn" @click="pickFile">
172+
<span v-html="uploadIcon" />{{ t('addModal.file.chooseFile') }}
173+
</button>
174+
<button type="button" class="file-choice-btn" @click="pickFolder">
175+
<span v-html="folderIcon" />{{ t('addModal.file.chooseFolder') }}
176+
</button>
177+
</div>
170178
</template>
171179
</div>
172180
<div class="path-row">
@@ -176,7 +184,7 @@
176184
:placeholder="t('addModal.file.placeholder')"
177185
@change="onPathChange"
178186
/>
179-
<button class="browse-btn" @click.stop="pickFileOrFolder" v-html="folderIcon" :title="t('addModal.file.browse')" />
187+
<button class="browse-btn" @click.stop="pickFile" v-html="folderIcon" :title="t('addModal.file.browse')" />
180188
</div>
181189
</div>
182190

@@ -614,9 +622,14 @@ async function createDocument() {
614622
}
615623
616624
// ── 单个文件操作 ────────────────────────────────────────
617-
async function pickFileOrFolder() {
618-
const selection = await window.api.files.pickFileOrFolder()
619-
if (selection) applyPathSelection(selection.path, selection.isDirectory)
625+
async function pickFile() {
626+
const path = await window.api.files.pickFile()
627+
if (path) applyPathSelection(path, false)
628+
}
629+
630+
async function pickFolder() {
631+
const path = await window.api.files.pickFolder()
632+
if (path) applyPathSelection(path, true)
620633
}
621634
622635
function onDrop(e: DragEvent) {
@@ -721,7 +734,6 @@ async function submitWebpage() {
721734
}
722735
}
723736
724-
// ── 文件夹操作 ──────────────────────────────────────────
725737
// ── 扫描目录操作 ────────────────────────────────────────
726738
async function pickScanDir() {
727739
const path = await window.api.files.pickFolder()
@@ -1111,6 +1123,11 @@ const scanDirIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor
11111123
color: var(--text-3);
11121124
}
11131125
1126+
.file-choice-actions { display: flex; gap: 8px; margin-top: 4px; }
1127+
.file-choice-btn { display: inline-flex; align-items: center; gap: 5px; padding: 6px 9px; border: 1px solid var(--border); border-radius: 5px; background: var(--surface-2); color: var(--text-2); font: inherit; font-size: 12px; cursor: pointer; }
1128+
.file-choice-btn:hover { border-color: var(--accent); color: var(--text); }
1129+
.file-choice-btn :deep(svg) { width: 14px; height: 14px; }
1130+
11141131
.spinner {
11151132
width: 24px;
11161133
height: 24px;

app/frontend/src/i18n/locales/en.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,8 @@ export default {
739739
or: 'or',
740740
orBrowse: 'or click to browse',
741741
dragHint: 'Drag a file or folder here',
742+
chooseFile: 'Choose file',
743+
chooseFolder: 'Choose folder',
742744
titlePlaceholder: 'Resource name...',
743745
notePlaceholder: 'Optional note...',
744746
descLabel: 'Description',

app/frontend/src/i18n/locales/zh.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,8 @@ export default {
739739
or: '或',
740740
orBrowse: '或点击浏览',
741741
dragHint: '拖入文件或文件夹到此处',
742+
chooseFile: '选择文件',
743+
chooseFolder: '选择文件夹',
742744
titlePlaceholder: '资源名称...',
743745
notePlaceholder: '可选的备注描述...',
744746
descLabel: '描述',

app/frontend/src/types/api.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ declare global {
6767
getAppIcon: (filePath: string) => Promise<string | null>
6868
saveCover: (resourceId: string, dataUrl: string, userPicked?: boolean) => Promise<string | null>
6969
pickFile: () => Promise<string | null>
70-
pickFileOrFolder: () => Promise<{ path: string; isDirectory: boolean } | null>
7170
pickImage: () => Promise<string | null>
7271
pickFolder: () => Promise<string | null>
7372
pickMultipleFiles: () => Promise<string[] | null>

app/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ai-cubby",
3-
"version": "0.4.20-beta.3",
3+
"version": "0.4.20-beta.4",
44
"description": "AI小抽屉 - 本地资源自动入库与AI标签",
55
"main": "out/main/main.js",
66
"scripts": {

app/scripts/test-default.mjs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -409,13 +409,12 @@ test('document category can create managed notes and profile documents', () => {
409409
assert.match(addModal, /class="document-create-body"/)
410410
assert.match(addModal, /window\.api\.documents\.create/)
411411
assert.match(addModal, /emit\('document-created'/)
412-
assert.match(ipc, /ipcMain\.handle\('files:pickFileOrFolder'/)
413-
assert.match(ipc, /properties: \['openFile', 'openDirectory'\]/)
414-
assert.match(preload, /pickFileOrFolder: \(\): Promise<\{ path: string; isDirectory: boolean \} \| null>/)
415-
assert.match(apiTypes, /pickFileOrFolder: \(\) => Promise<\{ path: string; isDirectory: boolean \} \| null>/)
416412
assert.match(addModal, /key: 'file' as const,\s+label: t\('addModal\.tabs\.fileOrFolder'\)/)
417-
assert.match(addModal, /window\.api\.files\.pickFileOrFolder\(\)/)
418-
assert.match(addModal, /applyPathSelection\(selection\.path, selection\.isDirectory\)/)
413+
assert.match(addModal, /window\.api\.files\.pickFile\(\)/)
414+
assert.match(addModal, /window\.api\.files\.pickFolder\(\)/)
415+
assert.match(addModal, /applyPathSelection\(path, false\)/)
416+
assert.match(addModal, /applyPathSelection\(path, true\)/)
417+
assert.doesNotMatch(ipc, /files:pickFileOrFolder/)
419418
assert.doesNotMatch(addModal, /key: 'folder' as const/)
420419
assert.doesNotMatch(addModal, /key: 'scan-sys' as const/)
421420
assert.doesNotMatch(addModal, /doSystemScan/)

0 commit comments

Comments
 (0)