add sorting

This commit is contained in:
Artem Anufrij
2026-10-08 23:33:30 +02:00
parent 120b38bf0e
commit 8d19e61ed2
2 changed files with 57 additions and 7 deletions
+37 -7
View File
@@ -1,15 +1,17 @@
<script setup>
import { ref, watch, computed, onBeforeUnmount } from "vue";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { faMinus, faPlus, faPlay, faStop, faTrash, faArrowDown, faList, faGrip, faDownload, faUpload, faCheck, faPen } from "@fortawesome/free-solid-svg-icons";
import { faMinus, faPlus, faPlay, faStop, faTrash, faArrowDown, faList, faGrip, faDownload, faUpload, faCheck, faPen, faArrowDownAZ, faArrowDown19 } from "@fortawesome/free-solid-svg-icons";
// App Einstellungen
const view = ref(loadView());
const sort = ref(loadSort());
const MIN_BPM = 20;
const MAX_BPM = 300;
const STORAGE_KEY_PRESETS = "ClickPresets"
const STORAGE_KEY_VIEW = "ClickView"
const STORAGE_KEY_SORT = "ClickSort"
// Reaktiver Zustand (für die UI)
const bpm = ref(120);
@@ -163,8 +165,13 @@ function savePreset() {
editPreset.value = null;
}
const sortedPresets = computed(() =>
[...presets.value].sort((a, b) => a.tempo - b.tempo)
const sortedPresets = computed(() => {
if (sort.value == "tempo") {
return [...presets.value].sort((a, b) => a.tempo - b.tempo)
} else {
return [...presets.value].sort((a, b) => a.title.localeCompare(b.title))
}
}
);
// App View
@@ -179,11 +186,26 @@ function loadView() {
}
}
function switchView(val) {
function loadSort() {
try {
const raw = localStorage.getItem(STORAGE_KEY_SORT);
return raw || "title";
} catch (error) {
console.error("View settings could not be loaded:", error);
return "title";
}
}
function setView(val) {
view.value = val;
localStorage.setItem(STORAGE_KEY_VIEW, val);
}
function setSort(val) {
sort.value = val;
localStorage.setItem(STORAGE_KEY_SORT, val);
}
// EXPORT / IMPORT
function exportPresets() {
const json = JSON.stringify(presets.value, null, 2);
@@ -279,7 +301,15 @@ watch(
<main>
<div id="presets">
<h1>Presets</h1>
<div id="presetsTitle" class="flex">
<button @click="setSort('title')" :class="{ active: sort == 'title' }">
<font-awesome-icon :icon="faArrowDownAZ" size="xl" />
</button>
<h1 class="grow">Presets</h1>
<button @click="setSort('tempo')" :class="{ active: sort == 'tempo' }">
<font-awesome-icon :icon="faArrowDown19" size="xl" />
</button>
</div>
<h2 id="presetsMessage" v-if="presets.length == 0">No Presets defined</h2>
<div id="presetsItems" :class="{ list: view == 'list', grid: view == 'grid' }">
<button v-for="preset in sortedPresets" :key="preset.id" class="presetItem" :class="{ selected: selectedPreset === preset }" @click="startPreset(preset)">
@@ -300,10 +330,10 @@ watch(
</div>
<div class="grow"></div>
<div class="right">
<button v-if="view == 'grid'" @click="switchView('list')">
<button v-if="view == 'grid'" @click="setView('list')">
<font-awesome-icon :icon="faList" size="xl" />
</button>
<button v-if="view == 'list'" @click="switchView('grid')">
<button v-if="view == 'list'" @click="setView('grid')">
<font-awesome-icon :icon="faGrip" size="xl" />
</button>
</div>
+20
View File
@@ -90,6 +90,26 @@ button#stop {
flex-grow: 1;
}
#presetsTitle {
width: 100%;
}
#presetsTitle h1 {
text-align: center;
}
#presetsTitle button {
margin: 16px;
height: 48px;
width: 48px;
background: transparent;
color: var(--light-gray)
}
#presetsTitle button.active {
color: var(--dark)
}
#presetsMessage {
flex-grow: 1;
align-content: center;