파일 이름 변경 내용에 접미사 추가
This commit is contained in:
@@ -92,9 +92,10 @@ function register() {
|
|||||||
return { restored, errors };
|
return { restored, errors };
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('rename-files', async (_event, { folderPath, files, prefix, digits }) => {
|
ipcMain.handle('rename-files', async (_event, { folderPath, files, prefix, digits, postfix = '' }) => {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
const pad = (n) => String(n + 1).padStart(digits, '0');
|
const pad = (n) => String(n + 1).padStart(digits, '0');
|
||||||
|
const suffix = postfix ? `_${postfix}` : '';
|
||||||
|
|
||||||
// 1단계: 임시 이름으로 이동 (충돌 방지)
|
// 1단계: 임시 이름으로 이동 (충돌 방지)
|
||||||
const tmpMap = [];
|
const tmpMap = [];
|
||||||
@@ -113,7 +114,7 @@ function register() {
|
|||||||
// 2단계: 최종 이름으로 이동
|
// 2단계: 최종 이름으로 이동
|
||||||
const renamed = [];
|
const renamed = [];
|
||||||
for (const { tmp, ext, idx } of tmpMap) {
|
for (const { tmp, ext, idx } of tmpMap) {
|
||||||
const newName = `${prefix}_${pad(idx)}${ext}`;
|
const newName = `${prefix}_${pad(idx)}${suffix}${ext}`;
|
||||||
const dest = path.join(folderPath, newName);
|
const dest = path.join(folderPath, newName);
|
||||||
try {
|
try {
|
||||||
fs.renameSync(tmp, dest);
|
fs.renameSync(tmp, dest);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const fileCount = document.getElementById('file-count');
|
|||||||
const selCount = document.getElementById('sel-count');
|
const selCount = document.getElementById('sel-count');
|
||||||
const inputPrefix = document.getElementById('input-prefix');
|
const inputPrefix = document.getElementById('input-prefix');
|
||||||
const inputDigits = document.getElementById('input-digits');
|
const inputDigits = document.getElementById('input-digits');
|
||||||
|
const inputPostfix = document.getElementById('input-postfix');
|
||||||
|
|
||||||
let _cardObserver = null;
|
let _cardObserver = null;
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ export function updateNumberBadges() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function updateNewNameLabels() {
|
export function updateNewNameLabels() {
|
||||||
const format = getNameFormat(inputPrefix, inputDigits);
|
const format = getNameFormat(inputPrefix, inputDigits, 3, inputPostfix);
|
||||||
Array.from(grid.children).forEach((card, i) => {
|
Array.from(grid.children).forEach((card, i) => {
|
||||||
const el = card.querySelector('.card-new-name');
|
const el = card.querySelector('.card-new-name');
|
||||||
const file = state.files[i];
|
const file = state.files[i];
|
||||||
|
|||||||
@@ -45,6 +45,8 @@
|
|||||||
<span class="format-sep">_</span>
|
<span class="format-sep">_</span>
|
||||||
<input type="number" id="input-digits" value="4" min="1" max="6" />
|
<input type="number" id="input-digits" value="4" min="1" max="6" />
|
||||||
<span class="format-sep">자리 순번</span>
|
<span class="format-sep">자리 순번</span>
|
||||||
|
<span class="format-sep">_</span>
|
||||||
|
<input type="text" id="input-postfix" maxlength="3" size="3" placeholder="접미사" />
|
||||||
<span class="format-arrow">→</span>
|
<span class="format-arrow">→</span>
|
||||||
<span id="preview-name">photo_001.jpg</span>
|
<span id="preview-name">photo_001.jpg</span>
|
||||||
<span id="sel-count"></span>
|
<span id="sel-count"></span>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { buildSequentialName, getNameFormat } from './utils/file-name
|
|||||||
|
|
||||||
const inputPrefix = document.getElementById('input-prefix');
|
const inputPrefix = document.getElementById('input-prefix');
|
||||||
const inputDigits = document.getElementById('input-digits');
|
const inputDigits = document.getElementById('input-digits');
|
||||||
|
const inputPostfix = document.getElementById('input-postfix');
|
||||||
const renameConfirmModal = document.getElementById('rename-confirm-modal');
|
const renameConfirmModal = document.getElementById('rename-confirm-modal');
|
||||||
const renameConfirmSelectedTitle = renameConfirmModal.querySelector('.rename-title-selected');
|
const renameConfirmSelectedTitle = renameConfirmModal.querySelector('.rename-title-selected');
|
||||||
const renameConfirmAllTitle = renameConfirmModal.querySelector('.rename-title-all');
|
const renameConfirmAllTitle = renameConfirmModal.querySelector('.rename-title-all');
|
||||||
@@ -30,8 +31,8 @@ renameConfirmModal.addEventListener('modal:closed', () => {
|
|||||||
|
|
||||||
export async function doRename() {
|
export async function doRename() {
|
||||||
if (!state.files.length || !state.currentFolder) return;
|
if (!state.files.length || !state.currentFolder) return;
|
||||||
const { prefix, digits } = getNameFormat(inputPrefix, inputDigits);
|
const { prefix, digits, postfix } = getNameFormat(inputPrefix, inputDigits, 3, inputPostfix);
|
||||||
const format = { prefix, digits };
|
const format = { prefix, digits, postfix };
|
||||||
|
|
||||||
const selectedArr = [...state.selectedIdxs].sort((a, b) => a - b);
|
const selectedArr = [...state.selectedIdxs].sort((a, b) => a - b);
|
||||||
const filesToRename = selectedArr.length > 0
|
const filesToRename = selectedArr.length > 0
|
||||||
@@ -75,6 +76,7 @@ export async function doRename() {
|
|||||||
files: filesToRename,
|
files: filesToRename,
|
||||||
prefix,
|
prefix,
|
||||||
digits,
|
digits,
|
||||||
|
postfix,
|
||||||
});
|
});
|
||||||
hideLoading();
|
hideLoading();
|
||||||
if (result.errors.length) {
|
if (result.errors.length) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const btnSortDate = document.getElementById('btn-sort-date');
|
|||||||
const btnRename = document.getElementById('btn-rename');
|
const btnRename = document.getElementById('btn-rename');
|
||||||
const inputPrefix = document.getElementById('input-prefix');
|
const inputPrefix = document.getElementById('input-prefix');
|
||||||
const inputDigits = document.getElementById('input-digits');
|
const inputDigits = document.getElementById('input-digits');
|
||||||
|
const inputPostfix = document.getElementById('input-postfix');
|
||||||
const previewName = document.getElementById('preview-name');
|
const previewName = document.getElementById('preview-name');
|
||||||
const dirPath = document.getElementById('dir-path');
|
const dirPath = document.getElementById('dir-path');
|
||||||
const rubberBand = document.getElementById('rubber-band');
|
const rubberBand = document.getElementById('rubber-band');
|
||||||
@@ -113,6 +114,7 @@ window.api.onFullscreenChange((isFullscreen) => {
|
|||||||
// ── 버튼 / 키보드 이벤트 ─────────────────────────
|
// ── 버튼 / 키보드 이벤트 ─────────────────────────
|
||||||
inputPrefix.addEventListener('input', updatePreview);
|
inputPrefix.addEventListener('input', updatePreview);
|
||||||
inputDigits.addEventListener('input', updatePreview);
|
inputDigits.addEventListener('input', updatePreview);
|
||||||
|
inputPostfix.addEventListener('input', updatePreview);
|
||||||
btnOpen.addEventListener('click', () => {
|
btnOpen.addEventListener('click', () => {
|
||||||
log('ui', 'open button clicked');
|
log('ui', 'open button clicked');
|
||||||
folderController.openFolder();
|
folderController.openFolder();
|
||||||
@@ -146,7 +148,9 @@ initKeyboardShortcuts({
|
|||||||
function updatePreview() {
|
function updatePreview() {
|
||||||
const prefix = inputPrefix.value.trim() || 'photo';
|
const prefix = inputPrefix.value.trim() || 'photo';
|
||||||
const digits = clampDigits(inputDigits.value);
|
const digits = clampDigits(inputDigits.value);
|
||||||
|
const postfix = inputPostfix.value.trim();
|
||||||
const ext = state.files.length ? getExtension(state.files[0].name) : 'jpg';
|
const ext = state.files.length ? getExtension(state.files[0].name) : 'jpg';
|
||||||
previewName.textContent = `${prefix}_${'1'.padStart(digits, '0')}.${ext}`;
|
const suffix = postfix ? `_${postfix}` : '';
|
||||||
|
previewName.textContent = `${prefix}_${'1'.padStart(digits, '0')}${suffix}.${ext}`;
|
||||||
updateNewNameLabels();
|
updateNewNameLabels();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ main {
|
|||||||
#format-bar input:focus { border-color: var(--accent); }
|
#format-bar input:focus { border-color: var(--accent); }
|
||||||
#input-prefix { width: 160px; }
|
#input-prefix { width: 160px; }
|
||||||
#input-digits { width: 50px; text-align: center; }
|
#input-digits { width: 50px; text-align: center; }
|
||||||
|
#input-postfix { width: 54px; }
|
||||||
.format-sep { color: var(--muted); font-family: 'JetBrains Mono', monospace; font-size: 14px; }
|
.format-sep { color: var(--muted); font-family: 'JetBrains Mono', monospace; font-size: 14px; }
|
||||||
.format-arrow { color: var(--muted); font-size: 12px; }
|
.format-arrow { color: var(--muted); font-size: 12px; }
|
||||||
#preview-name {
|
#preview-name {
|
||||||
|
|||||||
@@ -7,14 +7,17 @@ export function clampDigits(value, fallback = 3) {
|
|||||||
return Math.max(1, Math.min(6, parseInt(value, 10) || fallback));
|
return Math.max(1, Math.min(6, parseInt(value, 10) || fallback));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildSequentialName(fileName, index, { prefix, digits }) {
|
export function buildSequentialName(fileName, index, { prefix, digits, postfix = '' }) {
|
||||||
const ext = getExtension(fileName);
|
const ext = getExtension(fileName);
|
||||||
return `${prefix}_${String(index + 1).padStart(digits, '0')}.${ext}`;
|
const sequence = `${prefix}_${String(index + 1).padStart(digits, '0')}`;
|
||||||
|
const suffix = postfix ? `_${postfix}` : '';
|
||||||
|
return `${sequence}${suffix}.${ext}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNameFormat(prefixInput, digitsInput, digitsFallback = 3) {
|
export function getNameFormat(prefixInput, digitsInput, digitsFallback = 3, postfixInput = null) {
|
||||||
return {
|
return {
|
||||||
prefix: prefixInput.value.trim() || 'photo',
|
prefix: prefixInput.value.trim() || 'photo',
|
||||||
digits: clampDigits(digitsInput.value, digitsFallback),
|
digits: clampDigits(digitsInput.value, digitsFallback),
|
||||||
|
postfix: postfixInput?.value.trim() || '',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user