feat: add settings page and torrent drag-drop modal flow

This commit is contained in:
2026-02-24 00:59:28 +09:00
parent bba6b8de5c
commit 845d5ca65c

View File

@@ -17,6 +17,8 @@ import {
type TaskFilter = 'all' | 'active' | 'waiting' | 'stopped' type TaskFilter = 'all' | 'active' | 'waiting' | 'stopped'
type AddTab = 'url' | 'torrent' type AddTab = 'url' | 'torrent'
type AppPage = 'downloads' | 'settings'
type SettingsTab = 'basic' | 'advanced' | 'lab'
const binaryPath = ref('aria2c') const binaryPath = ref('aria2c')
const rpcPort = ref(6800) const rpcPort = ref(6800)
@@ -32,6 +34,24 @@ const errorMessage = ref('')
const successMessage = ref('') const successMessage = ref('')
const autoRefresh = ref(true) const autoRefresh = ref(true)
const filter = ref<TaskFilter>('all') const filter = ref<TaskFilter>('all')
const page = ref<AppPage>('downloads')
const settingsTab = ref<SettingsTab>('basic')
const settingTheme = ref<'auto' | 'light' | 'dark'>('dark')
const settingHideWindowOnStartup = ref(false)
const settingTraySpeed = ref(true)
const settingShowDockProgress = ref(true)
const settingLanguage = ref('한국어')
const settingRunOnLogin = ref(false)
const settingRememberWindow = ref(true)
const settingAutoResume = ref(true)
const settingUploadLimit = ref(256)
const settingDownloadLimit = ref(0)
const settingMagnetAsTorrent = ref(true)
const settingAutoDownloadTorrentMeta = ref(true)
const settingBtForceEncryption = ref(false)
const settingKeepSeeding = ref(true)
const settingSeedRatio = ref(1)
const showAddModal = ref(false) const showAddModal = ref(false)
const addTab = ref<AddTab>('url') const addTab = ref<AddTab>('url')
@@ -205,6 +225,18 @@ function openAddModal() {
addTab.value = 'url' addTab.value = 'url'
} }
function openDownloadsPage() {
page.value = 'downloads'
}
function openSettingsPage() {
page.value = 'settings'
}
function saveSettings() {
pushSuccess('설정이 저장되었습니다.')
}
function closeAddModal() { function closeAddModal() {
showAddModal.value = false showAddModal.value = false
modalDropActive.value = false modalDropActive.value = false
@@ -460,20 +492,25 @@ onUnmounted(() => {
<aside class="sidebar"> <aside class="sidebar">
<div class="brand">m</div> <div class="brand">m</div>
<div class="side-icons"> <div class="side-icons">
<button class="side-icon" title="목록"></button> <button class="side-icon" :class="{ active: page === 'downloads' }" title="목록" @click="openDownloadsPage">
</button>
<button class="side-icon add" title="새 작업" @click="openAddModal"></button> <button class="side-icon add" title="새 작업" @click="openAddModal"></button>
</div> </div>
<nav> <nav>
<a class="active">다운로드 </a> <a class="active" @click="openDownloadsPage">다운로드 </a>
<a>대기 </a> <a>대기 </a>
<a>중단됨</a> <a>중단됨</a>
</nav> </nav>
<div class="sidebar-foot"> <div class="sidebar-foot">
<button class="side-icon" title="설정"></button> <button class="side-icon" :class="{ active: page === 'settings' }" title="설정" @click="openSettingsPage">
</button>
<button class="side-icon" title="도움말">?</button>
</div> </div>
</aside> </aside>
<section class="content"> <section v-if="page === 'downloads'" class="content">
<header class="toolbar"> <header class="toolbar">
<div class="toolbar-left"> <div class="toolbar-left">
<h1>다운로드 </h1> <h1>다운로드 </h1>
@@ -587,6 +624,91 @@ onUnmounted(() => {
</section> </section>
</section> </section>
<section v-else class="content settings-content">
<section class="settings-layout">
<aside class="settings-nav card">
<h2>설정</h2>
<button :class="{ active: settingsTab === 'basic' }" @click="settingsTab = 'basic'">기본</button>
<button :class="{ active: settingsTab === 'advanced' }" @click="settingsTab = 'advanced'">고급</button>
<button :class="{ active: settingsTab === 'lab' }" @click="settingsTab = 'lab'">실험실</button>
</aside>
<article class="settings-panel card">
<h1>기본</h1>
<div v-if="settingsTab === 'basic'" class="settings-form">
<section class="settings-group">
<label>테마</label>
<div class="theme-row">
<button class="theme-tile" :class="{ active: settingTheme === 'auto' }" @click="settingTheme = 'auto'">자동</button>
<button class="theme-tile" :class="{ active: settingTheme === 'light' }" @click="settingTheme = 'light'">밝게</button>
<button class="theme-tile" :class="{ active: settingTheme === 'dark' }" @click="settingTheme = 'dark'">어둡게</button>
</div>
</section>
<section class="settings-group">
<label class="check-row"><input v-model="settingHideWindowOnStartup" type="checkbox" /> 자동으로 숨기기</label>
<label class="check-row"><input v-model="settingTraySpeed" type="checkbox" /> 메뉴 막대 트레이에 실시간 속도 표시</label>
<label class="check-row"><input v-model="settingShowDockProgress" type="checkbox" /> 다운로드 진행률 막대 보기</label>
</section>
<section class="settings-group two-col">
<label>언어
<select v-model="settingLanguage">
<option>한국어</option>
<option>English</option>
</select>
</label>
<label>분할
<input v-model.number="split" type="number" min="1" max="64" />
</label>
</section>
<section class="settings-group">
<label class="check-row"><input v-model="settingRunOnLogin" type="checkbox" /> 로그인 실행</label>
<label class="check-row"><input v-model="settingRememberWindow" type="checkbox" /> 크기 위치 기억</label>
<label class="check-row"><input v-model="settingAutoResume" type="checkbox" /> 완료되지 않은 작업 자동 재개</label>
</section>
<section class="settings-group">
<label>기본 폴더
<input v-model="downloadDir" type="text" />
</label>
</section>
<section class="settings-group two-col">
<label>업로드 제한 (KB/s)
<input v-model.number="settingUploadLimit" type="number" min="0" />
</label>
<label>다운로드 제한 (KB/s)
<input v-model.number="settingDownloadLimit" type="number" min="0" />
</label>
</section>
<section class="settings-group">
<h3>BitTorrent</h3>
<label class="check-row"><input v-model="settingMagnetAsTorrent" type="checkbox" /> 마그넷 링크를 토렌트 파일로 저장</label>
<label class="check-row"><input v-model="settingAutoDownloadTorrentMeta" type="checkbox" /> 마그넷 토렌트 내용 자동 다운로드</label>
<label class="check-row"><input v-model="settingBtForceEncryption" type="checkbox" /> BT 강제 암호화</label>
<label class="check-row"><input v-model="settingKeepSeeding" type="checkbox" /> 수동으로 멈출 때까지 계속 배포</label>
<label>배포 비율
<input v-model.number="settingSeedRatio" type="number" min="0" step="0.1" />
</label>
</section>
<div class="settings-actions">
<button @click="saveSettings">저장 적용</button>
<button class="ghost" @click="openDownloadsPage">취소</button>
</div>
</div>
<div v-else class="settings-placeholder">
<p>{{ settingsTab === 'advanced' ? '고급 설정 화면(포팅 진행 중)' : '실험실 설정 화면(포팅 진행 중)' }}</p>
</div>
</article>
</section>
</section>
<div v-if="showAddModal" class="modal-backdrop" @click.self="closeAddModal"> <div v-if="showAddModal" class="modal-backdrop" @click.self="closeAddModal">
<section class="add-modal"> <section class="add-modal">
<header class="modal-header"> <header class="modal-header">