forked from Mastodon/mastoradio-la-radio-di-mastodon
add context menu
This commit is contained in:
parent
f60bc914c1
commit
415c582c00
|
@ -2650,6 +2650,11 @@
|
||||||
"physical-cpu-count": "^2.0.0"
|
"physical-cpu-count": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-zj7Gw8QC4jmR92eKUvtrZUEpl2ypRbq+qlE4pwf9n2hnUO9BOAcWUs4/Ht+gNIbFt98xtqhLvccdCfD469MzpQ=="
|
||||||
|
},
|
||||||
"@types/q": {
|
"@types/q": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"typescript": "^3.8.2"
|
"typescript": "^3.8.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@popperjs/core": "^2.0.6",
|
||||||
"core-js-pure": "^3.6.4",
|
"core-js-pure": "^3.6.4",
|
||||||
"date-fns": "^2.9.0",
|
"date-fns": "^2.9.0",
|
||||||
"get-urls": "^9.2.0",
|
"get-urls": "^9.2.0",
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* ----------------------------------------------------------- */
|
||||||
|
/* == context menu module */
|
||||||
|
/* ----------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* Overlay
|
||||||
|
-------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.contextMenu__overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextMenu__overlay.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu
|
||||||
|
-------------------------------------------------------------- */
|
||||||
|
|
||||||
|
.contextMenu {
|
||||||
|
z-index: 10;
|
||||||
|
visibility: hidden;
|
||||||
|
overflow: hidden;
|
||||||
|
min-width: 15rem;
|
||||||
|
border-radius: .3rem;
|
||||||
|
background-color: $color-primary;
|
||||||
|
color: $color-light-text;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextMenu.active {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextMenu__item,
|
||||||
|
.contextMenu__item:link,
|
||||||
|
.contextMenu__item:visited {
|
||||||
|
display: block;
|
||||||
|
padding: 1.2rem 2rem;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background: none;
|
||||||
|
color: $color-light-text;
|
||||||
|
text-align: left;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: .1s all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextMenu__item:hover,
|
||||||
|
.contextMenu__item:active,
|
||||||
|
.contextMenu__item:focus {
|
||||||
|
background-color: $color-secondary;
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
.track {
|
.track {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
margin-right: -1rem;
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
.track__main {
|
.track__main {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.track__title {
|
.track__title {
|
||||||
|
@ -53,7 +55,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-right: -1rem;
|
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
@import "5-modules/controls";
|
@import "5-modules/controls";
|
||||||
@import "5-modules/queue";
|
@import "5-modules/queue";
|
||||||
@import "5-modules/track";
|
@import "5-modules/track";
|
||||||
|
@import "5-modules/context-menu";
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------
|
// --------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<button class="contextMenu__item">Share the track</button>
|
||||||
|
<a class="contextMenu__item" href="" target="_blank">Link to toot</a>
|
||||||
|
<a class="contextMenu__item" href="" target="_blank">Link to media</a>
|
|
@ -24,7 +24,12 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls__menu">
|
<div class="controls__menu">
|
||||||
<button class="controls__menuBtn" aria-label="track menu"><IconMenu></IconMenu></button>
|
<Popper>
|
||||||
|
<button slot="btn" class="controls__menuBtn" aria-label="track menu"><IconMenu></IconMenu></button>
|
||||||
|
<div slot="content" class="contextMenu__list">
|
||||||
|
<ContextMenu></ContextMenu>
|
||||||
|
</div>
|
||||||
|
</Popper>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -35,6 +40,8 @@
|
||||||
import Prev from '/components/icons/controls/Prev'
|
import Prev from '/components/icons/controls/Prev'
|
||||||
import Next from '/components/icons/controls/Next'
|
import Next from '/components/icons/controls/Next'
|
||||||
import IconMenu from '/components/icons/Menu'
|
import IconMenu from '/components/icons/Menu'
|
||||||
|
import Popper from '/components/PopperMenu'
|
||||||
|
import ContextMenu from '/components/ContextMenu'
|
||||||
|
|
||||||
const paused = getContext('paused')
|
const paused = getContext('paused')
|
||||||
const canPrevious = getContext('canPrevious')
|
const canPrevious = getContext('canPrevious')
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<span bind:this={btn} on:click={() => openMenu()}>
|
||||||
|
<slot name="btn">
|
||||||
|
<button>button</button>
|
||||||
|
</slot>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="contextMenu__overlay" class:active={isActive} on:click={() => closeMenu()}></div>
|
||||||
|
<div class="contextMenu" bind:this={content} class:active={isActive}>
|
||||||
|
<slot name="content">
|
||||||
|
No content
|
||||||
|
</slot>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { createPopper } from '@popperjs/core';
|
||||||
|
import detectOverflow from '@popperjs/core/lib/utils/detectOverflow.js';
|
||||||
|
|
||||||
|
let btn
|
||||||
|
let content
|
||||||
|
let isActive = false
|
||||||
|
|
||||||
|
function openMenu () {
|
||||||
|
isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMenu () {
|
||||||
|
isActive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
createPopper(btn, content, {
|
||||||
|
placement: 'left-start',
|
||||||
|
modifiers: [
|
||||||
|
{
|
||||||
|
name: 'offset',
|
||||||
|
options: {
|
||||||
|
offset: ({ reference, popper }) => {
|
||||||
|
return [-10, -reference.width - 5];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'myModifier',
|
||||||
|
enabled: true,
|
||||||
|
phase: 'main',
|
||||||
|
requiresIfExists: ['offset'],
|
||||||
|
fn({ state }) {
|
||||||
|
const overflow = detectOverflow(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -1,8 +1,8 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="queue__section">
|
<div class="queue__section">
|
||||||
<div class="queue__sectionTitle">Next song</div>
|
<div class="queue__sectionTitle">Next song</div>
|
||||||
<div class="track" on:click={() => select($next)}>
|
<div class="track">
|
||||||
<div class="track__main">
|
<div class="track__main" on:click={() => select($next)}>
|
||||||
<div class="track__title" class:placeholder={!$next}>
|
<div class="track__title" class:placeholder={!$next}>
|
||||||
{#if $next}{$next.media.title}{/if}
|
{#if $next}{$next.media.title}{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@ -14,7 +14,12 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if $next}
|
{#if $next}
|
||||||
<button class="track__menu" aria-label="track menu"><IconMenu></IconMenu></button>
|
<Popper>
|
||||||
|
<button slot="btn" class="track__menu" aria-label="track menu"><IconMenu></IconMenu></button>
|
||||||
|
<div slot="content" class="contextMenu__list">
|
||||||
|
<ContextMenu></ContextMenu>
|
||||||
|
</div>
|
||||||
|
</Popper>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -23,15 +28,20 @@
|
||||||
<div class="queue__section">
|
<div class="queue__section">
|
||||||
<div class="queue__sectionTitle">History</div>
|
<div class="queue__sectionTitle">History</div>
|
||||||
{#each history as track}
|
{#each history as track}
|
||||||
<div class="track" class:track--active={track === $current} class:track--playing={!$paused} on:click={() => select(track)}>
|
<div class="track" class:track--active={track === $current} class:track--playing={!$paused}>
|
||||||
<div class="track__main">
|
<div class="track__main" on:click={() => select(track)}>
|
||||||
<div class="track__title">{track.media.title}</div>
|
<div class="track__title">{track.media.title}</div>
|
||||||
<div class="track__subtitle">
|
<div class="track__subtitle">
|
||||||
shared by {track.referer.username} •
|
shared by {track.referer.username} •
|
||||||
<DistanceDate date={track.referer.date} />
|
<DistanceDate date={track.referer.date} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="track__menu" aria-label="track menu"><IconMenu></IconMenu></button>
|
<Popper>
|
||||||
|
<button slot="btn" class="track__menu" aria-label="track menu"><IconMenu></IconMenu></button>
|
||||||
|
<div slot="content" class="contextMenu__list">
|
||||||
|
<ContextMenu></ContextMenu>
|
||||||
|
</div>
|
||||||
|
</Popper>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
{#if history.length === 0}
|
{#if history.length === 0}
|
||||||
|
@ -49,6 +59,8 @@
|
||||||
import { getContext } from 'svelte'
|
import { getContext } from 'svelte'
|
||||||
import DistanceDate from '/components/DistanceDate'
|
import DistanceDate from '/components/DistanceDate'
|
||||||
import IconMenu from '/components/icons/Menu'
|
import IconMenu from '/components/icons/Menu'
|
||||||
|
import Popper from '/components/PopperMenu'
|
||||||
|
import ContextMenu from '/components/ContextMenu'
|
||||||
|
|
||||||
const current = getContext('current')
|
const current = getContext('current')
|
||||||
const enqueueing = getContext('enqueueing')
|
const enqueueing = getContext('enqueueing')
|
||||||
|
|
Loading…
Reference in New Issue