mirror of
https://github.com/devon22/obsidian-gridexplorer.git
synced 2026-07-22 05:38:16 +00:00
3.4.11
This commit is contained in:
parent
f01a2cbf83
commit
9d81fd0f11
13 changed files with 283 additions and 251 deletions
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "gridexplorer",
|
||||
"name": "GridExplorer",
|
||||
"version": "3.4.10",
|
||||
"version": "3.4.11",
|
||||
"minAppVersion": "1.8.7",
|
||||
"description": "Browse note files in a grid view.",
|
||||
"author": "Devon22",
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "gridexplorer",
|
||||
"version": "3.4.10",
|
||||
"version": "3.4.11",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gridexplorer",
|
||||
"version": "3.4.10",
|
||||
"version": "3.4.11",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jszip": "^3.10.1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "gridexplorer",
|
||||
"version": "3.4.10",
|
||||
"version": "3.4.11",
|
||||
"description": "Browse note files in a grid view.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,190 @@ export class GridPreviewManager {
|
|||
}
|
||||
}
|
||||
|
||||
// 註冊預覽視窗的行動裝置滑動手勢(包含上下拖曳關閉與左右滑動切換歷史記錄)
|
||||
private registerPreviewTouchEvents(
|
||||
container: HTMLElement,
|
||||
scrollContainer: HTMLElement,
|
||||
onClose: () => void
|
||||
) {
|
||||
if (!Platform.isMobile) return;
|
||||
|
||||
container.setCssProps({ touchAction: 'pan-y' });
|
||||
|
||||
let startY = 0;
|
||||
let startX = 0;
|
||||
let currentY = 0;
|
||||
let currentX = 0;
|
||||
let isPullingUp = false;
|
||||
let isDragging = false;
|
||||
let isHorizontalDragging = false;
|
||||
let initialScrollTop = 0;
|
||||
let isAtTop = false;
|
||||
let isAtBottom = false;
|
||||
|
||||
const handleTouchStart = (e: TouchEvent) => {
|
||||
if (e.touches.length > 1) return;
|
||||
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.closest('input') || target.closest('textarea')) {
|
||||
return;
|
||||
}
|
||||
|
||||
initialScrollTop = scrollContainer.scrollTop;
|
||||
isAtTop = initialScrollTop <= 0;
|
||||
isAtBottom = initialScrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 1;
|
||||
|
||||
startY = e.touches[0].clientY;
|
||||
currentY = startY;
|
||||
startX = e.touches[0].clientX;
|
||||
currentX = startX;
|
||||
|
||||
isDragging = false;
|
||||
isPullingUp = false;
|
||||
isHorizontalDragging = false;
|
||||
};
|
||||
|
||||
const handleTouchMove = (e: TouchEvent) => {
|
||||
if (e.touches.length > 1) return;
|
||||
|
||||
currentY = e.touches[0].clientY;
|
||||
currentX = e.touches[0].clientX;
|
||||
const deltaY = currentY - startY;
|
||||
const deltaX = currentX - startX;
|
||||
|
||||
// 決定滑動方向
|
||||
if (!isDragging && !isHorizontalDragging) {
|
||||
const threshold = 10;
|
||||
if (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold) {
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
// 左右滑動
|
||||
const hasForwardHistory = this.previewHistoryIndex < this.previewHistory.length - 1;
|
||||
if (deltaX < 0 && !hasForwardHistory) {
|
||||
// 禁用該方向,不設為 dragging
|
||||
} else {
|
||||
isHorizontalDragging = true;
|
||||
container.setCssProps({ transition: 'none' });
|
||||
}
|
||||
} else {
|
||||
// 上下滑動 (原有拉動關閉功能)
|
||||
if (isAtTop || isAtBottom) {
|
||||
const pullDownStartThreshold = 24;
|
||||
const pullUpStartThreshold = 36;
|
||||
const canPullDown = isAtTop && deltaY > pullDownStartThreshold;
|
||||
const canPullUp = isAtBottom && deltaY < -pullUpStartThreshold;
|
||||
|
||||
if (canPullDown || canPullUp) {
|
||||
isDragging = true;
|
||||
isPullingUp = canPullUp && deltaY < 0;
|
||||
container.setCssProps({ transition: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 只有在進入我們自己定義的拖曳狀態時,才攔截事件與阻止預設行為
|
||||
if (isHorizontalDragging || isDragging) {
|
||||
e.stopPropagation();
|
||||
if (e.cancelable) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// 處理左右滑動視覺反饋
|
||||
if (isHorizontalDragging) {
|
||||
const hasForwardHistory = this.previewHistoryIndex < this.previewHistory.length - 1;
|
||||
let translateX = deltaX * 0.6;
|
||||
if (!hasForwardHistory && translateX < 0) {
|
||||
translateX = 0;
|
||||
}
|
||||
|
||||
if (translateX !== 0) {
|
||||
container.setCssProps({ transform: `translateX(${translateX}px)` });
|
||||
}
|
||||
}
|
||||
|
||||
// 處理上下滑動視覺反饋
|
||||
if (isDragging) {
|
||||
const resistance = 0.5;
|
||||
const translateY = deltaY * resistance;
|
||||
container.setCssProps({ transform: `translateY(${translateY}px)` });
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = (e: TouchEvent) => {
|
||||
if (isHorizontalDragging || isDragging) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
const deltaX = currentX - startX;
|
||||
const deltaY = currentY - startY;
|
||||
|
||||
if (isHorizontalDragging) {
|
||||
isHorizontalDragging = false;
|
||||
const swipeThreshold = 80;
|
||||
|
||||
const hasForwardHistory = this.previewHistoryIndex < this.previewHistory.length - 1;
|
||||
const isValidSwipe = !(deltaX < 0 && !hasForwardHistory);
|
||||
|
||||
if (isValidSwipe && Math.abs(deltaX) > swipeThreshold) {
|
||||
if (deltaX > 0) {
|
||||
void this.navigatePreviewBack();
|
||||
} else {
|
||||
void this.navigatePreviewForward();
|
||||
}
|
||||
container.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
} else {
|
||||
container.setCssProps({
|
||||
transition: 'transform 0.3s ease-out',
|
||||
transform: 'translateX(0)',
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
container.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}, 300);
|
||||
}
|
||||
} else if (isDragging) {
|
||||
isDragging = false;
|
||||
|
||||
const closeThreshold = isPullingUp ? 170 : 110;
|
||||
if ((!isPullingUp && deltaY > closeThreshold) || (isPullingUp && deltaY < -closeThreshold)) {
|
||||
const targetY = isPullingUp ? '-100vh' : '100vh';
|
||||
container.setCssProps({
|
||||
transition: 'transform 0.2s ease-out',
|
||||
transform: `translateY(${targetY})`,
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
onClose();
|
||||
container.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}, 200);
|
||||
} else {
|
||||
container.setCssProps({
|
||||
transition: 'transform 0.3s ease-out',
|
||||
transform: 'translateY(0)',
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
container.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
container.addEventListener('touchstart', handleTouchStart, { capture: true, passive: false });
|
||||
container.addEventListener('touchmove', handleTouchMove, { capture: true, passive: false });
|
||||
container.addEventListener('touchend', handleTouchEnd, { capture: true });
|
||||
}
|
||||
|
||||
// 在網格視圖中直接顯示筆記
|
||||
async showNoteInGrid(file: TFile, isHistoryNavigation = false) {
|
||||
|
|
@ -444,124 +627,8 @@ export class GridPreviewManager {
|
|||
await this.renderLinksSection(file, noteContent);
|
||||
|
||||
|
||||
// 行動裝置下拉或上拉關閉筆記
|
||||
if (Platform.isMobile && noteViewContainer) {
|
||||
let startY = 0;
|
||||
let startX = 0;
|
||||
let currentY = 0;
|
||||
let isPulling = false;
|
||||
let isPullingUp = false;
|
||||
let isDragging = false;
|
||||
let initialScrollTop = 0;
|
||||
let isAtTop = false;
|
||||
let isAtBottom = false;
|
||||
|
||||
const handleTouchStart = (e: TouchEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.closest('button') || target.closest('a') || target.closest('input') || target.closest('textarea')) {
|
||||
return;
|
||||
}
|
||||
|
||||
initialScrollTop = scrollContainer.scrollTop;
|
||||
isAtTop = initialScrollTop <= 0;
|
||||
isAtBottom = initialScrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 1;
|
||||
|
||||
if (isAtTop || isAtBottom) {
|
||||
startY = e.touches[0].clientY;
|
||||
currentY = startY;
|
||||
startX = e.touches[0].clientX;
|
||||
isPulling = true;
|
||||
isDragging = false;
|
||||
isPullingUp = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchMove = (e: TouchEvent) => {
|
||||
if (!isPulling || !noteViewContainer) return;
|
||||
|
||||
currentY = e.touches[0].clientY;
|
||||
const currentX = e.touches[0].clientX;
|
||||
const deltaY = currentY - startY;
|
||||
const deltaX = currentX - startX;
|
||||
|
||||
if (!isDragging) {
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
isPulling = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const pullDownStartThreshold = 24;
|
||||
const pullUpStartThreshold = 36;
|
||||
const canPullDown = isAtTop && deltaY > pullDownStartThreshold;
|
||||
const canPullUp = isAtBottom && deltaY < -pullUpStartThreshold;
|
||||
|
||||
if (canPullDown || canPullUp) {
|
||||
isDragging = true;
|
||||
isPullingUp = canPullUp && deltaY < 0;
|
||||
if (noteViewContainer) {
|
||||
noteViewContainer.setCssProps({ transition: 'none' });
|
||||
}
|
||||
} else if ((isAtTop && !isAtBottom && deltaY < 0) || (isAtBottom && !isAtTop && deltaY > 0)) {
|
||||
isPulling = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDragging) {
|
||||
if (e.cancelable) {
|
||||
e.preventDefault();
|
||||
}
|
||||
const resistance = 0.5;
|
||||
const translateY = deltaY * resistance;
|
||||
noteViewContainer.setCssProps({ transform: `translateY(${translateY}px)` });
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
if (!isPulling || !noteViewContainer) return;
|
||||
isPulling = false;
|
||||
|
||||
if (!isDragging) return;
|
||||
isDragging = false;
|
||||
|
||||
const deltaY = currentY - startY;
|
||||
|
||||
const closeThreshold = isPullingUp ? 170 : 110;
|
||||
if ((!isPullingUp && deltaY > closeThreshold) || (isPullingUp && deltaY < -closeThreshold)) {
|
||||
const targetY = isPullingUp ? '-100vh' : '100vh';
|
||||
noteViewContainer.setCssProps({
|
||||
transition: 'transform 0.2s ease-out',
|
||||
transform: `translateY(${targetY})`,
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
this.hideNoteInGrid();
|
||||
if (noteViewContainer) {
|
||||
noteViewContainer.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}
|
||||
}, 200);
|
||||
} else {
|
||||
noteViewContainer.setCssProps({
|
||||
transition: 'transform 0.3s ease-out',
|
||||
transform: 'translateY(0)',
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
if (noteViewContainer) {
|
||||
noteViewContainer.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
noteViewContainer.addEventListener('touchstart', handleTouchStart, { passive: true });
|
||||
noteViewContainer.addEventListener('touchmove', handleTouchMove, { passive: false });
|
||||
noteViewContainer.addEventListener('touchend', handleTouchEnd);
|
||||
}
|
||||
// 註冊行動裝置滑動手勢
|
||||
this.registerPreviewTouchEvents(noteViewContainer, scrollContainer, () => this.hideNoteInGrid());
|
||||
|
||||
// 設定狀態
|
||||
this.view.isShowingNote = true;
|
||||
|
|
@ -866,124 +933,8 @@ export class GridPreviewManager {
|
|||
console.error('Error loading ZIP content in grid:', error);
|
||||
}
|
||||
|
||||
// 行動裝置下拉關閉
|
||||
if (Platform.isMobile && zipViewContainer) {
|
||||
let startY = 0;
|
||||
let startX = 0;
|
||||
let currentY = 0;
|
||||
let isPulling = false;
|
||||
let isPullingUp = false;
|
||||
let isDragging = false;
|
||||
let initialScrollTop = 0;
|
||||
let isAtTop = false;
|
||||
let isAtBottom = false;
|
||||
|
||||
const handleTouchStart = (e: TouchEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.closest('button') || target.closest('a') || target.closest('input') || target.closest('textarea')) {
|
||||
return;
|
||||
}
|
||||
|
||||
initialScrollTop = scrollContainer.scrollTop;
|
||||
isAtTop = initialScrollTop <= 0;
|
||||
isAtBottom = initialScrollTop + scrollContainer.clientHeight >= scrollContainer.scrollHeight - 1;
|
||||
|
||||
if (isAtTop || isAtBottom) {
|
||||
startY = e.touches[0].clientY;
|
||||
currentY = startY;
|
||||
startX = e.touches[0].clientX;
|
||||
isPulling = true;
|
||||
isDragging = false;
|
||||
isPullingUp = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchMove = (e: TouchEvent) => {
|
||||
if (!isPulling || !zipViewContainer) return;
|
||||
|
||||
currentY = e.touches[0].clientY;
|
||||
const currentX = e.touches[0].clientX;
|
||||
const deltaY = currentY - startY;
|
||||
const deltaX = currentX - startX;
|
||||
|
||||
if (!isDragging) {
|
||||
if (Math.abs(deltaX) > Math.abs(deltaY)) {
|
||||
isPulling = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const pullDownStartThreshold = 24;
|
||||
const pullUpStartThreshold = 36;
|
||||
const canPullDown = isAtTop && deltaY > pullDownStartThreshold;
|
||||
const canPullUp = isAtBottom && deltaY < -pullUpStartThreshold;
|
||||
|
||||
if (canPullDown || canPullUp) {
|
||||
isDragging = true;
|
||||
isPullingUp = canPullUp && deltaY < 0;
|
||||
if (zipViewContainer) {
|
||||
zipViewContainer.setCssProps({ transition: 'none' });
|
||||
}
|
||||
} else if ((isAtTop && !isAtBottom && deltaY < 0) || (isAtBottom && !isAtTop && deltaY > 0)) {
|
||||
isPulling = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDragging) {
|
||||
if (e.cancelable) {
|
||||
e.preventDefault();
|
||||
}
|
||||
const resistance = 0.5;
|
||||
const translateY = deltaY * resistance;
|
||||
zipViewContainer.setCssProps({ transform: `translateY(${translateY}px)` });
|
||||
}
|
||||
};
|
||||
|
||||
const handleTouchEnd = () => {
|
||||
if (!isPulling || !zipViewContainer) return;
|
||||
isPulling = false;
|
||||
|
||||
if (!isDragging) return;
|
||||
isDragging = false;
|
||||
|
||||
const deltaY = currentY - startY;
|
||||
|
||||
const closeThreshold = isPullingUp ? 170 : 110;
|
||||
if ((!isPullingUp && deltaY > closeThreshold) || (isPullingUp && deltaY < -closeThreshold)) {
|
||||
const targetY = isPullingUp ? '-100vh' : '100vh';
|
||||
zipViewContainer.setCssProps({
|
||||
transition: 'transform 0.2s ease-out',
|
||||
transform: `translateY(${targetY})`,
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
this.hideZipInGrid();
|
||||
if (zipViewContainer) {
|
||||
zipViewContainer.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}
|
||||
}, 200);
|
||||
} else {
|
||||
zipViewContainer.setCssProps({
|
||||
transition: 'transform 0.3s ease-out',
|
||||
transform: 'translateY(0)',
|
||||
});
|
||||
window.setTimeout(() => {
|
||||
if (zipViewContainer) {
|
||||
zipViewContainer.setCssProps({
|
||||
transform: '',
|
||||
transition: '',
|
||||
});
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
zipViewContainer.addEventListener('touchstart', handleTouchStart, { passive: true });
|
||||
zipViewContainer.addEventListener('touchmove', handleTouchMove, { passive: false });
|
||||
zipViewContainer.addEventListener('touchend', handleTouchEnd);
|
||||
}
|
||||
// 註冊行動裝置滑動手勢
|
||||
this.registerPreviewTouchEvents(zipViewContainer, scrollContainer, () => this.hideZipInGrid());
|
||||
|
||||
// 設定狀態
|
||||
this.view.isShowingZip = true;
|
||||
|
|
|
|||
|
|
@ -243,12 +243,12 @@ export class GridView extends ItemView {
|
|||
if (this.app.workspace.getActiveViewOfType(GridView) !== this) return;
|
||||
// 有 modal 時不處理
|
||||
if (activeDocument.querySelector('.modal-container')) return;
|
||||
|
||||
|
||||
// 阻止內建快捷鍵與其他監聽器
|
||||
event.preventDefault();
|
||||
// 停止後續所有監聽器(包含 Obsidian 內建 hotkey)
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
|
||||
if (this.isShowingNote || this.isShowingZip) {
|
||||
void this.previewManager.navigatePreviewBack();
|
||||
} else {
|
||||
|
|
@ -260,12 +260,12 @@ export class GridView extends ItemView {
|
|||
if (this.app.workspace.getActiveViewOfType(GridView) !== this) return;
|
||||
// 有 modal 時不處理
|
||||
if (activeDocument.querySelector('.modal-container')) return;
|
||||
|
||||
|
||||
// 阻止內建快捷鍵與其他監聽器
|
||||
event.preventDefault();
|
||||
// 停止後續所有監聽器(包含 Obsidian 內建 hotkey)
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
|
||||
if (this.isShowingNote || this.isShowingZip) {
|
||||
void this.previewManager.navigatePreviewForward();
|
||||
} else {
|
||||
|
|
@ -277,7 +277,7 @@ export class GridView extends ItemView {
|
|||
if (this.app.workspace.getActiveViewOfType(GridView) !== this) return;
|
||||
// 有 modal 時不處理
|
||||
if (activeDocument.querySelector('.modal-container')) return;
|
||||
|
||||
|
||||
// 若正在顯示預覽,則關閉預覽
|
||||
if (this.isShowingNote || this.isShowingZip) {
|
||||
event.preventDefault();
|
||||
|
|
@ -325,6 +325,80 @@ export class GridView extends ItemView {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
// 監聽外部檔案拖曳進來並複製到目前資料夾
|
||||
this.registerDomEvent(this.containerEl, 'dragover', (event: DragEvent) => {
|
||||
if (this.sourceMode === 'folder') {
|
||||
const types = event.dataTransfer?.types || [];
|
||||
// 確保為外部系統檔案拖曳,排除內部元素拖曳 (內部拖曳通常含有 text/html 或 text/plain)
|
||||
const isExternalFile = types.includes('Files') && !types.includes('text/html') && !types.includes('text/plain');
|
||||
if (isExternalFile) {
|
||||
event.preventDefault();
|
||||
if (event.dataTransfer) event.dataTransfer.dropEffect = 'copy';
|
||||
this.containerEl.addClass('ge-dragover');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.registerDomEvent(this.containerEl, 'dragleave', () => {
|
||||
this.containerEl.removeClass('ge-dragover');
|
||||
});
|
||||
|
||||
this.registerDomEvent(this.containerEl, 'drop', async (event: DragEvent) => {
|
||||
if (this.sourceMode !== 'folder') return;
|
||||
this.containerEl.removeClass('ge-dragover');
|
||||
|
||||
if (!event.dataTransfer) return;
|
||||
|
||||
const types = event.dataTransfer.types || [];
|
||||
const isExternalFile = types.includes('Files') && !types.includes('text/html') && !types.includes('text/plain');
|
||||
|
||||
// 如果不是外部檔案,直接返回(交給其他已經寫好搬移邏輯的處理器處理,不攔截)
|
||||
if (!isExternalFile) return;
|
||||
|
||||
// 處理外部檔案的複製匯入 (Copy/Import)
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const files = event.dataTransfer.files;
|
||||
if (!files || files.length === 0) return;
|
||||
|
||||
let importedCount = 0;
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
const file = files[i];
|
||||
try {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
|
||||
// 處理檔名重複
|
||||
let baseName = file.name;
|
||||
let extension = '';
|
||||
const lastDotIndex = file.name.lastIndexOf('.');
|
||||
if (lastDotIndex !== -1) {
|
||||
baseName = file.name.substring(0, lastDotIndex);
|
||||
extension = file.name.substring(lastDotIndex);
|
||||
}
|
||||
|
||||
let targetPath = normalizePath(`${this.sourcePath}/${file.name}`);
|
||||
let counter = 1;
|
||||
while (this.app.vault.getAbstractFileByPath(targetPath)) {
|
||||
targetPath = normalizePath(`${this.sourcePath}/${baseName}_${counter}${extension}`);
|
||||
counter++;
|
||||
}
|
||||
|
||||
await this.app.vault.createBinary(targetPath, arrayBuffer);
|
||||
importedCount++;
|
||||
} catch (err) {
|
||||
console.error(`GridExplorer: Failed to import file ${file.name}`, err);
|
||||
new Notice(t('import_fail_notice'));
|
||||
}
|
||||
}
|
||||
|
||||
if (importedCount > 0) {
|
||||
if (!this.fileWatcher) {
|
||||
await this.render();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getViewType() {
|
||||
|
|
@ -2162,7 +2236,7 @@ export class GridView extends ItemView {
|
|||
} else {
|
||||
copyPath = `${f.basename} 1.${f.extension}`;
|
||||
}
|
||||
|
||||
|
||||
let counter = 1;
|
||||
while (this.app.vault.getAbstractFileByPath(copyPath)) {
|
||||
counter++;
|
||||
|
|
@ -2172,7 +2246,7 @@ export class GridView extends ItemView {
|
|||
copyPath = `${f.basename} ${counter}.${f.extension}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
await this.app.vault.copy(f, copyPath);
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -332,4 +332,5 @@ export default {
|
|||
'save_stash_as_markdown': 'Save stash as Markdown',
|
||||
'add_to_stash': 'Add to stash',
|
||||
'added_to_stash': 'Added to stash',
|
||||
'import_fail_notice': 'Import failed',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,4 +331,5 @@ export default {
|
|||
'save_stash_as_markdown': '一時保存をMarkdownとして保存',
|
||||
'add_to_stash': '一時保存に追加',
|
||||
'added_to_stash': '一時保存に追加されました',
|
||||
'import_fail_notice': 'インポートに失敗しました',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -332,4 +332,5 @@ export default {
|
|||
'save_stash_as_markdown': '보관함을 Markdown으로 저장',
|
||||
'add_to_stash': '보관함에 추가',
|
||||
'added_to_stash': '보관함에 추가됨',
|
||||
'import_fail_notice': '가져오기 실패',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,4 +331,5 @@ export default {
|
|||
'save_stash_as_markdown': 'Сохранить хранилище как Markdown',
|
||||
'add_to_stash': 'Добавить в хранилище',
|
||||
'added_to_stash': 'Добавлено в хранилище',
|
||||
'import_fail_notice': 'Ошибка импорта',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,4 +331,5 @@ export default {
|
|||
'save_stash_as_markdown': 'Зберегти сховище як Markdown',
|
||||
'add_to_stash': 'Додати до сховища',
|
||||
'added_to_stash': 'Додано до сховища',
|
||||
'import_fail_notice': 'Помилка імпорту',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -332,4 +332,5 @@ export default {
|
|||
'save_stash_as_markdown': '將暫存區存為 Markdown',
|
||||
'add_to_stash': '加入暫存區',
|
||||
'added_to_stash': '已添加到暫存區',
|
||||
'import_fail_notice': '匯入失敗',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,4 +331,5 @@ export default {
|
|||
'save_stash_as_markdown': '将暂存区保存为 Markdown',
|
||||
'add_to_stash': '加入暂存区',
|
||||
'added_to_stash': '已添加到暂存区',
|
||||
'import_fail_notice': '导入失败',
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@
|
|||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.ge-grid-view-container .ge-grid-container .ge-grid-item:hover {
|
||||
body .ge-grid-view-container .ge-grid-container .ge-grid-item:hover {
|
||||
transform: translateY(-2px);
|
||||
background-color: var(--text-selection);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--interactive-accent) !important;
|
||||
border-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
.ge-grid-item:hover p {
|
||||
|
|
@ -3428,11 +3428,11 @@ a.ge-current-folder:hover {
|
|||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.ge-folder-button:hover {
|
||||
body .ge-folder-button:hover {
|
||||
background-color: var(--text-selection);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--interactive-accent) !important;
|
||||
border-color: var(--interactive-accent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue