use album colors on album header play button

- use alnum chars only on hashes
- add underline on track album hover
This commit is contained in:
geoffrey45 2022-06-30 21:02:01 +03:00 committed by Mungai Geoffrey
parent 5acb8cb84d
commit 34a214df22
6 changed files with 87 additions and 19 deletions

View File

@ -1,9 +1,7 @@
""" """
This module contains mini functions for the server. This module contains mini functions for the server.
""" """
from dataclasses import dataclass
import os import os
from pprint import pprint
import threading import threading
from datetime import datetime from datetime import datetime
from typing import Dict, Set from typing import Dict, Set
@ -13,7 +11,6 @@ import requests
from app import models from app import models
from app import instances from app import instances
from app.lib.albumslib import Thumbnail
def background(func): def background(func):
@ -53,8 +50,6 @@ def run_fast_scandir(__dir: str, full=False) -> Dict[List[str], List[str]]:
return subfolders, files return subfolders, files
class RemoveDuplicates: class RemoveDuplicates:
def __init__(self, tracklist: List[models.Track]) -> None: def __init__(self, tracklist: List[models.Track]) -> None:
self.tracklist = tracklist self.tracklist = tracklist
@ -77,15 +72,12 @@ def is_valid_file(filename: str) -> bool:
return False return False
ill_chars = '/\\:*?"<>|#&'
def create_album_hash(title: str, artist: str) -> str: def create_album_hash(title: str, artist: str) -> str:
""" """
Creates a simple hash for an album Creates a simple hash for an album
""" """
lower = (title + artist).replace(" ", "").lower() lower = (title + artist).replace(" ", "").lower()
hash = "".join([i for i in lower if i not in ill_chars]) hash = "".join([i for i in lower if i.isalnum()])
return hash return hash
@ -99,7 +91,7 @@ def create_safe_name(name: str) -> str:
""" """
Creates a url-safe name from a name. Creates a url-safe name from a name.
""" """
return "".join([i for i in name if i not in ill_chars]) return "".join([i for i in name if i.isalnum()])
class UseBisection: class UseBisection:

View File

@ -54,10 +54,8 @@ class Track:
@staticmethod @staticmethod
def create_unique_hash(*args): def create_unique_hash(*args):
ill_chars = '/\\:*?"<>|#&'
string = "".join(str(a) for a in args).replace(" ", "") string = "".join(str(a) for a in args).replace(" ", "")
return "".join(string).strip(ill_chars).lower() return "".join([i for i in string if i.isalnum()]).lower()
@dataclass(slots=True) @dataclass(slots=True)

View File

@ -35,7 +35,11 @@
{{ formatSeconds(album.duration, true) }} {{ album.date }} {{ formatSeconds(album.duration, true) }} {{ album.date }}
{{ album.artist }} {{ album.artist }}
</div> </div>
<PlayBtnRect :source="playSources.album" :store="useAlbumStore" /> <PlayBtnRect
:source="playSources.album"
:store="useAlbumStore"
:background="getButtonColor()"
/>
</div> </div>
</div> </div>
</div> </div>
@ -73,10 +77,57 @@ function isLight(rgb: string = props.album.colors[0]) {
const [r, g, b] = rgb.match(/\d+/g)!.map(Number); const [r, g, b] = rgb.match(/\d+/g)!.map(Number);
const brightness = (r * 299 + g * 587 + b * 114) / 1000; const brightness = (r * 299 + g * 587 + b * 114) / 1000;
console.log(brightness);
return brightness > 150; return brightness > 170;
} }
function getButtonColor(colors: string[] = props.album.colors) {
const base_color = colors[0];
console.log(colors.length);
if (colors.length === 0) return { color: "#000" };
for (let i = 0; i < colors.length; i++) {
// if (isLight(colors[i])) break;
if (theyContrast(base_color, colors[i])) {
return {
color: colors[i],
isDark: isLight(colors[i]),
};
}
}
return {
color: "#000",
};
}
function luminance(r: any, g: any, b: any) {
let a = [r, g, b].map(function (v) {
v /= 255;
return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(rgb1: number[], rgb2: number[]) {
let lum1 = luminance(rgb1[0], rgb1[1], rgb1[2]);
let lum2 = luminance(rgb2[0], rgb2[1], rgb2[2]);
let brightest = Math.max(lum1, lum2);
let darkest = Math.min(lum1, lum2);
return (brightest + 0.05) / (darkest + 0.05);
}
function rgbToArray(rgb: string) {
return rgb.match(/\d+/g)!.map(Number);
}
function theyContrast(color1: string, color2: string) {
return contrast(rgbToArray(color1), rgbToArray(color2)) > 3;
}
console.log(
contrast(rgbToArray(props.album.colors[0]), rgbToArray(props.album.colors[3]))
);
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -12,7 +12,14 @@
<div class="carddd"> <div class="carddd">
<div class="info"> <div class="info">
<div class="btns"> <div class="btns">
<PlayBtnRect :source="playSources.playlist" :store="usePStore" /> <PlayBtnRect
:source="playSources.playlist"
:store="usePStore"
:background="{
color: '#fff',
isDark: true,
}"
/>
<Option @showDropdown="showDropdown" :src="context.src" /> <Option @showDropdown="showDropdown" :src="context.src" />
</div> </div>
<div class="duration"> <div class="duration">

View File

@ -2,8 +2,12 @@
<div <div
class="playbtnrect rounded" class="playbtnrect rounded"
@click="usePlayFrom(source, useQStore, store)" @click="usePlayFrom(source, useQStore, store)"
:style="{
backgroundColor: background.color,
}"
:class="{ playbtnrectdark: background.isDark }"
> >
<div class="icon image"></div> <playBtnSvg />
<div class="text">Play</div> <div class="text">Play</div>
</div> </div>
</template> </template>
@ -15,9 +19,14 @@ import useFStore from "@/stores/pages/folder";
import useAStore from "@/stores/pages/album"; import useAStore from "@/stores/pages/album";
import usePStore from "@/stores/pages/playlist"; import usePStore from "@/stores/pages/playlist";
import useQStore from "@/stores/queue"; import useQStore from "@/stores/queue";
import playBtnSvg from "@/assets/icons/play.svg";
defineProps<{ defineProps<{
source: playSources; source: playSources;
background?: {
color: string;
isDark?: boolean;
};
store: store:
| typeof useQStore | typeof useQStore
| typeof useFStore | typeof useFStore
@ -34,7 +43,6 @@ defineProps<{
height: 2.5rem; height: 2.5rem;
padding-left: 0.75rem; padding-left: 0.75rem;
cursor: pointer; cursor: pointer;
background-color: $accent;
user-select: none; user-select: none;
color: $white; color: $white;
transition: all 0.5s ease-in-out; transition: all 0.5s ease-in-out;
@ -51,4 +59,12 @@ defineProps<{
} }
} }
} }
.playbtnrectdark {
color: $black !important;
svg > path {
fill: $accent !important;
}
}
</style> </style>

View File

@ -157,6 +157,10 @@ function emitUpdate(track: Track) {
max-width: max-content; max-width: max-content;
cursor: pointer; cursor: pointer;
&:hover {
text-decoration: underline;
}
@include tablet-portrait { @include tablet-portrait {
display: none; display: none;
} }