Skip to content

Commit b328ff8

Browse files
committed
fix: Show play buttons when touchscreen is detected
1 parent 5b0c888 commit b328ff8

8 files changed

Lines changed: 44 additions & 10 deletions

File tree

src/components/HomeWidgetRow.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
item.media_type,
3636
)
3737
"
38+
:is-available="itemIsAvailable(item)"
3839
@menu="onMenu"
3940
@click="onClick"
4041
@play="onPlayClick"

src/components/ItemsListing.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
:is-selected="isSelected(item)"
5555
:show-checkboxes="showCheckboxes"
5656
:show-actions="['tracks', 'albums'].includes(itemtype)"
57+
:is-available="itemIsAvailable(item)"
5758
@select="onSelect"
5859
@menu="onMenu"
5960
@click="onClick"
@@ -74,6 +75,7 @@
7475
:item="item"
7576
:is-selected="isSelected(item)"
7677
:show-checkboxes="showCheckboxes"
78+
:is-available="itemIsAvailable(item)"
7779
@select="onSelect"
7880
@menu="onMenu"
7981
@click="onClick"
@@ -102,6 +104,7 @@
102104
:show-album="showAlbum"
103105
:show-checkboxes="showCheckboxes"
104106
:is-selected="isSelected(item)"
107+
:is-available="itemIsAvailable(item)"
105108
:show-details="itemtype.includes('versions')"
106109
@select="onSelect"
107110
@menu="onMenu"

src/components/ListviewItem.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ListItem
44
link
55
:show-menu-btn="showMenu"
6-
:class="{ unavailable: !itemIsAvailable(item) }"
6+
:class="{ unavailable: !isAvailable }"
77
@click.stop="onClick"
88
@menu.stop="onMenu"
99
>
@@ -198,7 +198,6 @@ import { useI18n } from "vue-i18n";
198198
import { getBreakpointValue } from "@/plugins/breakpoint";
199199
import ListItem from "@/components/mods/ListItem.vue";
200200
import FavouriteButton from "@/components/FavoriteButton.vue";
201-
import { itemIsAvailable } from "@/plugins/api/helpers";
202201
203202
// properties
204203
export interface Props {
@@ -213,6 +212,7 @@ export interface Props {
213212
showDuration?: boolean;
214213
isSelected: boolean;
215214
isDisabled?: boolean;
215+
isAvailable?: boolean;
216216
showCheckboxes?: boolean;
217217
showDetails?: boolean;
218218
}
@@ -231,6 +231,7 @@ const compProps = withDefaults(defineProps<Props>(), {
231231
showDuration: true,
232232
showCheckboxes: false,
233233
isDisabled: false,
234+
isAvailable: true,
234235
});
235236
236237
// computed properties

src/components/PanelviewItem.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
tile
77
hover
88
class="panel-item"
9-
:class="{ unavailable: !itemIsAvailable(item) }"
9+
:class="{ unavailable: !isAvailable }"
1010
@click="onClick"
1111
@click.right.prevent="onMenu"
1212
>
@@ -67,7 +67,7 @@
6767

6868
<!-- play button -->
6969
<v-btn
70-
v-if="(isHovering || $vuetify.display.mobile) && itemIsAvailable(item)"
70+
v-if="(isHovering || store.isTouchscreen) && isAvailable"
7171
icon="mdi-play"
7272
color="primary"
7373
fab
@@ -138,10 +138,10 @@ import {
138138
getBrowseFolderName,
139139
parseBool,
140140
} from "@/helpers/utils";
141-
import { itemIsAvailable } from "@/plugins/api/helpers";
142141
import { iconHiRes } from "./QualityDetailsBtn.vue";
143142
import { getBreakpointValue } from "@/plugins/breakpoint";
144143
import FavouriteButton from "@/components/FavoriteButton.vue";
144+
import { store } from "@/plugins/store";
145145
146146
// properties
147147
export interface Props {
@@ -151,12 +151,14 @@ export interface Props {
151151
showCheckboxes?: boolean;
152152
showMediaType?: boolean;
153153
showActions?: boolean;
154+
isAvailable?: boolean;
154155
}
155156
const compProps = withDefaults(defineProps<Props>(), {
156157
size: 200,
157158
showCheckboxes: false,
158159
showActions: false,
159160
showMediaType: false,
161+
isAvailable: true,
160162
});
161163
162164
// computed properties

src/components/PanelviewItemCompact.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<v-card
44
v-hold="onMenu"
55
v-bind="props"
6-
:class="{ 'on-hover': isHovering, unavailable: !itemIsAvailable(item) }"
6+
:class="{ 'on-hover': isHovering, unavailable: !isAvailable }"
77
:elevation="isHovering ? 3 : 0"
88
@click="onClick"
99
@click.right.prevent="onMenu"
@@ -65,7 +65,7 @@
6565
</div>
6666
<!-- play button -->
6767
<v-btn
68-
v-if="isHovering || $vuetify.display.mobile"
68+
v-if="(isHovering || store.isTouchscreen) && isAvailable"
6969
icon="mdi-play"
7070
color="primary"
7171
fab
@@ -85,7 +85,7 @@ import {
8585
MediaType,
8686
} from "@/plugins/api/interfaces";
8787
import { getArtistsString, getBrowseFolderName } from "@/helpers/utils";
88-
import { itemIsAvailable } from "@/plugins/api/helpers";
88+
import { store } from "@/plugins/store";
8989
9090
// properties
9191
export interface Props {
@@ -94,12 +94,14 @@ export interface Props {
9494
isSelected?: boolean;
9595
showCheckboxes?: boolean;
9696
permanentOverlay?: boolean;
97+
isAvailable?: boolean;
9798
}
9899
const compProps = withDefaults(defineProps<Props>(), {
99100
size: 200,
100101
isSelected: false,
101102
showCheckboxes: false,
102103
permanentOverlay: false,
104+
isAvailable: true,
103105
});
104106
105107
// emits

src/helpers/utils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,3 +458,23 @@ export const panelViewItemResponsive = function (displaySize: number) {
458458
return 0;
459459
}
460460
};
461+
462+
export function isTouchscreenDevice() {
463+
// detect if device/browser is touch enabled
464+
let result = false;
465+
if (window.PointerEvent && "maxTouchPoints" in navigator) {
466+
if (navigator.maxTouchPoints > 0) {
467+
result = true;
468+
}
469+
} else {
470+
if (
471+
window.matchMedia &&
472+
window.matchMedia("(any-pointer:coarse)").matches
473+
) {
474+
result = true;
475+
} else if (window.TouchEvent || "ontouchstart" in window) {
476+
result = true;
477+
}
478+
}
479+
return result;
480+
}

src/plugins/api/helpers.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import api from ".";
44
import { MediaItemType, ItemMapping, MediaType } from "./interfaces";
55

6-
export const itemIsAvailable = function (item: MediaItemType | ItemMapping) {
6+
export const itemIsAvailable = function (
7+
item: MediaItemType | ItemMapping,
8+
): boolean {
79
if (item.media_type == MediaType.FOLDER) return true;
810
if ("provider_mappings" in item) {
911
for (const x of item.provider_mappings) {
1012
if (x.available && api.providers[x.provider_instance]?.available)
1113
return true;
1214
}
13-
} else if ("available" in item) return item.available;
15+
} else if ("available" in item) return item.available as boolean;
1416
return false;
1517
};

src/plugins/store.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Player, PlayerQueue, QueueItem } from "./api/interfaces";
33

44
import api from "./api";
55
import { StoredState } from "@/components/ItemsListing.vue";
6+
import { isTouchscreenDevice } from "@/helpers/utils";
67

78
export enum AlertType {
89
ERROR = "error",
@@ -40,6 +41,7 @@ interface Store {
4041
libraryPlaylistsCount?: number;
4142
libraryRadiosCount?: number;
4243
connected?: boolean;
44+
isTouchscreen: boolean;
4345
}
4446

4547
export const store: Store = reactive({
@@ -87,4 +89,5 @@ export const store: Store = reactive({
8789
libraryPlaylistsCount: undefined,
8890
libraryRadiosCount: undefined,
8991
connected: false,
92+
isTouchscreen: isTouchscreenDevice(),
9093
});

0 commit comments

Comments
 (0)