add sorting
This commit is contained in:
+37
-7
@@ -1,15 +1,17 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, watch, computed, onBeforeUnmount } from "vue";
|
import { ref, watch, computed, onBeforeUnmount } from "vue";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
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
|
// App Einstellungen
|
||||||
const view = ref(loadView());
|
const view = ref(loadView());
|
||||||
|
const sort = ref(loadSort());
|
||||||
|
|
||||||
const MIN_BPM = 20;
|
const MIN_BPM = 20;
|
||||||
const MAX_BPM = 300;
|
const MAX_BPM = 300;
|
||||||
const STORAGE_KEY_PRESETS = "ClickPresets"
|
const STORAGE_KEY_PRESETS = "ClickPresets"
|
||||||
const STORAGE_KEY_VIEW = "ClickView"
|
const STORAGE_KEY_VIEW = "ClickView"
|
||||||
|
const STORAGE_KEY_SORT = "ClickSort"
|
||||||
|
|
||||||
// Reaktiver Zustand (für die UI)
|
// Reaktiver Zustand (für die UI)
|
||||||
const bpm = ref(120);
|
const bpm = ref(120);
|
||||||
@@ -163,8 +165,13 @@ function savePreset() {
|
|||||||
editPreset.value = null;
|
editPreset.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const sortedPresets = computed(() =>
|
const sortedPresets = computed(() => {
|
||||||
[...presets.value].sort((a, b) => a.tempo - b.tempo)
|
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
|
// 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;
|
view.value = val;
|
||||||
localStorage.setItem(STORAGE_KEY_VIEW, val);
|
localStorage.setItem(STORAGE_KEY_VIEW, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSort(val) {
|
||||||
|
sort.value = val;
|
||||||
|
localStorage.setItem(STORAGE_KEY_SORT, val);
|
||||||
|
}
|
||||||
|
|
||||||
// EXPORT / IMPORT
|
// EXPORT / IMPORT
|
||||||
function exportPresets() {
|
function exportPresets() {
|
||||||
const json = JSON.stringify(presets.value, null, 2);
|
const json = JSON.stringify(presets.value, null, 2);
|
||||||
@@ -279,7 +301,15 @@ watch(
|
|||||||
|
|
||||||
<main>
|
<main>
|
||||||
<div id="presets">
|
<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>
|
<h2 id="presetsMessage" v-if="presets.length == 0">No Presets defined</h2>
|
||||||
<div id="presetsItems" :class="{ list: view == 'list', grid: view == 'grid' }">
|
<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)">
|
<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>
|
||||||
<div class="grow"></div>
|
<div class="grow"></div>
|
||||||
<div class="right">
|
<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" />
|
<font-awesome-icon :icon="faList" size="xl" />
|
||||||
</button>
|
</button>
|
||||||
<button v-if="view == 'list'" @click="switchView('grid')">
|
<button v-if="view == 'list'" @click="setView('grid')">
|
||||||
<font-awesome-icon :icon="faGrip" size="xl" />
|
<font-awesome-icon :icon="faGrip" size="xl" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -90,6 +90,26 @@ button#stop {
|
|||||||
flex-grow: 1;
|
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 {
|
#presetsMessage {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user