Merge branch 'main' into enhancement/radio

This commit is contained in:
cryptofyre 2022-05-24 11:01:28 -05:00 committed by GitHub
commit d80cf6efb1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 884 additions and 24624 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

View file

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="100%"
height="100%"
viewBox="0 0 34 34"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg10"
sodipodi:docname="stop.svg"
inkscape:version="1.1.2 (b8e25be833, 2022-02-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs14" /><sodipodi:namedview
id="namedview12"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:snap-object-midpoints="false"
inkscape:zoom="24.205882"
inkscape:cx="17"
inkscape:cy="17.020656"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg10"><inkscape:grid
type="xygrid"
id="grid1236" /></sodipodi:namedview>
<rect
style="fill:#ffffff;fill-opacity:1"
id="rect871"
width="18.01215"
height="19.375456"
x="7.9939251"
y="7.3122721"
ry="2.3134873" /></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,16 @@
/*
Copyright (c) 2021 Kil Hyung-jin, with Reserved Font Name Pretendard.
https://github.com/orioncactus/pretendard
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
*/
@font-face {
font-family: 'Pretendard Variable';
font-weight: 45 920;
font-style: normal;
font-display: swap;
src: local('Pretendard Variable'), url('./woff2/PretendardVariable.woff2') format('woff2-variations');
}

View file

@ -98,7 +98,6 @@ const CiderAudio = {
"name": "Maikiwi",
"description": "",
"gainComp": "1.3381352151540196",
"img": "./assets/audiolabs/focused.png",
},
{
"id": "71_420maikiwi",
@ -106,7 +105,6 @@ const CiderAudio = {
"name": "Soundstage",
"description": "",
"gainComp": "1.3963683610559376",
"img": "./assets/audiolabs/expansive.png",
},
{
"id": "70_422maikiwi",
@ -114,7 +112,6 @@ const CiderAudio = {
"name": "Separation",
"description": "",
"gainComp": "1.30767553892022",
"img": "./assets/audiolabs/classic.png",
},
{
"id": "standard",
@ -122,7 +119,6 @@ const CiderAudio = {
"name": "Minimal",
"description": "",
"gainComp": "1.2647363474711515",
"img": "./assets/audiolabs/minimal.png",
}
],
atmosphereRealizerProfiles: [
@ -407,7 +403,7 @@ const CiderAudio = {
CiderAudio.audioNodes.atmosphereRealizer2 = CiderAudio.context.createConvolver();
CiderAudio.audioNodes.atmosphereRealizer2.normalize = false;
let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) {
return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile;
return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer2_value;
});
if (atmosphereRealizerProfile === undefined) {
@ -452,7 +448,7 @@ const CiderAudio = {
CiderAudio.audioNodes.atmosphereRealizer1 = CiderAudio.context.createConvolver();
CiderAudio.audioNodes.atmosphereRealizer1.normalize = false;
let atmosphereRealizerProfile = CiderAudio.atmosphereRealizerProfiles.find(function (profile) {
return profile.id === app.cfg.audio.maikiwiAudio.spatialProfile;
return profile.id === app.cfg.audio.maikiwiAudio.atmosphereRealizer1_value;
});
if (atmosphereRealizerProfile === undefined) {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7670,160 +7670,132 @@ fieldset:disabled .btn {
.popover {
position: absolute;
top : 0;
left : 0
/* rtl:ignore */
;
z-index : 1070;
display : block;
max-width : 276px;
font-family : var(--bs-font-sans-serif);
font-style : normal;
font-weight : 400;
line-height : 1.5;
text-align : left;
text-align : start;
text-decoration : none;
text-shadow : none;
text-transform : none;
letter-spacing : normal;
word-break : normal;
word-spacing : normal;
white-space : normal;
line-break : auto;
font-size : 0.875rem;
word-wrap : break-word;
background-color: #fff;
background-clip : padding-box;
border : 1px solid rgba(0, 0, 0, 0.2);
border-radius : 0.3rem;
top: 0;
left: 0 /* rtl:ignore */;
z-index: 1070;
display: block;
max-width: 276px;
font-family: var(--bs-font-sans-serif);
font-style: normal;
font-weight: 400;
line-height: 1.5;
text-align: left;
text-align: start;
text-decoration: none;
text-shadow: none;
text-transform: none;
letter-spacing: normal;
word-break: normal;
word-spacing: normal;
white-space: normal;
line-break: auto;
font-size: 0.875rem;
word-wrap: break-word;
background-color: var(--modalBackground);
background-clip: padding-box;
box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow);
border-radius: var(--mediaItemRadius);
}
.popover .popover-arrow {
position: absolute;
display : block;
width : 1rem;
height : 0.5rem;
display: block;
width: 1rem;
height: 0.5rem;
}
.popover .popover-arrow::before,
.popover .popover-arrow::after {
position : absolute;
display : block;
content : "";
.popover .popover-arrow::before, .popover .popover-arrow::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
}
.bs-popover-top>.popover-arrow,
.bs-popover-auto[data-popper-placement^=top]>.popover-arrow {
.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {
bottom: calc(-0.5rem - 1px);
}
.bs-popover-top>.popover-arrow::before,
.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before {
bottom : 0;
border-width : 0.5rem 0.5rem 0;
.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {
bottom: 0;
border-width: 0.5rem 0.5rem 0;
border-top-color: rgba(0, 0, 0, 0.25);
}
.bs-popover-top>.popover-arrow::after,
.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after {
bottom : 1px;
border-width : 0.5rem 0.5rem 0;
.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {
bottom: 1px;
border-width: 0.5rem 0.5rem 0;
border-top-color: #fff;
}
.bs-popover-end>.popover-arrow,
.bs-popover-auto[data-popper-placement^=right]>.popover-arrow {
left : calc(-0.5rem - 1px);
width : 0.5rem;
.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {
left: calc(-0.5rem - 1px);
width: 0.5rem;
height: 1rem;
}
.bs-popover-end>.popover-arrow::before,
.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before {
left : 0;
border-width : 0.5rem 0.5rem 0.5rem 0;
.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {
left: 0;
border-width: 0.5rem 0.5rem 0.5rem 0;
border-right-color: rgba(0, 0, 0, 0.25);
}
.bs-popover-end>.popover-arrow::after,
.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after {
left : 1px;
border-width : 0.5rem 0.5rem 0.5rem 0;
.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {
left: 1px;
border-width: 0.5rem 0.5rem 0.5rem 0;
border-right-color: #fff;
}
.bs-popover-bottom>.popover-arrow,
.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow {
.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {
top: calc(-0.5rem - 1px);
}
.bs-popover-bottom>.popover-arrow::before,
.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before {
top : 0;
border-width : 0 0.5rem 0.5rem 0.5rem;
.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {
top: 0;
border-width: 0 0.5rem 0.5rem 0.5rem;
border-bottom-color: rgba(0, 0, 0, 0.25);
}
.bs-popover-bottom>.popover-arrow::after,
.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after {
top : 1px;
border-width : 0 0.5rem 0.5rem 0.5rem;
.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {
top: 1px;
border-width: 0 0.5rem 0.5rem 0.5rem;
border-bottom-color: #fff;
}
.bs-popover-bottom .popover-header::before,
.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {
position : absolute;
top : 0;
left : 50%;
display : block;
width : 1rem;
margin-left : -0.5rem;
content : "";
.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {
position: absolute;
top: 0;
left: 50%;
display: block;
width: 1rem;
margin-left: -0.5rem;
content: "";
border-bottom: 1px solid #f0f0f0;
}
.bs-popover-start>.popover-arrow,
.bs-popover-auto[data-popper-placement^=left]>.popover-arrow {
right : calc(-0.5rem - 1px);
width : 0.5rem;
.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {
right: calc(-0.5rem - 1px);
width: 0.5rem;
height: 1rem;
}
.bs-popover-start>.popover-arrow::before,
.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before {
right : 0;
border-width : 0.5rem 0 0.5rem 0.5rem;
.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {
right: 0;
border-width: 0.5rem 0 0.5rem 0.5rem;
border-left-color: rgba(0, 0, 0, 0.25);
}
.bs-popover-start>.popover-arrow::after,
.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after {
right : 1px;
border-width : 0.5rem 0 0.5rem 0.5rem;
.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {
right: 1px;
border-width: 0.5rem 0 0.5rem 0.5rem;
border-left-color: #fff;
}
.popover-header {
padding : 0.5rem 1rem;
margin-bottom : 0;
font-size : 1rem;
background-color : #f0f0f0;
border-bottom : 1px solid rgba(0, 0, 0, 0.2);
border-top-left-radius : calc(0.3rem - 1px);
padding: 0.5rem 1rem;
margin-bottom: 0;
font-size: 1rem;
background-color: #f0f0f0;
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
border-top-left-radius: calc(0.3rem - 1px);
border-top-right-radius: calc(0.3rem - 1px);
}
.popover-header:empty {
display: none;
}
.popover-body {
padding: 1rem 1rem;
color : #212529;
color: var(--textColor);
}
// carousel

View file

@ -4,22 +4,72 @@
#app.twopanel {
--chromeHeight1: 46px;
--chromeHeight2: 76px;
--chromeHeight : calc(var(--chromeHeight1) + var(--chromeHeight2));
--chromeHeight2: 90px;
--chromeHeight: calc(var(--chromeHeight1) + var(--chromeHeight2));
.app-chrome {
.app-mainmenu {
width : 30px;
width: 30px;
height: 30px;
}
.search-input {
width: 300px;
}
height: var(--chromeHeight1);
&.chrome-bottom {
background: var(--color2);
-webkit-app-region: no-drag;
height : var(--chromeHeight2);
height: var(--chromeHeight2);
box-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25);
z-index : 1;
z-index: 1;
.app-chrome-playback-duration-bottom {
width: 100%;
.col {
display: flex;
}
.col-sm-auto {
width: 4em;
display: flex;
justify-content: center;
align-items: center;
font-size: 0.8em;
}
input[type=range] {
appearance: none;
width: 100%;
height: 5px;
background-color: rgb(200 200 200 / 10%);
border-radius: 6px;
box-shadow: 0px 0px 0px 1px rgba(0 0 0 / 10%);
align-self: center;
&::-webkit-slider-thumb {
opacity: 0;
transform: scale(1);
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
border-radius: 100%;
background: var(--keyColor);
cursor: default;
transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
}
&:hover {
&::-webkit-slider-thumb {
opacity: 1;
}
}
}
}
}
}
@ -31,43 +81,43 @@
.app-playback-controls .actions {
align-self: center;
}
-webkit-app-region: no-drag;
.playback-button.play,
.playback-button.pause {
width : 42px;
height : 42px;
background-color: rgb(200 200 200 / 20%);
border-radius : 50%;
margin : 6px;
box-shadow : 0px 0px 0px 2px var(--keyColor);
.playback-button.pause,
.playback-button.stop{
width: 42px;
height: 42px;
border-radius: 50%;
margin: 6px;
}
.app-chrome--center {
display : flex;
display: flex;
flex-direction: column;
.app-chrome-playback-controls {
display : flex;
z-index : 1;
display: flex;
z-index: 1;
// margin-bottom: 12px;
}
.app-chrome-playback-duration {
position : relative;
width : 80%;
position: relative;
width: 80%;
-webkit-app-region: no-drag;
height : 16px;
height: 16px;
.song-progress {
@bgColor : transparent;
height : 16px;
position : absolute;
bottom : 4px;
left : 0px;
right : 4px;
@bgColor: transparent;
height: 16px;
position: absolute;
bottom: 4px;
left: 0px;
right: 4px;
background: @bgColor;
z-index : 0;
z-index: 0;
.song-duration {
@ -76,41 +126,41 @@
.song-duration p {
font-weight: 400;
font-size : 10px;
height : 1.2em;
font-size: 10px;
height: 1.2em;
line-height: 1.3em;
overflow : hidden;
margin : 0 0 0 0.25em;
overflow: hidden;
margin: 0 0 0 0.25em;
}
&:hover {
>input[type=range] {
> input[type=range] {
&::-webkit-slider-thumb {
opacity : 1;
opacity: 1;
transform: scale(1);
z-index : 1;
z-index: 1;
}
}
}
input[type=range] {
appearance : none;
width : 100%;
height : 4px;
appearance: none;
width: 100%;
height: 4px;
background-color: rgb(200 200 200 / 10%);
border-radius : 2px;
border-radius: 2px;
&::-webkit-slider-thumb {
opacity : 0;
transform : scale(0.5);
opacity: 0;
transform: scale(0.5);
-webkit-appearance: none;
appearance : none;
width : 12px;
height : 12px;
border-radius : 100%;
background : var(--keyColor);
cursor : default;
transition : opacity .10s var(--appleEase), transform .10s var(--appleEase);
appearance: none;
width: 12px;
height: 12px;
border-radius: 100%;
background: var(--keyColor);
cursor: default;
transition: opacity .10s var(--appleEase), transform .10s var(--appleEase);
}
}
}
@ -119,42 +169,48 @@
}
.app-chrome--left {
width : 30%;
width: 30%;
justify-content: flex-start;
align-items : flex-start;
-webkit-app-region: no-drag!important;
align-items: flex-start;
-webkit-app-region: no-drag !important;
.playback-controls {
-webkit-app-region: no-drag!important;
-webkit-app-region: no-drag !important;
.artwork {
width : var(--chromeHeight2);
height : var(--chromeHeight2);
margin : 0px 6px 0px 0px;
box-shadow: unset;
border : 0px;
--offset: 20px;
--marginOffset: 2;
--size: calc(var(--chromeHeight2) - var(--offset));
width: var(--size);
height: var(--size);
margin: 0 calc(var(--offset) / var(--marginOffset)) 0 calc(var(--offset) / var(--marginOffset));
.mediaitem-artwork,
img {
border-radius: 0px;
box-shadow : unset;
border : 0px;
border-radius: calc(var(--mediaItemRadius) / 2);
}
}
.playback-info {
align-items: flex-start;
margin : 6px;
margin: 6px;
.song-name {
text-align : left;
font-size : 15px;
font-weight : initial;
width : 100%;
text-align: left;
font-size: 0.98em;
font-weight: 500;
width: 100%;
-webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%);
}
.song-artist-album {
width : 100%;
-webkit-mask-image: linear-gradient(-90deg, transparent 0%, transparent 10%, black 20%);
.song-artist, .song-album {
font-size: 0.75em;
opacity: 0.8;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
.audio-type {
@ -163,23 +219,23 @@
.song-artist-album-content {
text-align: left;
font-size : 12px;
font-size: 12px;
}
}
width : 100%;
height : 100%;
width: 100%;
height: 100%;
max-width: 100%;
border : 0px;
border: 0px;
}
flex: 0 0 auto;
}
.app-chrome--right {
width : 30%;
flex : 0 0 auto;
width: 30%;
flex: 0 0 auto;
padding-right: 8px;
}
}

File diff suppressed because it is too large Load diff

View file

@ -897,8 +897,10 @@
/* mediaitem-square */
.cd-mediaitem-square {
width: 220px;
height: 238px;
--scaleRate: 1.25;
--scaleRateArtwork: 1;
width: 200px;
height: 200px;
display: inline-flex;
flex: 0 0 auto;
flex-direction: column;
@ -911,8 +913,8 @@
position: relative;
.artwork {
height: 190px;
width: 190px;
height: 150px;
width: 150px;
background: blue;
border-radius: var(--mediaItemRadius);
background: var(--artwork);
@ -920,7 +922,6 @@
flex: 0 0 auto;
margin: 6px;
cursor: pointer;
.mediaitem-artwork {
box-shadow: unset;
}
@ -993,6 +994,15 @@
}
}
@media (min-width: 1600px) {
width: calc(200px * var(--scaleRate));
height: calc(200px * var(--scaleRate));
.artwork-container>.artwork {
width: calc(190px * var(--scaleRateArtwork));
height: calc(190px * var(--scaleRateArtwork));
}
}
.info-rect {
width: 90%;
height: 100%;
@ -1074,8 +1084,6 @@
background: var(--spcolor);
height: 298px;
width: 230px;
max-width: 250px;
max-height: 500px;
overflow: hidden;
position: relative;
border-radius: calc(var(--mediaItemRadius) * 2);
@ -1126,6 +1134,10 @@
font-size: 0.9em;
font-weight: 500;
z-index: 1;
&+ .subtitle {
max-height: none !important;
margin-top: -0.5em;
}
}
.subtitle {
@ -1134,7 +1146,11 @@
align-items: center;
font-size: 0.75em;
width: 100%;
display: flex;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
max-height: 3.8em;
z-index: 1;
}
@ -1149,6 +1165,15 @@
pointer-events: none;
border-radius: inherit;
}
//@media (min-width: 1600px) {
// width: calc(230px * 1.25);
// height: calc(298px * 1.25);
// .artwork-container>.artwork {
// width: calc(230px * 1.25);
// height: calc(230px * 1.25);
// }
//}
}
}
@ -1524,7 +1549,7 @@ input[type=checkbox][switch]:checked:active::before {
border-radius: 6px;
font-size: 1em;
color: inherit;
background-size: 14px;
background-size: 0.98em;
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
@ -1555,6 +1580,7 @@ input[type=checkbox][switch]:checked:active::before {
.playback-button--small.cast {
background-image: url("./assets/cast_white.svg");
background-size: 1.25em;
}
.playback-button--small.miniplayer {
@ -1582,6 +1608,12 @@ input[type=checkbox][switch]:checked:active::before {
background-image: url("./assets/repeatOne.svg");
}
.playback-button.stop {
background-image: url('./assets/cider-icons/stop.svg');
background-size: 38px;
background-position: center;
}
.playback-button.pause {
background-image: url('./assets/cider-icons/pause.svg');
background-size: 38px;
@ -1605,6 +1637,15 @@ input[type=checkbox][switch]:checked:active::before {
background-size: 60%;
background-position: center;
}
.playback-button.disabled, .playback-button--small.disabled {
opacity: 0.25 !important;
pointer-events: none;
transform: none !important;
&:hover{
background-color: transparent !important;
transform: none !important;
}
}
.playback-button {
&.navigation {

View file

@ -1,349 +0,0 @@
.notyf__toast {
-webkit-app-region: no-drag;
cursor: pointer;
}
.notyf-info {
background: var(--keyColor);
}
.tooltip-inner {
background: #2f2f2f;
opacity: 1;
border: 1px solid rgba(0, 0, 0, 0.35);
transition: all 0.3s ease-in-out;
box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
}
.modal-fullscreen {
display: flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 1000;
}
.modal-fullscreen .modal-window {
background: #333;
border-radius: 10px;
box-shadow: var(--mediaItemShadow-Shadow);
display: flex;
flex-flow: column;
max-height: 500px;
max-width: 360px;
background: #121212;
width: 100%;
position: relative;
}
.modal-fullscreen .modal-window:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
box-shadow: var(--mediaItemShadow);
z-index: 1;
border-radius: inherit;
}
.modal-fullscreen .modal-window .modal-header {
width: 100%;
padding: 6px;
}
.modal-fullscreen .modal-window .modal-content {
width: 100%;
height: 100%;
overflow: hidden;
overflow-y: overlay;
}
.spatialproperties-panel .modal-window {
height: 700px;
max-height: 700px;
width: 800px;
max-width: 800px;
overflow: hidden;
}
.spatialproperties-panel .modal-window .info-header {
padding-left: 12px;
}
.spatialproperties-panel .modal-window .visual-container {
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.spatialproperties-panel .modal-window .visual {
position: relative;
height: 250px;
width: 300px;
display: inline-flex;
align-items: flex-end;
justify-content: center;
filter: drop-shadow(2px 12px 6px rgba(0, 0, 0, 0.25));
margin: 0 auto;
}
.spatialproperties-panel .modal-window .visual .face {
position: absolute;
width: calc(12px * 6);
height: calc(12px * 6);
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
}
.spatialproperties-panel .modal-window .visual .listener {
position: absolute;
width: 32px;
height: 32px;
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
background: white;
color: black;
z-index: 2;
}
.spatialproperties-panel .modal-window .visual .audiosource {
position: absolute;
width: 32px;
height: 32px;
border-radius: 6px;
transform: rotateX(60deg) rotateZ(-45deg);
transition: transform 0.2s linear, width 0.2s linear, height 0.2s linear;
background: yellow;
z-index: 2;
}
.spatialproperties-panel .modal-window .visual .face:nth-of-type(1) {
background: linear-gradient(45deg, #28223a, #1f2038);
z-index: 1;
}
.spatialproperties-panel .modal-window .visual .face:nth-of-type(2) {
background: linear-gradient(45deg, #7d53ad, #5763ff);
transform: rotateX(60deg) rotateZ(-45deg) translateZ(30px);
opacity: 0.7;
z-index: 3;
}
.spatialproperties-panel .modal-window .modal-header {
padding: 16px;
position: relative;
overflow: hidden;
}
.spatialproperties-panel .modal-window .modal-header .modal-title {
text-align: center;
}
.spatialproperties-panel .modal-window .modal-header .close-btn {
width: 50px;
height: 100%;
background-image: var(--gfx-closeBtn);
background-position: center;
background-repeat: no-repeat;
-webkit-app-region: no-drag;
appearance: none;
border: 0;
background-color: transparent;
position: absolute;
top: 0;
right: 0;
}
.spatialproperties-panel .modal-window .modal-header .close-btn:hover {
background-color: #c42b1c;
}
.addtoplaylist-panel .modal-window {
max-height: 600px;
max-width: 400px;
background: rgba(18, 18, 18, 0.9);
overflow: hidden;
backdrop-filter: blur(16px) saturate(180%);
}
.addtoplaylist-panel .modal-window .modal-header {
padding: 16px;
position: relative;
}
.addtoplaylist-panel .modal-window .modal-header .modal-title {
text-align: center;
}
.addtoplaylist-panel .modal-window .modal-header .close-btn {
width: 50px;
height: 100%;
background-image: var(--gfx-closeBtn);
background-position: center;
background-repeat: no-repeat;
-webkit-app-region: no-drag;
appearance: none;
border: 0;
background-color: transparent;
position: absolute;
top: 0;
right: 0;
}
.addtoplaylist-panel .modal-window .modal-header .close-btn:hover {
background-color: #c42b1c;
}
.addtoplaylist-panel .modal-window .modal-search {
width: 100%;
padding: 0px 16px;
position: relative;
}
.addtoplaylist-panel .modal-window .playlist-item {
appearance: none;
border: 0px;
text-align: left;
width: 100%;
margin: 0;
display: flex;
background: rgba(32, 32, 32, 0.46);
color: #eee;
font-family: inherit;
font-size: 0.98em;
padding: 6px 12px;
align-items: center;
flex-flow: row;
}
.addtoplaylist-panel .modal-window .playlist-item .icon {
pointer-events: none;
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
margin-right: 6px;
}
.addtoplaylist-panel .modal-window .playlist-item .name {
position: relative;
}
.addtoplaylist-panel .modal-window .playlist-item:hover {
background: var(--selected);
}
.addtoplaylist-panel .modal-window .playlist-item:active {
background: var(--selected-click);
}
.addtoplaylist-panel .modal-window .playlist-item.focused {
background: var(--keyColor);
}
.addtoplaylist-panel .modal-window .playlist-item:last-child {
border-bottom: 0px;
}
.menu-panel {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 100001;
display: flex;
justify-content: center;
align-items: center;
-webkit-app-region: no-drag;
}
.menu-panel .menu-header-body {
padding: 6px;
display: flex;
background: rgba(200, 200, 200, 0.1);
}
.menu-panel .menu-header-body .menu-option-header {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--mediaItemRadius);
appearance: none;
border: 0;
background: transparent;
}
.menu-panel .menu-header-body .menu-option-header.active .sidebar-icon > .svg-icon {
--color: var(--keyColor);
}
.menu-panel .menu-header-body .menu-option-header:hover {
background: var(--selected);
}
.menu-panel .menu-header-body .menu-option-header:active {
background: var(--selected-click);
}
.menu-panel .menu-panel-body {
display: flex;
flex-flow: column;
background: #262626;
position: relative;
min-width: 200px;
box-shadow: var(--ciderShadow-Generic);
border-radius: var(--mediaItemRadius);
overflow: hidden;
font-size: 13px;
}
.menu-panel .menu-panel-body .menu-option {
text-align: left;
display: flex;
width: 100%;
padding: 9px 16px;
appearance: none;
border: 0px;
font: inherit;
background: transparent;
color: inherit;
}
.menu-panel .menu-panel-body .menu-option:hover {
background: var(--selected);
}
.menu-panel .menu-panel-body .menu-option:active {
background: var(--selected-click);
}
.menu-panel .menu-header-text {
margin: 18px 6px;
}
.menu-panel .menu-header-text .close-btn {
width: 50px;
height: 42px;
background-image: var(--gfx-closeBtn);
background-position: center;
background-repeat: no-repeat;
-webkit-app-region: no-drag;
appearance: none;
border: 0;
background-color: transparent;
position: absolute;
top: 0;
right: 0;
}
.menu-panel .menu-header-text .close-btn:hover {
background-color: #c42b1c;
}
.menu-panel .menu-body {
overflow: overlay;
height: 100%;
}
.menu-panel .menu-footer {
width: 100%;
padding: 12px;
}
.queue-panel {
height: 100%;
width: 100%;
display: flex;
flex-flow: column;
}
.queue-panel .queue-header-text {
margin: 18px 6px;
}
.queue-panel .queue-body {
overflow: overlay;
height: 100%;
}
.queue-panel .queue-footer {
width: 100%;
padding: 12px;
}
.queue-panel .autoplay {
background: rgba(200, 200, 200, 0.15);
display: flex;
justify-content: center;
appearance: none;
border: 0;
border-radius: 6px;
height: 32px;
width: 32px;
}
.queue-panel .infinity {
content: url("assets/infinity.svg");
margin: auto;
}

View file

@ -333,6 +333,7 @@
position : relative;
width : 100%;
padding : 9px 14px;
align-items: center;
&::before {
background : var(--hover);
@ -484,4 +485,39 @@
}
}
}
}
.mediainfo-popover {
user-select: none;
background-color: rgb(0 0 0 / 100%);
overflow: hidden;
.content {
.shadow-artwork {
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
z-index: -1;
filter:blur(32px) brightness(50%) saturate(280%);
}
.popover-artwork {
width: 200px;
height: 200px;
margin: 0 0 20px 0;
}
.song-name {
font-weight: 600;
}
.song-artist,.song-album {
opacity: 0.75;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
}

View file

@ -661,6 +661,7 @@ const app = new Vue({
}
this.mk._bag.features['seamless-audio-transitions'] = this.cfg.audio.seamless_audio
this.mk._bag.features["broadcast-radio"] = true
this.mk._services.apiManager.store.storekit._restrictedEnabled = false
// API Fallback
if (!this.chrome.userinfo) {
@ -1804,6 +1805,25 @@ const app = new Vue({
app.skipToPreviousItem()
}
},
isDisabled() {
if(!app.mk.nowPlayingItem || app.mk.nowPlayingItem.attributes.playParams.kind == 'radioStation') {
return true;
}
return false;
},
isPrevDisabled() {
if(this.isDisabled() || (app.mk.queue._position == 0 && app.mk.currentPlaybackTime <= 2)) {
return true;
}
return false;
},
isNextDisabled() {
if(this.isDisabled() || app.mk.queue._position + 1 == app.mk.queue.length) {
return true;
}
return false;
},
async getNowPlayingItemDetailed(target) {
try {
let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind,
@ -3698,7 +3718,7 @@ const app = new Vue({
if (app.getThemeDirective("lcdArtworkSize") != "") {
artworkSize = app.getThemeDirective("lcdArtworkSize")
} else if (this.cfg.visual.directives.windowLayout == "twopanel") {
artworkSize = 80
artworkSize = 110
}
this.currentArtUrl = '';
this.currentArtUrlRaw = '';
@ -4188,11 +4208,8 @@ const app = new Vue({
this.fullscreenState = flag;
if (flag) {
ipcRenderer.send('setFullScreen', true);
if (app.mk.nowPlayingItem.type && app.mk.nowPlayingItem.type.toLowerCase().includes("video")) {
// document.querySelector('video#apple-music-video-player').requestFullscreen()
} else {
app.appMode = 'fullscreen';
}
app.appMode = 'fullscreen';
document.addEventListener('keydown', event => {
if (event.key === 'Escape' && app.appMode === 'fullscreen') {
this.fullscreen(false);
@ -4200,11 +4217,7 @@ const app = new Vue({
});
} else {
ipcRenderer.send('setFullScreen', false);
if (app.mk.nowPlayingItem.type && app.mk.nowPlayingItem.type.toLowerCase().includes("video")) {
} else {
app.appMode = 'player';
}
app.appMode = 'player';
}
},
pip(){

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
@import url("assets/fonts/Inter/inter.css");
@import url("assets/fonts/Pretendard/pretendardvariable.css");
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100;300;400;500;700;900&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100;300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+HK:wght@100;300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500;700;900&display=swap");
@import url("https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap");
@import url("less/bootstrap-vue.min.css");
@import url("less/bootstrap-vue.min.less");
@import url("less/ameframework.less");
@import url("less/codicon.css");
@import url("less/bootstrap.less");
@ -63,7 +63,7 @@ body {
background-size: cover;
background-position: center;
background: #0000;
font-family: "Inter var experimental", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
font-family: "Pretendard Variable", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
transition: opacity .10s var(--appleEase);
}
@ -146,8 +146,16 @@ body.notransparency::before {
}
#app {
--color1: rgba(15, 15, 15, 30%);
--color2: rgba(30, 30, 30, 50%);
@panelBrightness : 0%;
@panelTransparency: 50%;
@msColor1 : #202020;
@msColor2 : #272727;
@msColor3 : #2b2b2b;
--panelColor1 : darken(mix(@msColor1, transparent, @panelTransparency), @panelBrightness);
--panelColor2 : darken(mix(@msColor2, transparent, @panelTransparency), @panelBrightness);
--color1 : var(--panelColor2);
--color2 : var(--panelColor1);
--color3 : rgb(0 0 0 / 20%);
--bgColor: transparent;
--bgWidth: 0px;
--bgHeight: 0px;
@ -399,7 +407,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
}
#app-content {
background-color: var(--color2);
background-color: var(--color3);
height: 100%;
width: 100%;
overflow-y: scroll;
@ -827,6 +835,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
color: #eee;
transition: transform 0.1s;
text-align: left;
align-items: center;
&.app-sidebar-item-playlist {
-webkit-user-drag: element;
@ -1006,22 +1015,12 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
height: 14px;
width: 14px;
border-radius: 50%;
background: rgb(50 50 50);
background: #A5A8BA;
box-shadow: 0px 0px 0px 1px rgba(0 0 0 / 10%);
cursor: default;
box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.4);
transition: all var(--appleTransition);
}
.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:hover {
background-image: radial-gradient(var(--keyColor) 2px, transparent 3px, transparent 10px);
transform: scale(1.2);
}
.app-chrome .app-chrome-item.volume > input[type=range]::-webkit-slider-thumb:active {
background-image: radial-gradient(var(--keyColor) 3px, transparent 4px, transparent 10px);
transform: scale(1);
}
.app-chrome .app-chrome-item.volume > input[type=range] {
-webkit-appearance: none;
height: 4px;

View file

@ -1,40 +0,0 @@
.menu-panel .menu-panel-body {
background-color: rgba(30, 30, 30, 0.45);
backdrop-filter: blur(32px) saturate(180%);
animation: menuIn 0.1s var(--appleEase);
}
@keyframes menuIn {
0% {
opacity: 0;
transform: translateY(-10px) translate3d(0, 0, 0);
background: #1e1e1e;
}
100% {
opacity: 1;
transform: translateY(0);
background: rgba(30, 30, 30, 0.45);
}
}
.cd-mediaitem-square:not(.mediaitem-card) {
transition: transform 0.2s var(--appleEase);
transition-delay: 0.1s;
padding: 12px;
height: 250px;
}
.cd-mediaitem-square:not(.mediaitem-card) .artwork-container,
.cd-mediaitem-square:not(.mediaitem-card) .info-rect {
transition: transform 0.22s var(--appleEase);
transition-delay: 0.05s;
}
.cd-mediaitem-square:not(.mediaitem-card):hover .artwork-container {
transform: scale(1.1);
transition: transform 0.1s var(--appleEase);
transition-delay: 0s;
transform-origin: center;
}
.cd-mediaitem-square:not(.mediaitem-card):hover .info-rect {
z-index: 1;
transition: transform 0.1s var(--appleEase);
transition-delay: 0s;
transform: translateY(8px) translate3d(0, 0, 0);
}

View file

@ -46,6 +46,13 @@
}
.cd-mediaitem-square {
--transition: width 1s, height 1s;
transition: var(--transition);
.artwork {
transition: var(--transition);
}
}
.cd-mediaitem-square:not(.mediaitem-card) {
transition : transform .2s var(--appleEase);
@ -53,7 +60,7 @@
padding : 12px;
// background-color: red;
height: 250px;
height: 220px;
.artwork-container {}

View file

@ -4,9 +4,30 @@
<template v-if="mkReady()">
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
<div class="artwork" @click="drawer.open = false; fullscreen(true)">
<div class="artwork" id="artworkLCD">
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
</div>
<b-popover custom-class="mediainfo-popover" target="artworkLCD" triggers="hover" placement="right">
<div class="content">
<div class="shadow-artwork">
<mediaitem-artwork :url="currentArtUrl" :url="currentArtUrlRaw"></mediaitem-artwork>
</div>
<div class="popover-artwork">
<mediaitem-artwork :size="210" :url="currentArtUrlRaw"></mediaitem-artwork>
</div>
<div class="song-name">{{ mk.nowPlayingItem["attributes"]["name"] }}</div>
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">{{ mk.nowPlayingItem["attributes"]["artistName"] }}</div>
<div class="song-album" @click="getNowPlayingItemDetailed(`album`)">
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</div>
<hr>
<div class="btn-group" style="width:100%;">
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; miniPlayer(true)">{{ $root.getLz("term.miniplayer") }}</button>
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; fullscreen(true)">{{ $root.getLz("term.fullscreenView") }}</button>
</div>
</div>
</b-popover>
<div class="playback-info">
<div class="song-name"
:class="[isElementOverflowing('#app-main > div.app-chrome > div.app-chrome--center > div > div > div.playback-info > div.song-name') ? 'marquee' : '']">
@ -15,27 +36,17 @@
v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'"
style="display: inline-block"></div>
</div>
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
</div>
<div class="song-album" @click="getNowPlayingItemDetailed('album')" v-if='mk.nowPlayingItem["attributes"]["albumName"]'>
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</div>
<div class="chrome-icon-container">
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true"></div>
<div class="audio-type ppe-icon" v-if="cfg.audio.maikiwiAudio.ciderPPE === true"></div>
</div>
<div class="song-artist-album">
<div class="song-artist-album-content"
:class="[isElementOverflowing('#app-main > .app-chrome .app-chrome-item > .app-playback-controls > div >.song-artist-album > .song-artist-album-content') ? 'marquee' : '']"
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap;">
<div class="item-navigate song-artist" style="display: inline-block"
@click="getNowPlayingItemDetailed(`artist`)">
{{ mk.nowPlayingItem["attributes"]["artistName"] }}
</div>
<div class="song-artist item-navigate" style="display: inline-block"
@click="getNowPlayingItemDetailed('album')"
v-if="mk.nowPlayingItem['attributes']['albumName'] != ''">
<div class="separator" style="display: inline-block;">{{"—"}}</div>
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</div>
</div>
</div>
</div>
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
<div class="actions">
@ -53,57 +64,56 @@
</div>
<div class="app-chrome--center">
<div class="app-chrome-playback-duration-bottom">
<b-row>
<b-col sm="auto">{{ convertTime(getSongProgress()) }}</b-col>
<b-col>
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
@mouseup="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
</b-col>
<b-col sm="auto">{{ convertTime(mk.currentPlaybackDuration) }}</b-col>
</b-row>
</div>
<div class="app-chrome-playback-controls">
<div class="app-chrome-item">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0" :class="isDisabled() && 'disabled'"
@click="mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')"
v-b-tooltip.hover></button>
<button class="playback-button--small shuffle active" v-else
<button class="playback-button--small shuffle active" v-else :class="isDisabled() && 'disabled'"
@click="mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')"
v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item">
<button class="playback-button previous" @click="prevButton()"
<button class="playback-button previous" @click="prevButton()" :class="isPrevDisabled() && 'disabled'"
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item">
<button class="playback-button pause" @click="mk.pause()" v-if="mk.isPlaying"
<button class="playback-button stop" @click="mk.stop()" v-if="mk.isPlaying && mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
<button class="playback-button pause" @click="mk.pause()" v-else-if="mk.isPlaying"
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
<button class="playback-button play" @click="mk.play()" v-else
:title="$root.getLz('term.play')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item">
<button class="playback-button next" @click="skipToNextItem()"
<button class="playback-button next" @click="skipToNextItem()" :class="isNextDisabled() && 'disabled'"
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0" :class="isDisabled() && 'disabled'"
@click="mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')"
v-b-tooltip.hover></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2" :class="isDisabled() && 'disabled'"
v-else-if="mk.repeatMode == 1" :title="$root.getLz('term.disableRepeatOne')"
v-b-tooltip.hover></button>
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0" :class="isDisabled() && 'disabled'"
v-else-if="mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
v-b-tooltip.hover></button>
</div>
</div>
<div class="app-chrome-playback-duration">
<div class="song-progress">
<div class="song-duration"
style="justify-content: space-between; height: 1px;">
<p style="width: auto">{{ convertTime(getSongProgress()) }}</p>
<p style="width: auto">{{ convertTime(mk.currentPlaybackDuration) }}
</p>
</div>
<input type="range" step="0.01" min="0" :style="progressBarStyle()"
@input="playerLCD.desiredDuration = $event.target.value;playerLCD.userInteraction = true"
@mouseup="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
@touchend="mk.seekToTime($event.target.value);setTimeout(()=>{playerLCD.desiredDuration = 0;playerLCD.userInteraction = false}, 1000);"
:max="mk.currentPlaybackDuration" :value="getSongProgress()">
</div>
</div>
</div>
<div class="app-chrome--right">
<div class="app-chrome-item volume">
@ -116,10 +126,10 @@
v-b-tooltip.hover :title="formatVolumeTooltip()">
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small miniplayer"
:title="$root.getLz('term.miniplayer')"
<button class="playback-button--small cast"
:title="$root.getLz('term.cast')"
v-b-tooltip.hover
@click="drawer.open = false; miniPlayer(true)"></button>
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"></button>
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small queue" :class="{'active': drawer.panel == 'queue'}"

View file

@ -35,35 +35,37 @@
</template>
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
<div class="app-chrome-item display--large">
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0"
<button class="playback-button--small shuffle" v-if="mk.shuffleMode == 0" :class="isDisabled() && 'disabled'"
@click="mk.shuffleMode = 1" :title="$root.getLz('term.enableShuffle')"
v-b-tooltip.hover></button>
<button class="playback-button--small shuffle active" v-else
<button class="playback-button--small shuffle active" v-else :class="isDisabled() && 'disabled'"
@click="mk.shuffleMode = 0" :title="$root.getLz('term.disableShuffle')"
v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button previous" @click="prevButton()"
<button class="playback-button previous" @click="prevButton()" :class="isPrevDisabled() && 'disabled'"
:title="$root.getLz('term.previous')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button pause" @click="mk.pause()" v-if="mk.isPlaying"
<button class="playback-button stop" @click="mk.stop()" v-if="mk.isPlaying && mk.nowPlayingItem.attributes.playParams.kind == 'radioStation'"
:title="$root.getLz('term.stop')" v-b-tooltip.hover></button>
<button class="playback-button pause" @click="mk.pause()" v-else-if="mk.isPlaying"
:title="$root.getLz('term.pause')" v-b-tooltip.hover></button>
<button class="playback-button play" @click="mk.play()" v-else
:title="$root.getLz('term.play')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button next" @click="skipToNextItem()"
<button class="playback-button next" @click="skipToNextItem()" :class="isNextDisabled() && 'disabled'"
:title="$root.getLz('term.next')" v-b-tooltip.hover></button>
</div>
<div class="app-chrome-item display--large">
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0"
<button class="playback-button--small repeat" v-if="mk.repeatMode == 0" :class="isDisabled() && 'disabled'"
@click="mk.repeatMode = 1" :title="$root.getLz('term.enableRepeatOne')"
v-b-tooltip.hover></button>
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2"
<button class="playback-button--small repeat repeatOne" @click="mk.repeatMode = 2" :class="isDisabled() && 'disabled'"
v-else-if="mk.repeatMode == 1" :title="$root.getLz('term.disableRepeatOne')"
v-b-tooltip.hover></button>
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0"
<button class="playback-button--small repeat active" @click="mk.repeatMode = 0" :class="isDisabled() && 'disabled'"
v-else-if="mk.repeatMode == 2" :title="$root.getLz('term.disableRepeat')"
v-b-tooltip.hover></button>
</div>
@ -74,9 +76,30 @@
<template v-if="mkReady()">
<div class="app-playback-controls" @mouseover="chrome.progresshover = true"
@mouseleave="chrome.progresshover = false" @contextmenu="nowPlayingContextMenu">
<div class="artwork" @click="drawer.open = false; fullscreen(true)">
<div class="artwork" id="artworkLCD">
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
</div>
<b-popover custom-class="mediainfo-popover" target="artworkLCD" triggers="hover" placement="bottom">
<div class="content">
<div class="shadow-artwork">
<mediaitem-artwork :url="currentArtUrl" :url="currentArtUrlRaw"></mediaitem-artwork>
</div>
<div class="popover-artwork">
<mediaitem-artwork :size="210" :url="currentArtUrlRaw"></mediaitem-artwork>
</div>
<div class="song-name">{{ mk.nowPlayingItem["attributes"]["name"] }}</div>
<div class="song-artist" @click="getNowPlayingItemDetailed(`artist`)">{{ mk.nowPlayingItem["attributes"]["artistName"] }}</div>
<div class="song-album" @click="getNowPlayingItemDetailed(`album`)">
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
</div>
<hr>
<div class="btn-group" style="width:100%;">
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; miniPlayer(true)">{{ $root.getLz("term.miniplayer") }}</button>
<button class="md-btn md-btn-small" style="width: 100%;" @click="drawer.open = false; fullscreen(true)">{{ $root.getLz("term.fullscreenView") }}</button>
</div>
</div>
</b-popover>
<div class="playback-info">
<div class="chrome-icon-container">
<div class="audio-type private-icon" v-if="cfg.general.privateEnabled === true"></div>
@ -136,8 +159,24 @@
</template>
</div>
<div class="app-title-text" v-if="false">
Cider
<div class="app-chrome-item" v-else>
<div class="search-input-container">
<div class="search-input--icon"></div>
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
@blur="setTimeout(()=>{search.showHints = false}, 300)"
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();"
@input="getSearchHints()" :placeholder="$root.getLz('term.search') + '...'" v-model="search.term"
ref="searchInput" class="search-input">
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
{{ hint }}
</button>
</div>
</div>
</div>
</div>
</div>
<div class="app-chrome--right">
@ -152,10 +191,11 @@
v-b-tooltip.hover :title="formatVolumeTooltip()">
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small miniplayer"
:title="$root.getLz('term.miniplayer')"
<button class="playback-button--small cast"
:title="$root.getLz('term.cast')"
@click="cfg.advanced.AudioContext ? modals.castMenu = true : $root.notyf.error($root.getLz('settings.warn.enableAdvancedFunctionality'))"
v-b-tooltip.hover
@click="drawer.open = false; miniPlayer(true)"></button>
></button>
</div>
<div class="app-chrome-item generic">
<button class="playback-button--small queue"

View file

@ -1,22 +1,26 @@
<div id="app-sidebar">
<div class="app-sidebar-header">
<div class="search-input-container">
<div class="search-input--icon"></div>
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
@blur="setTimeout(()=>{search.showHints = false}, 300)"
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();"
@input="getSearchHints()" :placeholder="$root.getLz('term.search') + '...'" v-model="search.term"
ref="searchInput" class="search-input">
<template v-if="getThemeDirective('windowLayout') != 'twopanel'">
<div class="app-sidebar-header">
<div class="search-input-container">
<div class="search-input--icon"></div>
<input type="search" spellcheck="false" @click="showSearch()" @focus="search.showHints = true"
@blur="setTimeout(()=>{search.showHints = false}, 300)"
v-on:keyup.enter="searchQuery();search.showHints = false" @change="showSearch();"
@input="getSearchHints()" :placeholder="$root.getLz('term.search') + '...'" v-model="search.term"
ref="searchInput" class="search-input">
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
{{ hint }}
</button>
</div>
</div>
</div>
</div>
</div>
<div class="search-hints-container" v-if="search.showHints && search.hints.length != 0">
<div class="search-hints">
<button class="search-hint text-overflow-elipsis" v-for="hint in search.hints"
@click="search.term = hint;search.showHints = false;searchQuery(hint)">
{{ hint }}
</button>
</div>
</div>
</template>
<div class="app-sidebar-content" scrollaxis="y">
<div class="app-sidebar-header-text"
@click="cfg.general.sidebarCollapsed.cider = !cfg.general.sidebarCollapsed.cider"

View file

@ -15,7 +15,7 @@
{{playbackRate}} ×
</div>
<div class="md-option-segment md-option-segment_auto">
<input type="range" :step="0.05" min="0.25" :max="2" v-model="playbackRate">
<input type="range" :step="0.05" min="0.25" :max="2" @wheel="playbackRateWheel" v-model="playbackRate">
</div>
</div>
</div>
@ -34,10 +34,26 @@
},
watch: {
playbackRate: function (newValue, _oldValue) {
this.$root.mk.playbackRate = newValue
this.$root.cfg.audio.playbackRate = newValue
this.playbackRate = newValue
this.saveValue(newValue);
}
}
},
methods: {
playbackRateWheel(event) {
if (app.checkScrollDirectionIsUp(event)) {
this.saveValue(this.$root.cfg.audio.playbackRate + 0.05);
} else {
this.saveValue(this.$root.cfg.audio.playbackRate - 0.05);
}
},
saveValue(newValue) {
newValue = Number(newValue);
if (newValue >= 0.25 && newValue <= 2) {
newValue = String(newValue).length > 4 ? newValue.toFixed(2) : newValue;
this.$root.mk.playbackRate = newValue;
this.$root.cfg.audio.playbackRate = newValue;
this.playbackRate = newValue;
}
}
}
});
</script>
</script>

View file

@ -98,7 +98,7 @@
async mounted() {
await this.getBadges()
if (typeof this.item.attributes.playParams == "object") {
if (this.item.attributes.playParams.kind.includes("radioStation") && (this.item.attributes.playParams.streamingKind == 1 || this.item.attributes.playParams.streamingKind == 2)) {
if (this.item.attributes.playParams.kind.includes("radioStation") && (this.item.attributes.playParams.streamingKind == 1)) {
this.unavailable = true
}
} else {

View file

@ -118,20 +118,6 @@
</select>
</div>
</div>
<div class="spprofile-line" v-show="app.cfg.audio.maikiwiAudio.spatial === true">
<div class="spprofile-viewport">
<button class="spprev" @click="profilePrev"></button>
<button class="nextprev" @click="profileNext"></button>
<template v-for="profile in spprofiles" v-if="$root.cfg.audio.maikiwiAudio.spatialProfile == profile.id">
<transition name="spfade">
<div class="spslide" :key="profile.id">
<img v-if="profile.img" loading="eager" decoding="async" :src="profile.img" alt="">
<h1 class="sptitle">{{ profile.name }}</h1>
</div>
</transition>
</template>
</div>
</div>
<div style="opacity: 0.5; pointer-events: none">
<div class="md-option-header">
<span>{{$root.getLz('settings.header.unfinished')}}</span>
@ -192,6 +178,14 @@
case "Maikiwi":
return "Maikiwi";
break;
case "Maikiwi+":
return "Maikiwi+";
break;
case "live":
return "LIVE";
break;
}
switch (type) {
case "CAR":
@ -204,39 +198,6 @@
return name;
}
},
profileNext() {
var next = this.spprofiles.find(function (profile) {
return profile.id === this.$root.cfg.audio.maikiwiAudio.spatialProfile;
}.bind(this));
if (next) {
next = this.spprofiles[this.spprofiles.indexOf(next) + 1];
if (next) {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = next.id;
} else {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = this.spprofiles[0].id;
}
} else {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = this.spprofiles[0].id;
}
this.toggleMaikiwiSpatial()
},
profilePrev() {
// select the previous profile based on $root.cfg.audio.maikiwiAudio.spatialProfile
var prev = this.spprofiles.find(function (profile) {
return profile.id === this.$root.cfg.audio.maikiwiAudio.spatialProfile;
}.bind(this));
if (prev) {
prev = this.spprofiles[this.spprofiles.indexOf(prev) - 1];
if (prev) {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = prev.id;
} else {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = this.spprofiles[this.spprofiles.length - 1].id;
}
} else {
this.$root.cfg.audio.maikiwiAudio.spatialProfile = this.spprofiles[this.spprofiles.length - 1].id;
}
this.toggleMaikiwiSpatial()
},
toggleSpatial: function () {
if (app.cfg.audio.maikiwiAudio.spatial) {
CiderAudio.spatialOn()

View file

@ -94,9 +94,21 @@
<img :class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{app.getLz('term.confirm')}}
</button>
<button class="more-btn-round" style="float:right;" @click="menu" :aria-label="app.getLz('term.more')">
<div class="svg-icon"></div>
</button>
<div style="display: flex; float: right;">
<div class="search-input-container" style="margin-right: 8px;">
<div class="search-input--icon"></div>
<input type="search"
style="width:100%;"
spellcheck="false"
:placeholder="$root.getLz('term.search') + '...'"
@input="search()"
v-model="searchQuery"
class="search-input">
</div>
<button class="more-btn-round" @click="menu" :aria-label="app.getLz('term.more')">
<div class="svg-icon"></div>
</button>
</div>
</div>
</div>
</div>
@ -160,12 +172,12 @@
<draggable :options="{disabled: !editing}"
v-model="data.relationships.tracks.data" @start="drag=true"
@end="drag=false;put()">
<template v-if="nestedPlaylist == [] || nestedPlaylist.length <= 1">
<template v-if="!hasNestedPlaylist">
<mediaitem-list-item :item="item" :parent="getItemParent(data)" :index="index"
:showIndex="true"
:showIndexPlaylist="(data.attributes.playParams.kind ?? data.type ?? '').includes('playlist')"
:context-ext="buildContextMenu()"
v-for="(item,index) in data.relationships.tracks.data"></mediaitem-list-item>
v-for="(item,index) in displayListing"></mediaitem-list-item>
</template>
<template v-else>
<div v-for="disc in nestedPlaylist">
@ -262,7 +274,11 @@
useArtistChip: false,
nestedPlaylist: [],
classes: [],
editing: false
editing: false,
inPlaylist: false,
searchQuery: "",
displayListing: [],
hasNestedPlaylist: false,
}
},
mounted: function () {
@ -271,11 +287,21 @@
})
},
watch: {
data: function () {
this.nestedPlaylist = [];
this.isInLibrary()
this.getBadges()
this.generateNestedPlaylist()
data: {
handler: function () {
this.isInLibrary()
this.getBadges()
if (this.data.relationships) {
this.generateNestedPlaylist(this.data.relationships.tracks.data)
if (!this.hasNestedPlaylist) {
this.displayListing = this.data.relationships.tracks.data
}
}
this.inPlaylist = this.data.type == "library-playlists";
},
deep: true
}
},
methods: {
@ -296,23 +322,24 @@
}
app.modals.moreInfo = true;
},
generateNestedPlaylist() {
generateNestedPlaylist(songlists) {
this.nestedPlaylist = [];
if (this.data?.type?.includes("album")) {
console.log(this.data.relationships.tracks.data)
let songlists = this.data.relationships.tracks.data;
let discs = songlists.map(x => {
return x.attributes.discNumber
}).filter((item, i, ar) => ar.indexOf(item) === i);
if (discs && discs.length > 1) {
if ((discs && discs.length > 1) || (discs && this.hasNestedPlaylist)) {
for (disc of discs) {
let songs = songlists.filter(x => x.attributes.discNumber == disc);
this.nestedPlaylist.push({disc: disc, tracks: songs})
this.nestedPlaylist.push({ disc: disc, tracks: songs })
}
}
console.log(this.nestedPlaylist)
}
if (!this.hasNestedPlaylist)
this.hasNestedPlaylist = this.nestedPlaylist != [] && this.nestedPlaylist.length > 1;
},
isHeaderVisible(visible) {
this.headerVisible = visible
@ -398,7 +425,7 @@
this.confirm = false
},
async removeFromLibrary(id) {
const params = {"fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library"};
const params = { "fields[songs]": "inLibrary", "fields[albums]": "inLibrary", "relate": "library" };
var id = this.data.id ?? this.data.attributes.playParams.id
const res = await app.mkapi(this.data.attributes.playParams.kind ?? this.data.type, this.data.attributes.playParams.isLibrary ?? false, this.data.attributes.playParams.id ?? this.data.id, params);
if (res.data.data[0] && res.data.data[0].relationships && res.data.data[0].relationships.library && res.data.data[0].relationships.library.data && res.data.data[0].relationships.library.data.length > 0) {
@ -706,7 +733,7 @@
let query = (this.data ?? app.showingPlaylist).relationships.tracks.data.map(item => new MusicKit.MediaItem(item));
app.mk.stop().then(function () {
app.mk.setQueue({[truekind]: [id], parameters: {l: app.mklang}}).then(function () {
app.mk.setQueue({ [truekind]: [id], parameters: { l: app.mklang } }).then(function () {
app.mk.play().then(function () {
if (query.length > 100) {
let u = query.slice(100);
@ -724,8 +751,48 @@
navClass(data) {
if (data && typeof data.views != "undefined") return "";
return "d-none";
}
},
search() {
let filtered = [];
if (this.searchQuery == "") {
filtered = this.data.relationships.tracks.data;
} else {
filtered = this.data.relationships.tracks.data.filter((item) => {
let itemName = item.attributes.name.toLowerCase();
let searchTerm = this.searchQuery.toLowerCase();
let artistName = "";
let albumName = "";
if (item.attributes.artistName != null) {
artistName = item.attributes.artistName.toLowerCase();
}
if (item.attributes.albumName != null) {
albumName = item.attributes.albumName.toLowerCase();
}
// remove any non-alphanumeric characters and spaces from search term and item name
searchTerm = searchTerm.replace(/[^\p{L}\p{N} ]/gu, "");
itemName = itemName.replace(/[^\p{L}\p{N} ]/gu, "");
artistName = artistName.replace(/[^\p{L}\p{N} ]/gu, "");
albumName = albumName.replace(/[^\p{L}\p{N} ]/gu, "");
let match = itemName.includes(searchTerm) || artistName.includes(searchTerm);
// only include album name in playlists
// this allows to search for the title track (itemName == albumName)
if (this.inPlaylist) match = match || albumName.includes(searchTerm)
if (match) return item;
});
}
if (!this.hasNestedPlaylist) {
// Regular album/playlist
this.displayListing = filtered;
} else {
// Album with multiple discs
this.generateNestedPlaylist(filtered);
}
}
}
})
</script>
</script>

View file

@ -89,6 +89,9 @@
<label>
<select class="md-select" style="width:180px;"
v-model="$root.cfg.general.resumeTabs.tab">
<option value="dynamic">
{{$root.getLz('settings.option.general.resumetabs.dynamic')}}
</option>
<option value="home">{{$root.getLz('home.title')}}</option>
<option value="listen_now">{{$root.getLz('term.listenNow')}}</option>
<option value="browse">{{$root.getLz('term.browse')}}</option>
@ -99,9 +102,6 @@
<option value="library-artists">{{$root.getLz('term.artists')}}</option>
<option value="library-videos">{{$root.getLz('term.videos')}}</option>
<option value="podcasts">{{$root.getLz('term.podcasts')}}</option>
<option value="dynamic">
{{$root.getLz('settings.option.general.resumetabs.dynamic')}}
</option>
</select>
</label>
</div>