From 038fa2ead4dd9c88b3a0c554dbfd62f9c378d6ee Mon Sep 17 00:00:00 2001 From: lgoose Date: Fri, 21 Aug 2026 01:08:17 +0200 Subject: [PATCH] feat(frontend): komponenty panelu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Widok rozbity na komponenty odpowiadające kafelkom pulpitu: - AppHeader, VoiceChannelPanel, PlayerPanel, AddTrackPanel - UploadsPanel wraz z UploadedFileRow współdzielonym z oknem modalnym - QueuePanel i QueueItem - przeciąganie, zmiana kolejności, limit odtworzeń - HistoryPanel, ModalShell, SettingsModal, UploadsLibraryModal, ToastHost Arkusz stylów przeniesiony ze static/style.css bez zmian w wyglądzie. Style, które app.js wstrzykiwał inline przy budowaniu HTML-a, przeniesione do klas współdzielonych i bloków scoped w komponentach. Poprawki bezpieczeństwa wynikające z przepisania: - Tytuły utworów i nazwy plików nie trafiają już do innerHTML. Poprzednia wersja składała wiersze kolejki, historii i listy plików ze stringów, więc tytuł zawierający znaczniki HTML był wstawiany do DOM bez escapowania. - Nazwy plików nie są już wklejane do atrybutów onclick z ręcznym escapowaniem apostrofu, które i tak nie obejmowało cudzysłowu. Zdarzenia podpina Vue, bez generowania kodu w stringach. Co-Authored-By: Claude Opus 5 --- frontend/src/App.vue | 54 +++++ {static => frontend/src/assets}/style.css | 55 +++++ frontend/src/components/AddTrackPanel.vue | 51 +++++ frontend/src/components/AppHeader.vue | 52 +++++ frontend/src/components/HistoryPanel.vue | 86 ++++++++ frontend/src/components/ModalShell.vue | 38 ++++ frontend/src/components/PlayerPanel.vue | 189 ++++++++++++++++++ frontend/src/components/QueueItem.vue | 170 ++++++++++++++++ frontend/src/components/QueuePanel.vue | 115 +++++++++++ frontend/src/components/SettingsModal.vue | 151 ++++++++++++++ frontend/src/components/ToastHost.vue | 36 ++++ frontend/src/components/UploadedFileRow.vue | 44 ++++ .../src/components/UploadsLibraryModal.vue | 47 +++++ frontend/src/components/UploadsPanel.vue | 94 +++++++++ frontend/src/components/VoiceChannelPanel.vue | 58 ++++++ frontend/src/main.ts | 5 + 16 files changed, 1245 insertions(+) create mode 100644 frontend/src/App.vue rename {static => frontend/src/assets}/style.css (94%) create mode 100644 frontend/src/components/AddTrackPanel.vue create mode 100644 frontend/src/components/AppHeader.vue create mode 100644 frontend/src/components/HistoryPanel.vue create mode 100644 frontend/src/components/ModalShell.vue create mode 100644 frontend/src/components/PlayerPanel.vue create mode 100644 frontend/src/components/QueueItem.vue create mode 100644 frontend/src/components/QueuePanel.vue create mode 100644 frontend/src/components/SettingsModal.vue create mode 100644 frontend/src/components/ToastHost.vue create mode 100644 frontend/src/components/UploadedFileRow.vue create mode 100644 frontend/src/components/UploadsLibraryModal.vue create mode 100644 frontend/src/components/UploadsPanel.vue create mode 100644 frontend/src/components/VoiceChannelPanel.vue create mode 100644 frontend/src/main.ts diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..e284b45 --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,54 @@ + + + diff --git a/static/style.css b/frontend/src/assets/style.css similarity index 94% rename from static/style.css rename to frontend/src/assets/style.css index 06eaca4..b08228b 100644 --- a/static/style.css +++ b/frontend/src/assets/style.css @@ -1114,3 +1114,58 @@ body { white-space: nowrap; display: block; } + +/* ========================================================================== + Klasy współdzielone przez komponenty Vue. + Zastępują style, które wcześniej były wstrzykiwane inline z JavaScriptu. + ========================================================================== */ + +.btn-block { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.btn-compact { + padding: 4px 10px; + font-size: 0.8rem; + display: flex; + align-items: center; + gap: 4px; +} + +.queue-track-meta { + font-size: 0.78rem; + color: var(--text-muted); + margin-top: 2px; +} + +/* Krótsze listy: baza plików i historia. */ +.queue-list-container.list-short { + max-height: 250px; +} + +.glass-card-subtle { + background: rgba(255, 255, 255, 0.03); + border: 1px solid var(--border-glass); + border-radius: 14px; +} + +/* Pasek przesyłania nie zna postępu, więc animujemy go w nieskończoność. */ +.progress-bar-fill.indeterminate { + width: 40%; + background: var(--primary); + animation: upload-slide 1.1s ease-in-out infinite; +} + +@keyframes upload-slide { + 0% { margin-left: 0; } + 50% { margin-left: 60%; } + 100% { margin-left: 0; } +} + +.main-header { + width: 100%; +} diff --git a/frontend/src/components/AddTrackPanel.vue b/frontend/src/components/AddTrackPanel.vue new file mode 100644 index 0000000..eb41ade --- /dev/null +++ b/frontend/src/components/AddTrackPanel.vue @@ -0,0 +1,51 @@ + + + diff --git a/frontend/src/components/AppHeader.vue b/frontend/src/components/AppHeader.vue new file mode 100644 index 0000000..4e68e43 --- /dev/null +++ b/frontend/src/components/AppHeader.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/frontend/src/components/HistoryPanel.vue b/frontend/src/components/HistoryPanel.vue new file mode 100644 index 0000000..31f7d1f --- /dev/null +++ b/frontend/src/components/HistoryPanel.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/frontend/src/components/ModalShell.vue b/frontend/src/components/ModalShell.vue new file mode 100644 index 0000000..634b3f4 --- /dev/null +++ b/frontend/src/components/ModalShell.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/frontend/src/components/PlayerPanel.vue b/frontend/src/components/PlayerPanel.vue new file mode 100644 index 0000000..8cf0bed --- /dev/null +++ b/frontend/src/components/PlayerPanel.vue @@ -0,0 +1,189 @@ + + + + + diff --git a/frontend/src/components/QueueItem.vue b/frontend/src/components/QueueItem.vue new file mode 100644 index 0000000..b264ee7 --- /dev/null +++ b/frontend/src/components/QueueItem.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/frontend/src/components/QueuePanel.vue b/frontend/src/components/QueuePanel.vue new file mode 100644 index 0000000..09e65e3 --- /dev/null +++ b/frontend/src/components/QueuePanel.vue @@ -0,0 +1,115 @@ + + + diff --git a/frontend/src/components/SettingsModal.vue b/frontend/src/components/SettingsModal.vue new file mode 100644 index 0000000..baf16a8 --- /dev/null +++ b/frontend/src/components/SettingsModal.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/frontend/src/components/ToastHost.vue b/frontend/src/components/ToastHost.vue new file mode 100644 index 0000000..28c3fe8 --- /dev/null +++ b/frontend/src/components/ToastHost.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/frontend/src/components/UploadedFileRow.vue b/frontend/src/components/UploadedFileRow.vue new file mode 100644 index 0000000..3eeafce --- /dev/null +++ b/frontend/src/components/UploadedFileRow.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/frontend/src/components/UploadsLibraryModal.vue b/frontend/src/components/UploadsLibraryModal.vue new file mode 100644 index 0000000..c24f460 --- /dev/null +++ b/frontend/src/components/UploadsLibraryModal.vue @@ -0,0 +1,47 @@ + + + diff --git a/frontend/src/components/UploadsPanel.vue b/frontend/src/components/UploadsPanel.vue new file mode 100644 index 0000000..58bd9ca --- /dev/null +++ b/frontend/src/components/UploadsPanel.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/frontend/src/components/VoiceChannelPanel.vue b/frontend/src/components/VoiceChannelPanel.vue new file mode 100644 index 0000000..d44b475 --- /dev/null +++ b/frontend/src/components/VoiceChannelPanel.vue @@ -0,0 +1,58 @@ + + + diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..a6377c0 --- /dev/null +++ b/frontend/src/main.ts @@ -0,0 +1,5 @@ +import { createApp } from 'vue' +import App from '@/App.vue' +import '@/assets/style.css' + +createApp(App).mount('#app')