Style Fixes on Small Screens

This commit is contained in:
shabinder 2021-03-13 16:07:27 +05:30
parent a47d9f52a0
commit 90b99cbb51
18 changed files with 462 additions and 82 deletions

View File

@ -7,7 +7,6 @@ import io.ktor.client.request.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collect
import org.khronos.webgl.ArrayBuffer
actual fun openPlatform(packageID:String, platformLink:String){
//TODO
@ -43,13 +42,14 @@ private suspend fun isInternetAvailable(): Boolean {
actual val isInternetAvailable:Boolean
get(){
return true
var result = false
/*var result = false
val job = GlobalScope.launch { result = isInternetAvailable() }
while(job.isActive){}
return result
return result*/
}
val DownloadProgressFlow: MutableSharedFlow<HashMap<String, DownloadStatus>> = MutableSharedFlow(1)
val allTracksStatus: HashMap<String, DownloadStatus> = hashMapOf()
actual suspend fun downloadTracks(
list: List<TrackDetails>,
@ -58,35 +58,48 @@ actual suspend fun downloadTracks(
){
withContext(Dispatchers.Default){
list.forEach {
allTracksStatus[it.title] = DownloadStatus.Queued
if (!it.videoID.isNullOrBlank()) {//Video ID already known!
downloadTrack(it.videoID!!, it, fetcher, dir)
} else {
val searchQuery = "${it.title} - ${it.artists.joinToString(",")}"
val videoID = fetcher.youtubeMusic.getYTIDBestMatch(searchQuery,it)
if (videoID.isNullOrBlank()) {
allTracksStatus[it.title] = DownloadStatus.Failed
DownloadProgressFlow.emit(allTracksStatus)
} else {//Found Youtube Video ID
downloadTrack(videoID, it, fetcher, dir)
}
}
}
DownloadProgressFlow.emit(allTracksStatus)
}
}
suspend fun downloadTrack(videoID: String, track: TrackDetails, fetcher:FetchPlatformQueryResult,dir:Dir) {
val url = fetcher.youtubeMp3.getMp3DownloadLink(videoID)
if(url == null){
// TODO Handle
allTracksStatus[track.title] = DownloadStatus.Failed
DownloadProgressFlow.emit(allTracksStatus)
println("No URL to Download")
}else {
downloadFile(url).collect {
when(it){
is DownloadResult.Success -> {
println("Download Completed")
allTracksStatus[track.title] = DownloadStatus.Downloaded
dir.saveFileWithMetadata(it.byteArray, track)
}
is DownloadResult.Error -> println("Download Error: ${track.title}")
is DownloadResult.Progress -> println("Download Progress: ${it.progress} : ${track.title}")
is DownloadResult.Error -> {
allTracksStatus[track.title] = DownloadStatus.Failed
println("Download Error: ${track.title}")
}
is DownloadResult.Progress -> {
allTracksStatus[track.title] = DownloadStatus.Downloading(it.progress)
println("Download Progress: ${it.progress} : ${track.title}")
}
}
DownloadProgressFlow.emit(allTracksStatus)
}
}
}

View File

@ -74,7 +74,7 @@ actual class Dir actual constructor(
private suspend fun writeTagsAndSave(writer:ID3Writer, albumArt:Object?, trackDetails: TrackDetails){
writer.apply {
setFrame("TIT2", trackDetails.title)
setFrame("TPE1", trackDetails.artists)
setFrame("TPE1", trackDetails.artists.toTypedArray())
setFrame("TALB", trackDetails.albumName?:"")
try{trackDetails.year?.substring(0,4)?.toInt()?.let { setFrame("TYER", it) }} catch(e:Exception){}
setFrame("TPE2", trackDetails.artists.joinToString(","))

View File

@ -6,11 +6,10 @@ import com.arkivanov.decompose.lifecycle.resume
import com.arkivanov.mvikotlin.core.store.StoreFactory
import com.arkivanov.mvikotlin.logging.store.LoggingStoreFactory
import com.arkivanov.mvikotlin.main.store.DefaultStoreFactory
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.di.DownloadProgressFlow
import com.shabinder.common.root.SpotiFlyerRoot
import com.shabinder.database.Database
import extras.renderableChild
import kotlinx.coroutines.flow.MutableSharedFlow
import react.*
import root.RootR
@ -40,8 +39,7 @@ class App(props: AppProps): RComponent<AppProps, RState>(props) {
override val directories = dependencies.directories
override val database: Database? = directories.db
override val showPopUpMessage: (String) -> Unit = {}//TODO
override val downloadProgressReport: MutableSharedFlow<HashMap<String, DownloadStatus>>
= MutableSharedFlow(1)
override val downloadProgressReport = DownloadProgressFlow
}
)

View File

@ -10,7 +10,6 @@ val colorOffWhite = Color("#E7E7E7")
object Styles: StyleSheet("Searchbar", isStatic = true) {
val makeRow by css {
display = Display.flex
flexDirection = FlexDirection.row
alignItems = Align.center
alignContent = Align.center
justifyContent = JustifyContent.center

View File

@ -24,11 +24,11 @@ fun RBuilder.IconList(handler:IconListProps.() -> Unit): ReactElement {
private val iconList = functionalComponent<IconListProps>("IconList") { props ->
styledDiv {
css {
+Styles.makeRow
margin(18.px)
if(props.isBadge) {
alignItems = Align.end
classes = mutableListOf("info-banners")
}
+ Styles.makeRow
}
for((icon,platformLink) in props.iconsAndPlatforms){
styledA(href = platformLink){

View File

@ -25,7 +25,7 @@ private val message = functionalComponent<MessageProps>("Message") { props->
+ props.text
css {
classes = mutableListOf("headingTitle")
fontSize = 3.2.rem
fontSize = 2.6.em
}
}
}

View File

@ -0,0 +1,38 @@
package list
import kotlinx.css.px
import kotlinx.css.width
import react.*
import styled.css
import styled.styledDiv
import styled.styledSpan
@Suppress("FunctionName")
fun RBuilder.CircularProgressBar(handler: CircularProgressBarProps.() -> Unit): ReactElement {
return child(circularProgressBar){
attrs {
handler()
}
}
}
external interface CircularProgressBarProps : RProps {
var progress:Int
}
private val circularProgressBar = functionalComponent<CircularProgressBarProps>("Circular-Progress-Bar") { props->
styledDiv {
styledSpan { +"${props.progress}%" }
styledDiv{
css {
classes = mutableListOf("left-half-clipper")
}
styledDiv{ css { classes = mutableListOf("first50-bar") } }
styledDiv{ css { classes = mutableListOf("value-bar") } }
}
css{
classes = mutableListOf("progress-circle","p${props.progress}").apply { if(props.progress>50) add("over50") }
width = 50.px
}
}
}

View File

@ -0,0 +1,49 @@
package list
import com.shabinder.common.models.DownloadStatus
import kotlinx.css.*
import kotlinx.html.js.onClickFunction
import react.*
import styled.css
import styled.styledDiv
import styled.styledImg
@Suppress("FunctionName")
fun RBuilder.DownloadButton(handler: DownloadButtonProps.() -> Unit): ReactElement {
return child(downloadButton){
attrs {
handler()
}
}
}
external interface DownloadButtonProps : RProps {
var onClick:()->Unit
var status :DownloadStatus
}
private val downloadButton = functionalComponent<DownloadButtonProps>("Circular-Progress-Bar") { props->
styledDiv {
val src = when(props.status){
is DownloadStatus.NotDownloaded -> "download-gradient.svg"
is DownloadStatus.Downloaded -> "check.svg"
is DownloadStatus.Failed -> "error.svg"
else -> ""
}
styledImg(src = src) {
attrs {
onClickFunction = {
props.onClick()
}
}
css {
width = (2.5).em
margin(8.px)
}
}
css {
classes = mutableListOf("glow-button")
borderRadius = 100.px
}
}
}

View File

@ -9,6 +9,7 @@ import kotlinx.html.id
import react.RBuilder
import styled.css
import styled.styledDiv
import styled.styledSection
class ListScreen(
props: Props<SpotiFlyerList>,
@ -20,9 +21,9 @@ class ListScreen(
val result = state.data.queryResult
styledDiv {
styledSection {
attrs {
id = "list-screen-div"
id = "list-screen"
}
if(result == null){
@ -37,10 +38,18 @@ class ListScreen(
isActive = state.data.trackList.isNotEmpty()
}
state.data.trackList.forEachIndexed{ index, trackDetails ->
TrackItem {
details = trackDetails
downloadTrack = model::onDownloadClicked
styledDiv{
css {
display =Display.flex
flexGrow = 1.0
flexDirection = FlexDirection.column
color = Color.white
}
state.data.trackList.forEachIndexed{ index, trackDetails ->
TrackItem {
details = trackDetails
downloadTrack = model::onDownloadClicked
}
}
}
}
@ -48,10 +57,9 @@ class ListScreen(
css {
classes = mutableListOf("list-screen")
display = Display.flex
padding(8.px)
flexDirection = FlexDirection.column
flexGrow = 1.0
justifyContent = JustifyContent.center
alignItems = Align.stretch
}
}
}

View File

@ -16,22 +16,28 @@ fun RBuilder.LoadingAnim(handler: RProps.() -> Unit): ReactElement {
}
private val loadingAnim = functionalComponent<RProps>("Loading Animation") {
styledDiv {
styledDiv { css { classes = mutableListOf("sk-cube sk-cube1") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube2") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube3") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube4") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube5") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube6") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube7") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube8") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube9") } }
styledDiv{
css {
classes = mutableListOf("sk-cube-grid")
height = 60.px
width = 60.px
flexGrow = 1.0
display = Display.flex
alignItems = Align.center
}
styledDiv {
styledDiv { css { classes = mutableListOf("sk-cube sk-cube1") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube2") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube3") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube4") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube5") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube6") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube7") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube8") } }
styledDiv { css { classes = mutableListOf("sk-cube sk-cube9") } }
css {
classes = mutableListOf("sk-cube-grid")
height = 60.px
width = 60.px
}
}
}
}

View File

@ -0,0 +1,29 @@
package list
import kotlinx.css.px
import kotlinx.css.width
import react.*
import styled.css
import styled.styledDiv
@Suppress("FunctionName")
fun RBuilder.LoadingSpinner(handler: RProps.() -> Unit): ReactElement {
return child(loadingSpinner){
attrs {
handler()
}
}
}
private val loadingSpinner = functionalComponent<RProps>("Loading-Spinner") {
styledDiv {
styledDiv{}
styledDiv{}
styledDiv{}
styledDiv{}
css{
classes = mutableListOf("lds-ring")
width = 50.px
}
}
}

View File

@ -1,9 +1,9 @@
package list
import com.shabinder.common.models.DownloadStatus
import com.shabinder.common.models.TrackDetails
import kotlinx.css.*
import kotlinx.html.id
import kotlinx.html.js.onClickFunction
import react.*
import styled.*
@ -36,72 +36,99 @@ private val trackItem = functionalComponent<TrackItemProps>("Track-Item"){ props
attrs {
id = "text-details"
}
styledDiv {
css {
flexGrow = 1.0
minWidth = 0.px
display = Display.flex
flexDirection = FlexDirection.column
margin(8.px)
}
styledDiv{
css {
height = 40.px
alignItems = Align.center
display = Display.flex
}
styledH3 {
+ details.title
css {
padding(8.px)
fontSize = 1.3.em
textOverflow = TextOverflow.ellipsis
whiteSpace = WhiteSpace.nowrap
overflow = Overflow.hidden
}
}
css {
height = 40.px
display =Display.flex
alignItems = Align.center
}
}
styledDiv {
css {
height = 40.px
alignItems = Align.center
display = Display.flex
}
styledH4 {
+ details.artists.joinToString(",")
css {
flexGrow = 1.0
padding(8.px)
minWidth = 4.em
fontSize = 1.1.em
textOverflow = TextOverflow.ellipsis
whiteSpace = WhiteSpace.nowrap
overflow = Overflow.hidden
}
}
styledH4 {
+ "${details.durationSec} sec"
css {
textAlign = TextAlign.end
flexGrow = 1.0
padding(8.px)
textAlign = TextAlign.right
minWidth = 4.em
fontSize = 1.1.em
textOverflow = TextOverflow.ellipsis
whiteSpace = WhiteSpace.nowrap
overflow = Overflow.hidden
}
+ details.durationSec.toString()
}
css {
height = 40.px
display =Display.flex
alignItems = Align.center
}
}
css {
display = Display.flex
flexGrow = 1.0
flexDirection = FlexDirection.column
margin(8.px)
}
}
styledDiv {
styledImg(src = "download-gradient.svg") {
attrs {
onClickFunction = {
props.downloadTrack(details)
}
}
css {
margin(8.px)
when(details.downloaded){
is DownloadStatus.NotDownloaded ->{
DownloadButton {
onClick = { props.downloadTrack(details) }
status = details.downloaded
}
}
css {
classes = mutableListOf("glow-button")
borderRadius = 100.px
width = 65.px
is DownloadStatus.Downloading -> {
CircularProgressBar {
progress = (details.downloaded as DownloadStatus.Downloading).progress
}
}
DownloadStatus.Queued -> {
LoadingSpinner {}
}
DownloadStatus.Downloaded -> {
DownloadButton {
onClick = {}
status = details.downloaded
}
}
DownloadStatus.Converting -> {
LoadingSpinner {}
}
DownloadStatus.Failed -> {
DownloadButton {
onClick = {}
status = details.downloaded
}
}
}
css {
alignItems = Align.center
display =Display.flex
flexDirection = FlexDirection.row
flexGrow = 1.0
color = Color.white
}
}
}

View File

@ -0,0 +1 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(1 0 0 -1 0 -6826)" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="-7082" y2="-7082"><stop offset="0" stop-color="#31d8ff"/><stop offset="1" stop-color="#FC5C7D"/></linearGradient><path d="m512 256c0 141.386719-114.613281 256-256 256s-256-114.613281-256-256 114.613281-256 256-256 256 114.613281 256 256zm0 0" fill="url(#a)"/><path d="m175 395.246094c-4.035156 0-7.902344-1.628906-10.726562-4.511719l-81-82.832031c-5.789063-5.921875-5.683594-15.417969.238281-21.210938 5.921875-5.792968 15.417969-5.6875 21.210937.238282l70.273438 71.859374 232.277344-237.523437c5.792968-5.921875 15.289062-6.027344 21.210937-.234375 5.925781 5.789062 6.03125 15.289062.238281 21.210938l-243 248.492187c-2.820312 2.882813-6.6875 4.511719-10.722656 4.511719zm0 0" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 923 B

View File

@ -0,0 +1,168 @@
.progress-circle {
margin: 20px;
position: relative; /* so that children can be absolutely positioned */
line-height: 5em;
}
.progress-circle:after{
border: none;
position: absolute;
text-align: center;
display: block;
border-radius: 50%;
width: 4.3em;
height: 4.3em;
background-color: white;
content: " ";
}
/* Text inside the control */
.progress-circle span {
position: absolute;
line-height: 5em;
width: 5em;
text-align: center;
display: block;
color: #53777A;
z-index: 2;
}
.left-half-clipper {
/* a round circle */
border-radius: 50%;
width: 5em;
height: 5em;
position: absolute; /* needed for clipping */
clip: rect(0, 5em, 5em, 2.5em); /* clips the whole left half*/
}
/* when p>50, don't clip left half*/
.progress-circle.over50 .left-half-clipper {
clip: rect(auto,auto,auto,auto);
}
.value-bar {
/*This is an overlayed square, that is made round with the border radius,
then it is cut to display only the left half, then rotated clockwise
to escape the outer clipping path.*/
position: absolute; /*needed for clipping*/
clip: rect(0, 2.5em, 5em, 0);
width: 5em;
height: 5em;
border-radius: 50%;
border: 0.45em solid #53777A; /*The border is 0.35 but making it larger removes visual artifacts */
/*background-color: #4D642D;*/ /* for debug */
box-sizing: border-box;
}
/* Progress bar filling the whole right half for values above 50% */
.progress-circle.over50 .first50-bar {
/*Progress bar for the first 50%, filling the whole right half*/
position: absolute; /*needed for clipping*/
clip: rect(0, 5em, 5em, 2.5em);
background-color: #53777A;
border-radius: 50%;
width: 5em;
height: 5em;
}
.progress-circle:not(.over50) .first50-bar{ display: none; }
/* Progress bar rotation position */
.progress-circle.p0 .value-bar { display: none; }
.progress-circle.p1 .value-bar { transform: rotate(4deg); }
.progress-circle.p2 .value-bar { transform: rotate(7deg); }
.progress-circle.p3 .value-bar { transform: rotate(11deg); }
.progress-circle.p4 .value-bar { transform: rotate(14deg); }
.progress-circle.p5 .value-bar { transform: rotate(18deg); }
.progress-circle.p6 .value-bar { transform: rotate(22deg); }
.progress-circle.p7 .value-bar { transform: rotate(25deg); }
.progress-circle.p8 .value-bar { transform: rotate(29deg); }
.progress-circle.p9 .value-bar { transform: rotate(32deg); }
.progress-circle.p10 .value-bar { transform: rotate(36deg); }
.progress-circle.p11 .value-bar { transform: rotate(40deg); }
.progress-circle.p12 .value-bar { transform: rotate(43deg); }
.progress-circle.p13 .value-bar { transform: rotate(47deg); }
.progress-circle.p14 .value-bar { transform: rotate(50deg); }
.progress-circle.p15 .value-bar { transform: rotate(54deg); }
.progress-circle.p16 .value-bar { transform: rotate(58deg); }
.progress-circle.p17 .value-bar { transform: rotate(61deg); }
.progress-circle.p18 .value-bar { transform: rotate(65deg); }
.progress-circle.p19 .value-bar { transform: rotate(68deg); }
.progress-circle.p20 .value-bar { transform: rotate(72deg); }
.progress-circle.p21 .value-bar { transform: rotate(76deg); }
.progress-circle.p22 .value-bar { transform: rotate(79deg); }
.progress-circle.p23 .value-bar { transform: rotate(83deg); }
.progress-circle.p24 .value-bar { transform: rotate(86deg); }
.progress-circle.p25 .value-bar { transform: rotate(90deg); }
.progress-circle.p26 .value-bar { transform: rotate(94deg); }
.progress-circle.p27 .value-bar { transform: rotate(97deg); }
.progress-circle.p28 .value-bar { transform: rotate(101deg); }
.progress-circle.p29 .value-bar { transform: rotate(104deg); }
.progress-circle.p30 .value-bar { transform: rotate(108deg); }
.progress-circle.p31 .value-bar { transform: rotate(112deg); }
.progress-circle.p32 .value-bar { transform: rotate(115deg); }
.progress-circle.p33 .value-bar { transform: rotate(119deg); }
.progress-circle.p34 .value-bar { transform: rotate(122deg); }
.progress-circle.p35 .value-bar { transform: rotate(126deg); }
.progress-circle.p36 .value-bar { transform: rotate(130deg); }
.progress-circle.p37 .value-bar { transform: rotate(133deg); }
.progress-circle.p38 .value-bar { transform: rotate(137deg); }
.progress-circle.p39 .value-bar { transform: rotate(140deg); }
.progress-circle.p40 .value-bar { transform: rotate(144deg); }
.progress-circle.p41 .value-bar { transform: rotate(148deg); }
.progress-circle.p42 .value-bar { transform: rotate(151deg); }
.progress-circle.p43 .value-bar { transform: rotate(155deg); }
.progress-circle.p44 .value-bar { transform: rotate(158deg); }
.progress-circle.p45 .value-bar { transform: rotate(162deg); }
.progress-circle.p46 .value-bar { transform: rotate(166deg); }
.progress-circle.p47 .value-bar { transform: rotate(169deg); }
.progress-circle.p48 .value-bar { transform: rotate(173deg); }
.progress-circle.p49 .value-bar { transform: rotate(176deg); }
.progress-circle.p50 .value-bar { transform: rotate(180deg); }
.progress-circle.p51 .value-bar { transform: rotate(184deg); }
.progress-circle.p52 .value-bar { transform: rotate(187deg); }
.progress-circle.p53 .value-bar { transform: rotate(191deg); }
.progress-circle.p54 .value-bar { transform: rotate(194deg); }
.progress-circle.p55 .value-bar { transform: rotate(198deg); }
.progress-circle.p56 .value-bar { transform: rotate(202deg); }
.progress-circle.p57 .value-bar { transform: rotate(205deg); }
.progress-circle.p58 .value-bar { transform: rotate(209deg); }
.progress-circle.p59 .value-bar { transform: rotate(212deg); }
.progress-circle.p60 .value-bar { transform: rotate(216deg); }
.progress-circle.p61 .value-bar { transform: rotate(220deg); }
.progress-circle.p62 .value-bar { transform: rotate(223deg); }
.progress-circle.p63 .value-bar { transform: rotate(227deg); }
.progress-circle.p64 .value-bar { transform: rotate(230deg); }
.progress-circle.p65 .value-bar { transform: rotate(234deg); }
.progress-circle.p66 .value-bar { transform: rotate(238deg); }
.progress-circle.p67 .value-bar { transform: rotate(241deg); }
.progress-circle.p68 .value-bar { transform: rotate(245deg); }
.progress-circle.p69 .value-bar { transform: rotate(248deg); }
.progress-circle.p70 .value-bar { transform: rotate(252deg); }
.progress-circle.p71 .value-bar { transform: rotate(256deg); }
.progress-circle.p72 .value-bar { transform: rotate(259deg); }
.progress-circle.p73 .value-bar { transform: rotate(263deg); }
.progress-circle.p74 .value-bar { transform: rotate(266deg); }
.progress-circle.p75 .value-bar { transform: rotate(270deg); }
.progress-circle.p76 .value-bar { transform: rotate(274deg); }
.progress-circle.p77 .value-bar { transform: rotate(277deg); }
.progress-circle.p78 .value-bar { transform: rotate(281deg); }
.progress-circle.p79 .value-bar { transform: rotate(284deg); }
.progress-circle.p80 .value-bar { transform: rotate(288deg); }
.progress-circle.p81 .value-bar { transform: rotate(292deg); }
.progress-circle.p82 .value-bar { transform: rotate(295deg); }
.progress-circle.p83 .value-bar { transform: rotate(299deg); }
.progress-circle.p84 .value-bar { transform: rotate(302deg); }
.progress-circle.p85 .value-bar { transform: rotate(306deg); }
.progress-circle.p86 .value-bar { transform: rotate(310deg); }
.progress-circle.p87 .value-bar { transform: rotate(313deg); }
.progress-circle.p88 .value-bar { transform: rotate(317deg); }
.progress-circle.p89 .value-bar { transform: rotate(320deg); }
.progress-circle.p90 .value-bar { transform: rotate(324deg); }
.progress-circle.p91 .value-bar { transform: rotate(328deg); }
.progress-circle.p92 .value-bar { transform: rotate(331deg); }
.progress-circle.p93 .value-bar { transform: rotate(335deg); }
.progress-circle.p94 .value-bar { transform: rotate(338deg); }
.progress-circle.p95 .value-bar { transform: rotate(342deg); }
.progress-circle.p96 .value-bar { transform: rotate(346deg); }
.progress-circle.p97 .value-bar { transform: rotate(349deg); }
.progress-circle.p98 .value-bar { transform: rotate(353deg); }
.progress-circle.p99 .value-bar { transform: rotate(356deg); }
.progress-circle.p100 .value-bar { transform: rotate(360deg); }

View File

@ -6,8 +6,8 @@
<stop offset="0" style="stop-color:#80D8FF"/>
<stop offset="0.16" style="stop-color:#88D1FF"/>
<stop offset="0.413" style="stop-color:#9FBEFE"/>
<stop offset="0.725" style="stop-color:#C4A0FD"/>
<stop offset="1" style="stop-color:#EA80FC"/>
<stop offset="0.725" style="stop-color:#FC5C7D"/>
<stop offset="1" style="stop-color:#FC5C7D"/>
</linearGradient>
<path style="fill:url(#SVGID_1_);" d="M462.622,512H49.378C22.151,512,0,489.85,0,462.623v-118.49c0-11.046,8.954-20,20-20
s20,8.954,20,20v118.49c0,5.171,4.207,9.377,9.378,9.377h413.244c5.171,0,9.378-4.207,9.378-9.377v-118.49c0-11.046,8.954-20,20-20

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1 @@
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(1 0 0 -1 0 -12146)" gradientUnits="userSpaceOnUse" x1="0" x2="512" y1="-12402" y2="-12402"><stop offset="0" stop-color="#9AB3FF"/><stop offset="1" stop-color="#FC5C7D"/></linearGradient><path d="m512 256c0 141.386719-114.613281 256-256 256s-256-114.613281-256-256 114.613281-256 256-256 256 114.613281 256 256zm0 0" fill="url(#a)"/><g fill="#fff"><path d="m256 56c-110.28125 0-200 89.71875-200 200s89.71875 200 200 200 200-89.71875 200-200-89.71875-200-200-200zm0 370c-93.738281 0-170-76.261719-170-170s76.261719-170 170-170 170 76.261719 170 170-76.261719 170-170 170zm0 0"/><path d="m324.179688 187.820312c-5.859376-5.855468-15.355469-5.855468-21.214844 0l-46.964844 46.964844-46.964844-46.964844c-5.859375-5.855468-15.355468-5.855468-21.214844 0-5.855468 5.859376-5.855468 15.355469 0 21.214844l46.964844 46.964844-46.964844 46.964844c-5.855468 5.859375-5.855468 15.355468 0 21.214844 2.929688 2.929687 6.769532 4.394531 10.605469 4.394531 3.839844 0 7.679688-1.464844 10.605469-4.394531l46.96875-46.964844 46.964844 46.964844c2.929687 2.929687 6.769531 4.394531 10.605468 4.394531 3.839844 0 7.679688-1.464844 10.609376-4.394531 5.855468-5.859376 5.855468-15.355469 0-21.214844l-46.964844-46.964844 46.964844-46.964844c5.855468-5.859375 5.855468-15.355468 0-21.214844zm0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -7,10 +7,11 @@
<script src="web-app.js"></script>
<link rel="icon" href="spotiflyer.svg" type="image/icon type">
<link rel="stylesheet" href="styles.css">
<link href="css-circular-prog-bar.css" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=RocknRoll+One&display=swap" rel="stylesheet">
</head>
<body>
<div style="height: 100%;display: flex; align-items: center;flex-direction: column" id="root"></div>
<div style="display: flex;flex-direction: column; height: inherit; color: white;" id="root"></div>
</body>
</html>

View File

@ -2,6 +2,16 @@
font-family: pristine;
src: url("pristine_script.ttf");
}
@media (max-width: 600px) {
/* CSS HERE ONLY ON PHONE */
.searchBox:hover > .searchInput {
width: 150px;
padding: 0 6px;
}
.info-banners {
flex-direction: column;
}
}
html {
background-image: url("header-dark.jpg");
font-family: Lora,Helvetica Neue,Helvetica,Arial,sans-serif;
@ -20,6 +30,8 @@ body, html {
}
#appName{
font-family: pristine, cursive;
font-weight: 100;
text-shadow: 0.3px 0.5px #ffffff;
}
.headingTitle{
text-align: center;
@ -30,6 +42,42 @@ body, html {
color: rgba(255, 255, 255, 1);
box-shadow: 0 5px 15px rgb(105, 44, 143);
}
/*Loading Spinner*/
.lds-ring {
align-items: center;
justify-content: center;
display: flex;
}
.lds-ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 3.5em;
height: 3.5em;
border: 8px solid #fff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #fff transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.button {
text-decoration: none;
color: rgba(255, 255, 255, 0.8);
@ -191,9 +239,3 @@ body, html {
transform: scale3D(0, 0, 1);
}
}
@media screen and (max-width: 620px) {
.searchBox:hover > .searchInput {
width: 150px;
padding: 0 6px;
}
}