diff --git a/src/main/ipc/files.js b/src/main/ipc/files.js
index be0b236..83ecd97 100644
--- a/src/main/ipc/files.js
+++ b/src/main/ipc/files.js
@@ -92,9 +92,10 @@ function register() {
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 pad = (n) => String(n + 1).padStart(digits, '0');
+ const suffix = postfix ? `_${postfix}` : '';
// 1단계: 임시 이름으로 이동 (충돌 방지)
const tmpMap = [];
@@ -113,7 +114,7 @@ function register() {
// 2단계: 최종 이름으로 이동
const renamed = [];
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);
try {
fs.renameSync(tmp, dest);
diff --git a/src/renderer/grid.js b/src/renderer/grid.js
index 53508e0..4084783 100644
--- a/src/renderer/grid.js
+++ b/src/renderer/grid.js
@@ -11,6 +11,7 @@ const fileCount = document.getElementById('file-count');
const selCount = document.getElementById('sel-count');
const inputPrefix = document.getElementById('input-prefix');
const inputDigits = document.getElementById('input-digits');
+const inputPostfix = document.getElementById('input-postfix');
let _cardObserver = null;
@@ -111,7 +112,7 @@ export function updateNumberBadges() {
}
export function updateNewNameLabels() {
- const format = getNameFormat(inputPrefix, inputDigits);
+ const format = getNameFormat(inputPrefix, inputDigits, 3, inputPostfix);
Array.from(grid.children).forEach((card, i) => {
const el = card.querySelector('.card-new-name');
const file = state.files[i];
diff --git a/src/renderer/index.html b/src/renderer/index.html
index 5575eea..5fba393 100644
--- a/src/renderer/index.html
+++ b/src/renderer/index.html
@@ -45,6 +45,8 @@
_
자리 순번
+ _
+
→
photo_001.jpg
diff --git a/src/renderer/rename.js b/src/renderer/rename.js
index a559643..df8c992 100644
--- a/src/renderer/rename.js
+++ b/src/renderer/rename.js
@@ -8,6 +8,7 @@ import { buildSequentialName, getNameFormat } from './utils/file-name
const inputPrefix = document.getElementById('input-prefix');
const inputDigits = document.getElementById('input-digits');
+const inputPostfix = document.getElementById('input-postfix');
const renameConfirmModal = document.getElementById('rename-confirm-modal');
const renameConfirmSelectedTitle = renameConfirmModal.querySelector('.rename-title-selected');
const renameConfirmAllTitle = renameConfirmModal.querySelector('.rename-title-all');
@@ -30,8 +31,8 @@ renameConfirmModal.addEventListener('modal:closed', () => {
export async function doRename() {
if (!state.files.length || !state.currentFolder) return;
- const { prefix, digits } = getNameFormat(inputPrefix, inputDigits);
- const format = { prefix, digits };
+ const { prefix, digits, postfix } = getNameFormat(inputPrefix, inputDigits, 3, inputPostfix);
+ const format = { prefix, digits, postfix };
const selectedArr = [...state.selectedIdxs].sort((a, b) => a - b);
const filesToRename = selectedArr.length > 0
@@ -75,6 +76,7 @@ export async function doRename() {
files: filesToRename,
prefix,
digits,
+ postfix,
});
hideLoading();
if (result.errors.length) {
diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js
index 45b6e0d..aebf236 100644
--- a/src/renderer/renderer.js
+++ b/src/renderer/renderer.js
@@ -27,6 +27,7 @@ const btnSortDate = document.getElementById('btn-sort-date');
const btnRename = document.getElementById('btn-rename');
const inputPrefix = document.getElementById('input-prefix');
const inputDigits = document.getElementById('input-digits');
+const inputPostfix = document.getElementById('input-postfix');
const previewName = document.getElementById('preview-name');
const dirPath = document.getElementById('dir-path');
const rubberBand = document.getElementById('rubber-band');
@@ -113,6 +114,7 @@ window.api.onFullscreenChange((isFullscreen) => {
// ── 버튼 / 키보드 이벤트 ─────────────────────────
inputPrefix.addEventListener('input', updatePreview);
inputDigits.addEventListener('input', updatePreview);
+inputPostfix.addEventListener('input', updatePreview);
btnOpen.addEventListener('click', () => {
log('ui', 'open button clicked');
folderController.openFolder();
@@ -146,7 +148,9 @@ initKeyboardShortcuts({
function updatePreview() {
const prefix = inputPrefix.value.trim() || 'photo';
const digits = clampDigits(inputDigits.value);
+ const postfix = inputPostfix.value.trim();
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();
}
diff --git a/src/renderer/style.css b/src/renderer/style.css
index 338063d..aab3083 100644
--- a/src/renderer/style.css
+++ b/src/renderer/style.css
@@ -216,6 +216,7 @@ main {
#format-bar input:focus { border-color: var(--accent); }
#input-prefix { width: 160px; }
#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-arrow { color: var(--muted); font-size: 12px; }
#preview-name {
diff --git a/src/renderer/utils/file-names.js b/src/renderer/utils/file-names.js
index 4458a7a..95e7096 100644
--- a/src/renderer/utils/file-names.js
+++ b/src/renderer/utils/file-names.js
@@ -7,14 +7,17 @@ export function clampDigits(value, fallback = 3) {
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);
- 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 {
prefix: prefixInput.value.trim() || 'photo',
digits: clampDigits(digitsInput.value, digitsFallback),
+ postfix: postfixInput?.value.trim() || '',
};
}