From 658e7cdbb76e3287cf7278831513f12c83a92cbd Mon Sep 17 00:00:00 2001 From: geoffrey45 Date: Sat, 12 Mar 2022 08:56:38 +0300 Subject: [PATCH] move global search input to a general location - create a global search store - create a half-baked context menu store - --- src/App.vue | 15 ++ src/assets/css/Search/Search.scss | 36 --- src/assets/css/global.scss | 7 +- src/components/AlbumView/Header.vue | 26 +- src/components/LeftSidebar/AlbumArt.vue | 9 + src/components/LeftSidebar/SongCard.vue | 2 +- .../RightSideBar/Recommendation.vue | 2 +- src/components/RightSideBar/Search.vue | 233 +++++++----------- src/components/RightSideBar/SearchInput.vue | 87 +++++++ src/components/RightSideBar/Tabs.vue | 27 +- src/components/Search/Filters.vue | 5 +- src/components/Search/Options.vue | 62 ++--- src/components/contextMenu.vue | 122 +++++++++ src/components/shared/SongItem.vue | 2 +- src/components/shared/TrackItem.vue | 2 +- src/composables/normalizeContextMenu.js | 34 +++ src/composables/perks.js | 3 + src/composables/searchMusic.js | 4 +- src/stores/context.js | 21 ++ src/stores/gsearch.js | 67 +++++ src/stores/tabs.js | 17 +- 21 files changed, 538 insertions(+), 245 deletions(-) create mode 100644 src/components/RightSideBar/SearchInput.vue create mode 100644 src/components/contextMenu.vue create mode 100644 src/composables/normalizeContextMenu.js create mode 100644 src/stores/context.js create mode 100644 src/stores/gsearch.js diff --git a/src/App.vue b/src/App.vue index a677adb1..27caaebf 100644 --- a/src/App.vue +++ b/src/App.vue @@ -16,6 +16,7 @@
+
@@ -35,10 +36,24 @@ import Main from "./components/RightSideBar/Main.vue"; import AlbumArt from "./components/LeftSidebar/AlbumArt.vue"; import NavBar from "./components/nav/NavBar.vue"; import Tabs from "./components/RightSideBar/Tabs.vue"; +import SearchInput from "./components/RightSideBar/SearchInput.vue"; +import useContextStore from "./stores/context.js"; + +const context_store = useContextStore(); const RightSideBar = Main; perks.readQueue(); const collapsed = ref(false); + +const app_dom = document.getElementById("app"); + +app_dom.addEventListener("click", (e) => { + const context_menu = perks.getElem("context-menu-visible", "class"); + console.log(e.target.offsetParent); + if (e.target.offsetParent != context_menu) { + context_store.hideContextMenu(); + } +}); diff --git a/src/components/LeftSidebar/SongCard.vue b/src/components/LeftSidebar/SongCard.vue index a346b937..fe319799 100644 --- a/src/components/LeftSidebar/SongCard.vue +++ b/src/components/LeftSidebar/SongCard.vue @@ -36,4 +36,4 @@ const props = defineProps({ }, }); const putCommas = perks.putCommas; - + \ No newline at end of file diff --git a/src/components/RightSideBar/Recommendation.vue b/src/components/RightSideBar/Recommendation.vue index 7eb7aa1a..fd06759c 100644 --- a/src/components/RightSideBar/Recommendation.vue +++ b/src/components/RightSideBar/Recommendation.vue @@ -37,7 +37,7 @@ export default { diff --git a/src/components/RightSideBar/Tabs.vue b/src/components/RightSideBar/Tabs.vue index b6846c03..86ab596b 100644 --- a/src/components/RightSideBar/Tabs.vue +++ b/src/components/RightSideBar/Tabs.vue @@ -5,9 +5,11 @@ v-for="tab in tabs.tabs" @click="tabs.changeTab(tab)" :key="tab" - class="image t-item" - :class="({ active_tab: tabs.current === tab }, `${tab}`)" - >
+ class="container" + :class="{ active_tab: tabs.current === tab }" + > +
+ @@ -15,7 +17,7 @@ diff --git a/src/components/shared/SongItem.vue b/src/components/shared/SongItem.vue index f7debd18..81366b72 100644 --- a/src/components/shared/SongItem.vue +++ b/src/components/shared/SongItem.vue @@ -7,7 +7,7 @@ {{ index }}
diff --git a/src/components/shared/TrackItem.vue b/src/components/shared/TrackItem.vue index 51128679..8a41e800 100644 --- a/src/components/shared/TrackItem.vue +++ b/src/components/shared/TrackItem.vue @@ -7,7 +7,7 @@ }" >
app_dom.clientWidth; + const outOfBoundsY = + scopeY + context_menu.clientHeight > app_dom.clientHeight; + + let normalizedX = x; + let normalizedY = y; + + if (outOfBoundsX) { + normalizedX = + scopeOffsetX + app_dom.clientWidth - context_menu.clientHeight; + } + + if (outOfBoundsY) { + normalizedY = + scopeOffsetY + app_dom.clientHeight - context_menu.clientHeight; + } + + return { + normalizedX, + normalizedY, + }; +} diff --git a/src/composables/perks.js b/src/composables/perks.js index 81098ba2..5948c042 100644 --- a/src/composables/perks.js +++ b/src/composables/perks.js @@ -212,6 +212,8 @@ window.addEventListener("keyup", () => { key_down_fired = false; }); + + function formatSeconds(seconds) { // check if there are arguments @@ -258,6 +260,7 @@ export default { focusCurrent, updateQueue, formatSeconds, + getElem, current, queue, next, diff --git a/src/composables/searchMusic.js b/src/composables/searchMusic.js index 04208970..15cab0ae 100644 --- a/src/composables/searchMusic.js +++ b/src/composables/searchMusic.js @@ -1,10 +1,10 @@ import state from "./state.js"; -const base_url = "http://0.0.0.0:9876/search?q="; +const base_url = `${state.settings.uri}/search?q=`; async function search(query) { state.loading.value = true; - const url = base_url + encodeURIComponent(query); + const url = base_url + encodeURIComponent(query.trim()); const res = await fetch(url); diff --git a/src/stores/context.js b/src/stores/context.js new file mode 100644 index 00000000..a9af43e7 --- /dev/null +++ b/src/stores/context.js @@ -0,0 +1,21 @@ +import { defineStore } from "pinia"; +import normalizeContextMenu from "../composables/normalizeContextMenu"; + +export default defineStore("context-menu", { + state: () => ({ + visible: false, + x: 0, + y: 0, + }), + actions: { + showContextMenu(e) { + this.visible = true; + const { normalX, normalY } = normalizeContextMenu(e.clientX, e.clientY); + this.x = normalX; + this.y = normalY; + }, + hideContextMenu() { + this.visible = false; + }, + }, +}); diff --git a/src/stores/gsearch.js b/src/stores/gsearch.js new file mode 100644 index 00000000..2be26df2 --- /dev/null +++ b/src/stores/gsearch.js @@ -0,0 +1,67 @@ +import { defineStore } from "pinia"; +import useDebouncedRef from "../composables/useDebouncedRef"; + +export default defineStore("gsearch", { + state: () => ({ + filters: [], + query: useDebouncedRef("", 600), + results: { + tracks: { + items: [], + more: false, + }, + albums: { + items: [], + more: false, + }, + artists: { + items: [], + more: false, + }, + }, + }), + actions: { + addFilter(filter) { + if (this.filters.includes(filter)) { + return; + } + this.filters.push(filter); + }, + removeFilter(filter) { + this.filters = this.filters.filter((f) => f !== filter); + }, + removeLastFilter() { + this.filters.pop(); + }, + updateQuery(query) { + this.query = query; + }, + updateTrackResults(results) { + this.results.tracks = results; + }, + addMoreTrackResults(results) { + this.results.tracks.items = [ + ...this.results.tracks.items, + ...results.items, + ]; + }, + updateAlbumResults(results) { + this.results.albums = results; + }, + addMoreAlbumResults(results) { + this.results.albums.items = [ + ...this.results.albums.items, + ...results.items, + ]; + }, + updateArtistResults(results) { + this.results.artists = results; + }, + addMoreArtistResults(results) { + this.results.artists.items = [ + ...this.results.artists.items, + ...results.items, + ]; + }, + }, +}); diff --git a/src/stores/tabs.js b/src/stores/tabs.js index 2cd79067..d79dc401 100644 --- a/src/stores/tabs.js +++ b/src/stores/tabs.js @@ -1,5 +1,5 @@ import { defineStore } from "pinia"; -import { ref } from "vue"; +import perks from "../composables/perks"; const tablist = { home: "home", @@ -14,8 +14,21 @@ export default defineStore("tabs", { }), actions: { changeTab(tab) { + if (tab === this.tabs.queue) { + setTimeout(() => { + perks.focusCurrent(); + }, 500); + } this.current = tab; - console.log(this.current); + }, + switchToQueue() { + this.changeTab(tablist.queue); + }, + switchToSearch() { + this.changeTab(tablist.search); + }, + switchToHome() { + this.changeTab(tablist.home); }, }, });