feat: add settings page and torrent drag-drop modal flow
This commit is contained in:
130
src/App.vue
130
src/App.vue
@@ -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">
|
||||||
|
|||||||
Reference in New Issue
Block a user