Intial Project Commit
first commit to get all the project files in there
24
.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
/.phpunit.cache
|
||||
/node_modules
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/.fleet
|
||||
/.idea
|
||||
/.vscode
|
||||
|
||||
/.parcel-cache
|
||||
|
||||
.env.local
|
||||
/.env.local.php
|
||||
/.env.*.local
|
||||
/.nova
|
||||
|
||||
/assets/audio/tapes
|
||||
|
||||
*.DS_Store
|
||||
*.codekit3
|
182
assets/css/front/index.css
Normal file
|
@ -0,0 +1,182 @@
|
|||
main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
transform-origin: 0 0;
|
||||
perspective: 500px;
|
||||
top: 50px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header {
|
||||
padding-top: 5px;
|
||||
background: rgba(6, 9, 41, 0.5);
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
div.audio-progress {
|
||||
width: 0;
|
||||
height: 1px;
|
||||
background: var(--primary);
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
article.tape-select {
|
||||
transition: all 1s cubic-bezier(0.83, 0.05, 0.28, 1);
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
backface-visibility: hidden;
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
article.tape-tracklist {
|
||||
transition: all 1s cubic-bezier(0.83, 0.05, 0.28, 1);
|
||||
max-width: 800px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
position: absolute;
|
||||
backface-visibility: hidden;
|
||||
top: 5px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
img.the-logo {
|
||||
width: 50px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
img.covers {
|
||||
padding-bottom: 2px;
|
||||
border-radius: 3px;
|
||||
width: 92px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img#tape-cover {
|
||||
width: 350px;
|
||||
margin: 0 auto;
|
||||
display: block;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
h1#tape-title {
|
||||
width: 300px;
|
||||
margin: 15px auto;
|
||||
}
|
||||
|
||||
section#playlist {
|
||||
width: 300px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
section#playlist div {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
font-size: 1em;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
transition: all 0.5s cubic-bezier(0.83, 0.05, 0.28, 1);
|
||||
}
|
||||
|
||||
section#playlist div label:nth-child(2) {
|
||||
font-weight: bold;
|
||||
color: var(--highlight);
|
||||
}
|
||||
|
||||
section#playlist div label {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
button.selectBtn {
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
div#tape-controls {
|
||||
background: var(--white);
|
||||
width: 300px;
|
||||
position: fixed;
|
||||
z-index: 500;
|
||||
height: 35px;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
transition: all 1s cubic-bezier(0.83, 0.05, 0.28, 1);
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
border: 3px solid var(--white);
|
||||
}
|
||||
|
||||
img.tape-control-button {
|
||||
width: 35px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
label.control-text {
|
||||
width: 73.6%;
|
||||
color: var(--secondary);
|
||||
position: relative;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.65em;
|
||||
font-weight: bold;
|
||||
height: 100%;
|
||||
line-height: 100%;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
background: var(--highlight);
|
||||
border-radius: 3px;
|
||||
padding: 0 5px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.front {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
|
||||
.back-right {
|
||||
transform: rotateY(-180deg);
|
||||
}
|
||||
|
||||
.back-left {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.playing {
|
||||
background: var(--white);
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.not-playing {
|
||||
background: none;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.label-playing {
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
.label-notplaying {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.control-open {
|
||||
bottom: -17.5px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.control-closed {
|
||||
bottom: -55px;
|
||||
opacity: 0;
|
||||
}
|
5
assets/css/front/start.css
Normal file
|
@ -0,0 +1,5 @@
|
|||
@import "../global/colors.css";
|
||||
@import "../global/forms.css";
|
||||
@import "../global/typography.css";
|
||||
@import "../global/frame.css";
|
||||
@import "index.css";
|
13
assets/css/global/colors.css
Normal file
|
@ -0,0 +1,13 @@
|
|||
:root {
|
||||
/* BASE COLORS */
|
||||
--primary: #ff0505;
|
||||
--secondary: #03061e;
|
||||
--highlight: #7ac1df;
|
||||
--white: #efebe3;
|
||||
--grey: #abb7b7;
|
||||
--black: #32302f;
|
||||
--error: #b62520;
|
||||
--silence: #ea6010;
|
||||
--suspend: #fb263a;
|
||||
--primary-rgb: 20 13 13;
|
||||
}
|
BIN
assets/css/global/fonts/Rubik/rubik-bold.ttf
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-bold.woff
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-bold.woff2
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-light.ttf
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-light.woff
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-light.woff2
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-medium.ttf
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-medium.woff
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-medium.woff2
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-regular.ttf
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-regular.woff
Normal file
BIN
assets/css/global/fonts/Rubik/rubik-regular.woff2
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskBold.ttf
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskBold.woff
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskBold.woff2
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskRegular.ttf
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskRegular.woff
Normal file
BIN
assets/css/global/fonts/ahg/AlteHaasGroteskRegular.woff2
Normal file
47
assets/css/global/forms.css
Normal file
|
@ -0,0 +1,47 @@
|
|||
input[type="email"],
|
||||
input[type="password"],
|
||||
input[type="text"] {
|
||||
border: 0;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
font: 18px var(--base-type);
|
||||
display: inline-block;
|
||||
background: var(--white);
|
||||
color: var(--primary);
|
||||
transition: all 0.2s linear;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus {
|
||||
outline: solid var(--highlight);
|
||||
background-color: var(--highlight);
|
||||
}
|
||||
|
||||
textarea {
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
color: var(--primary);
|
||||
background: var(--white);
|
||||
}
|
||||
|
||||
button,
|
||||
input[type="submit"] {
|
||||
color: var(--white);
|
||||
font: 1em var(--base-type);
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
transition: all 0.3s linear;
|
||||
padding: 0 0 10px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
select {
|
||||
font: 20px var(--base-type);
|
||||
border-radius: 5px;
|
||||
border: 1px solid var(--primary);
|
||||
appearance: none;
|
||||
color: var(--primary);
|
||||
background: var(--secondary);
|
||||
}
|
226
assets/css/global/frame.css
Normal file
|
@ -0,0 +1,226 @@
|
|||
html {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font: 400 1em/1em var(--base-type);
|
||||
}
|
||||
|
||||
html body {
|
||||
background: var(--secondary);
|
||||
color: var(--white);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--highlight);
|
||||
text-decoration: none;
|
||||
transition: all 0.2s linear;
|
||||
/*
|
||||
border-bottom: 1px solid var(--white);
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
strong {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
header > div:nth-child(1) {
|
||||
display: grid;
|
||||
grid-template-columns: 200px 1fr 40px;
|
||||
padding: 10px;
|
||||
gap: 10px;
|
||||
height: 200px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header > div span {
|
||||
font-size: 3em;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
bottom: 25px;
|
||||
width: 50%;
|
||||
line-height: 0.8em;
|
||||
}
|
||||
|
||||
header > div img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
header > div a {
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
header > div i {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
header > div nav {
|
||||
background: var(--black);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.system-notice-error {
|
||||
background: var(--error);
|
||||
color: var(--white);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
div.system-notice-message {
|
||||
background: var(--highlight);
|
||||
color: var(--black);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
main > section > article {
|
||||
width: 80%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
/* NAV */
|
||||
|
||||
#main-nav {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--black);
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
label[for="element-toggle"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#element-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#element-toggle:not(:checked) ~ #main-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a.nav-links {
|
||||
border-bottom: none;
|
||||
font-size: 40px;
|
||||
color: var(--highlight);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* GLOBALS */
|
||||
|
||||
a:hover {
|
||||
/*
|
||||
border-bottom: 1px solid var(--secondary);
|
||||
*/
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre;
|
||||
background: var(--secondary);
|
||||
}
|
||||
|
||||
code {
|
||||
background: var(--secondary);
|
||||
color: var(--primary);
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
sup {
|
||||
background: var(--black);
|
||||
color: var(--white);
|
||||
padding: 2px;
|
||||
border-radius: 3px;
|
||||
vertical-align: baseline;
|
||||
font-family: var(--mono-type);
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
height: 90%;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.location-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.location-image {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
display: inline-block;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
footer {
|
||||
width: 100%;
|
||||
color: var(--primary);
|
||||
background: var(--secondary);
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
footer > div:nth-child(1) {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
padding: 10px;
|
||||
gap: 10px;
|
||||
height: 200px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/*
|
||||
responsive
|
||||
*/
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
header > div:nth-child(1) {
|
||||
}
|
||||
|
||||
header > div nav {
|
||||
bottom: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 960px) {
|
||||
header > div:nth-child(1) {
|
||||
grid-template-columns: 150px 65% 1fr;
|
||||
height: 150px;
|
||||
}
|
||||
|
||||
header > div nav {
|
||||
bottom: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
}
|
54
assets/css/global/typography.css
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* RUBIK */
|
||||
@font-face {
|
||||
font-family: AlteHaasGrotesk;
|
||||
src: url("fonts/ahg/AlteHaasGroteskRegular.ttf") format("truetype"),
|
||||
url("fonts/ahg/AlteHaasGroteskRegular.woff") format("woff"),
|
||||
url("fonts/ahg/AlteHaasGroteskRegular.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: AlteHaasGrotesk;
|
||||
src: url("fonts/ahg/AlteHaasGroteskBold.ttf") format("truetype"),
|
||||
url("fonts/ahg/AlteHaasGroteskBold.woff") format("woff"),
|
||||
url("fonts/ahg/AlteHaasGroteskBold.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
--base-type: AlteHaasGrotesk, helvetica, arial, sans-serif;
|
||||
--mono-type: "Lucida Console", monaco, monospace;
|
||||
}
|
||||
|
||||
p {
|
||||
font: 400 1.2em/1.1em var(--base-type);
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: 600;
|
||||
font-kerning: normal;
|
||||
letter-spacing: -3px;
|
||||
text-transform: uppercase;
|
||||
line-height: 0.75em;
|
||||
margin: 0;
|
||||
overflow-wrap: break-word;
|
||||
color: var(--highlight);
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-transform: lowercase;
|
||||
font-size: 1.5em;
|
||||
font-weight: 500;
|
||||
line-height: 0.8em;
|
||||
color: var(--primary);
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.5em;
|
||||
font-weight: 300;
|
||||
}
|
BIN
assets/images/global/btn_back.png
Normal file
After Width: | Height: | Size: 1,022 B |
BIN
assets/images/global/btn_forward.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
assets/images/global/btn_play.png
Normal file
After Width: | Height: | Size: 1 KiB |
7
assets/images/global/close.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by Pixelmator Pro 3.3.8 -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Path" fill="none" stroke="none" d="M 0 0 L 24 0 L 24 24 L 0 24 Z"/>
|
||||
<path id="path1" fill="none" stroke="#efebe3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M 18 6 L 6 18"/>
|
||||
<path id="path2" fill="none" stroke="#efebe3" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M 6 6 L 18 18"/>
|
||||
</svg>
|
After Width: | Height: | Size: 523 B |
8
assets/images/global/icon-search.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by Pixelmator Pro 3.3.8 -->
|
||||
<svg width="101" height="100" viewBox="0 0 101 100" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="Group-copy">
|
||||
<path id="Path-copy-2" fill="none" stroke="#efebe3" stroke-width="8.777778" stroke-linecap="round" stroke-linejoin="round" d="M 11 41.722221 C 11 58.68964 24.754808 72.444443 41.722221 72.444443 C 58.68964 72.444443 72.444443 58.68964 72.444443 41.722221 C 72.444443 24.754807 58.68964 11 41.722221 11 C 24.754808 11 11 24.754807 11 41.722221"/>
|
||||
<path id="Path-copy" fill="none" stroke="#efebe3" stroke-width="8.777778" stroke-linecap="round" stroke-linejoin="round" d="M 90 90 L 63.666668 63.666668"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 729 B |
5
assets/images/global/logo-dark.svg
Normal file
After Width: | Height: | Size: 5.8 KiB |
5
assets/images/global/logo-light.svg
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
assets/images/global/logo-primary.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
assets/images/global/logo-secondary.png
Normal file
After Width: | Height: | Size: 54 KiB |
8
assets/images/global/menu.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by Pixelmator Pro 3.3.8 -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Path" fill="none" stroke="none" d="M 0 0 L 24 0 L 24 24 L 0 24 Z"/>
|
||||
<path id="path1" fill="none" stroke="#140d0d" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M 4 6 L 20 6"/>
|
||||
<path id="path2" fill="none" stroke="#140d0d" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M 4 12 L 20 12"/>
|
||||
<path id="path3" fill="none" stroke="#140d0d" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" d="M 4 18 L 20 18"/>
|
||||
</svg>
|
After Width: | Height: | Size: 658 B |
BIN
assets/images/global/special-trash.jpg
Normal file
After Width: | Height: | Size: 648 KiB |
6
assets/images/global/status-silence.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by Pixelmator Pro 3.3.8 -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Path" fill="none" stroke="none" d="M 0 0 L 24 0 L 24 24 L 0 24 Z"/>
|
||||
<path id="path1" fill="#ea6010" stroke="none" d="M 17 3.34 C 21.1674 5.746208 23.030024 10.779379 21.433001 15.318825 C 19.835976 19.858273 15.232252 22.616514 10.476249 21.883377 C 5.720245 21.15024 2.160861 17.133654 2.005 12.324 L 2 12 L 2.005 11.676 C 2.118919 8.162982 4.068822 4.967705 7.140892 3.259882 C 10.212963 1.552061 13.95609 1.582479 17 3.34 Z M 15 14 L 9 14 L 8.883 14.007 C 8.37995 14.066836 8.001114 14.493402 8.001114 15 C 8.001114 15.506598 8.37995 15.933164 8.883 15.993 L 9 16 L 15 16 L 15.117 15.993 C 15.62005 15.933164 15.998886 15.506598 15.998886 15 C 15.998886 14.493402 15.62005 14.066836 15.117 14.007 L 15 14 Z M 9.01 9 L 8.883 9.007 C 8.37995 9.066836 8.001114 9.493402 8.001114 10 C 8.001114 10.506598 8.37995 10.933164 8.883 10.993 L 9 11 L 9.127 10.993 C 9.630051 10.933164 10.008885 10.506598 10.008885 10 C 10.008885 9.493402 9.630051 9.066836 9.127 9.007 L 9.01 9 Z M 15.01 9 L 14.883 9.007 C 14.37995 9.066836 14.001114 9.493402 14.001114 10 C 14.001114 10.506598 14.37995 10.933164 14.883 10.993 L 15 11 L 15.127 10.993 C 15.630051 10.933164 16.008886 10.506598 16.008886 10 C 16.008886 9.493402 15.630051 9.066836 15.127 9.007 L 15.01 9 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
6
assets/images/global/status-suspend.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by Pixelmator Pro 3.3.8 -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="Path" fill="none" stroke="none" d="M 0 0 L 24 0 L 24 24 L 0 24 Z"/>
|
||||
<path id="path1" fill="#fb263a" stroke="none" d="M 17 3.34 C 21.1674 5.746208 23.030024 10.779379 21.433001 15.318825 C 19.835976 19.858273 15.232252 22.616514 10.476249 21.883377 C 5.720245 21.15024 2.160861 17.133654 2.005 12.324 L 2 12 L 2.005 11.676 C 2.118919 8.162982 4.068822 4.967705 7.140892 3.259882 C 10.212963 1.552061 13.95609 1.582479 17 3.34 Z M 15.57 13.502 C 13.250918 13.340779 10.940379 13.918414 8.97 15.152 C 8.501662 15.444711 8.359289 16.061663 8.652 16.530001 C 8.944711 16.998337 9.561663 17.140711 10.03 16.848 C 11.642129 15.838702 13.53257 15.366092 15.43 15.498 C 15.98118 15.53666 16.459339 15.121181 16.497999 14.57 C 16.536659 14.01882 16.12118 13.54066 15.57 13.502 Z M 9.01 9 L 8.883 9.007 C 8.37995 9.066836 8.001114 9.493402 8.001114 10 C 8.001114 10.506598 8.37995 10.933164 8.883 10.993 L 9 11 L 9.127 10.993 C 9.630051 10.933164 10.008885 10.506598 10.008885 10 C 10.008885 9.493402 9.630051 9.066836 9.127 9.007 L 9.01 9 Z M 15.01 9 L 14.883 9.007 C 14.37995 9.066836 14.001114 9.493402 14.001114 10 C 14.001114 10.506598 14.37995 10.933164 14.883 10.993 L 15 11 L 15.127 10.993 C 15.630051 10.933164 16.008886 10.506598 16.008886 10 C 16.008886 9.493402 15.630051 9.066836 15.127 9.007 L 15.01 9 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
BIN
assets/images/global/tape-icons.png
Normal file
After Width: | Height: | Size: 1 KiB |
171
assets/script/RecordPlayer.js
Normal file
|
@ -0,0 +1,171 @@
|
|||
export default class RecordPlayer {
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
this.audio = null;
|
||||
this.tracklist = "";
|
||||
this.currentTrackIndex = -1;
|
||||
this.trackListCount = 0;
|
||||
this.playing = false;
|
||||
this.controlText = document.querySelector(".control-text");
|
||||
this.tapePlaylist = document.getElementById("playlist");
|
||||
this.nextBtn = document.getElementById("control-next");
|
||||
this.backBtn = document.getElementById("control-back");
|
||||
this.progress = document.querySelector(".audio-progress");
|
||||
|
||||
this.setUpAudio();
|
||||
}
|
||||
|
||||
setUpAudio() {
|
||||
let self = this;
|
||||
//create element
|
||||
this.audio = document.createElement("audio");
|
||||
this.audio.controls = false;
|
||||
//set event listners
|
||||
this.audio.addEventListener(
|
||||
"timeupdate",
|
||||
(e) => this.handleTimeUpdate(e),
|
||||
false
|
||||
);
|
||||
|
||||
this.audio.addEventListener("ended", () => self.control("next"), false);
|
||||
|
||||
this.nextBtn.addEventListener("click", () => {
|
||||
self.control("next");
|
||||
});
|
||||
|
||||
this.backBtn.addEventListener("click", () => {
|
||||
self.control("back");
|
||||
});
|
||||
}
|
||||
|
||||
setTrackList(tracklist) {
|
||||
this.tracklist = tracklist;
|
||||
this.trackListCount = this.tracklist.length;
|
||||
this.buildPlaylist(this.tracklist);
|
||||
}
|
||||
|
||||
buildPlaylist(tracklist) {
|
||||
//clear playlist
|
||||
this.tapePlaylist.innerHTML = "";
|
||||
//build playlist ui
|
||||
for (var i = 0, length = tracklist.length; i < length; i++) {
|
||||
let sleeve = document.createElement("div");
|
||||
let select = document.createElement("button");
|
||||
sleeve.className = "sleeve";
|
||||
sleeve.id = "sleeve_" + i;
|
||||
select.id = tracklist[i].file;
|
||||
select.className = "selectBtn";
|
||||
let recordTitle = document.createElement("label");
|
||||
recordTitle.id = "title_" + i;
|
||||
recordTitle.innerText = tracklist[i].title;
|
||||
let recordAlbum = document.createElement("label");
|
||||
recordAlbum.id = "album_" + i;
|
||||
recordAlbum.innerText = tracklist[i].album;
|
||||
let recordArtist = document.createElement("label");
|
||||
recordArtist.id = "artist_" + i;
|
||||
recordArtist.innerText = tracklist[i].artist;
|
||||
|
||||
sleeve.appendChild(select);
|
||||
sleeve.appendChild(recordTitle);
|
||||
sleeve.appendChild(recordAlbum);
|
||||
sleeve.appendChild(recordArtist);
|
||||
|
||||
this.tapePlaylist.appendChild(sleeve);
|
||||
|
||||
select.addEventListener("click", (e) => this.handleButton(e), false);
|
||||
}
|
||||
}
|
||||
|
||||
playRecord(file) {
|
||||
for (var i = 0, length = this.tracklist.length; i < length; i++) {
|
||||
let sleeve = document.getElementById("sleeve_" + i);
|
||||
let album = document.getElementById("album_" + i);
|
||||
let artist = document.getElementById("artist_" + i);
|
||||
//handle pause state
|
||||
if (file == this.tracklist[i].file) {
|
||||
//if index is same, play our pause
|
||||
if (i === this.currentTrackIndex) {
|
||||
if (this.playing) {
|
||||
this.audio.pause();
|
||||
sleeve.style.opacity = 0.5;
|
||||
this.playing = false;
|
||||
return;
|
||||
} else {
|
||||
console.log("play");
|
||||
this.audio.play();
|
||||
sleeve.style.opacity = 1;
|
||||
this.playing = true;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
//if index is different play next track
|
||||
this.currentTrackIndex = i;
|
||||
this.controlText.innerText = this.tracklist[i].title;
|
||||
sleeve.classList.add("playing");
|
||||
sleeve.classList.remove("not-playing");
|
||||
album.classList.add("label-playing");
|
||||
album.classList.remove("label-notplaying");
|
||||
artist.classList.add("label-playing");
|
||||
artist.classList.remove("label-notplaying");
|
||||
}
|
||||
} else {
|
||||
sleeve.classList.add("not-playing");
|
||||
sleeve.classList.remove("playing");
|
||||
album.classList.add("label-notplaying");
|
||||
artist.classList.add("label-notplaying");
|
||||
}
|
||||
}
|
||||
|
||||
let record =
|
||||
"assets/audio/tapes/" +
|
||||
this.tracklist[this.currentTrackIndex].tape +
|
||||
"/" +
|
||||
this.tracklist[this.currentTrackIndex].file;
|
||||
|
||||
this.audio.src = record;
|
||||
this.audio.volume = 0.5;
|
||||
this.playing = true;
|
||||
this.audio.play();
|
||||
}
|
||||
|
||||
control(task) {
|
||||
this.playing = false;
|
||||
let fresh = "";
|
||||
switch (task) {
|
||||
case "next":
|
||||
fresh = this.currentTrackIndex + 1;
|
||||
if (fresh > this.tracklist.length - 1) fresh = 0;
|
||||
|
||||
break;
|
||||
case "back":
|
||||
fresh = this.currentTrackIndex - 1;
|
||||
if (fresh < 0) fresh = this.tracklist.length - 1;
|
||||
break;
|
||||
}
|
||||
this.playRecord(this.tracklist[fresh].file);
|
||||
}
|
||||
|
||||
//event handlers
|
||||
handleButton(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
this.playRecord(e.target.id);
|
||||
}
|
||||
|
||||
handleTimeUpdate(e) {
|
||||
var s = parseInt(this.audio.currentTime % 60);
|
||||
if (s < 10) {
|
||||
s = "0" + s;
|
||||
}
|
||||
var m = parseInt((this.audio.currentTime / 60) % 60);
|
||||
if (m < 10) {
|
||||
m = "0" + m;
|
||||
}
|
||||
|
||||
var currentProgress = this.audio.currentTime / this.audio.duration;
|
||||
var visProgress = 350 * currentProgress;
|
||||
this.progress.style.width = visProgress + "px";
|
||||
}
|
||||
}
|
9
assets/script/Start.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import TapeDeck from "./TapeDeck.js";
|
||||
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
function () {
|
||||
new TapeDeck();
|
||||
},
|
||||
false
|
||||
);
|
74
assets/script/TapeDeck.js
Normal file
|
@ -0,0 +1,74 @@
|
|||
import RecordPlayer from "./RecordPlayer.js";
|
||||
|
||||
export default class TapeDeck {
|
||||
//--------------------------
|
||||
// constructor
|
||||
//--------------------------
|
||||
constructor() {
|
||||
let self = this;
|
||||
this.rp = new RecordPlayer();
|
||||
this.tapeSelect = document.querySelector(".tape-select");
|
||||
this.tapeTracklist = document.querySelector(".tape-tracklist");
|
||||
this.tapeCover = document.getElementById("tape-cover");
|
||||
this.tapeTitle = document.getElementById("tape-title");
|
||||
this.tapeControls = document.getElementById("tape-controls");
|
||||
this.logo = document.querySelector(".the-logo");
|
||||
this.logo.addEventListener("click", (e) => {
|
||||
self.tapeSelect.classList.remove("back-left");
|
||||
self.tapeSelect.classList.add("front");
|
||||
self.tapeTracklist.classList.remove("front");
|
||||
self.tapeTracklist.classList.add("back-right");
|
||||
self.tapeControls.classList.add("control-closed");
|
||||
self.tapeControls.classList.remove("control-open");
|
||||
});
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", "api/tapes/list", true);
|
||||
request.onload = () => {
|
||||
if (request.status == 200) {
|
||||
let response = JSON.parse(request["response"]);
|
||||
//console.log(response);
|
||||
} else {
|
||||
let error = JSON.parse(request["response"]);
|
||||
consolel.log();
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
//make images buttons for playlist retrieval
|
||||
var covers = document.querySelectorAll(".covers");
|
||||
for (var i = 0, length = covers.length; i < length; i++) {
|
||||
covers[i].addEventListener("click", (e) => this.handleCovers(e), false);
|
||||
}
|
||||
}
|
||||
|
||||
//event handlers
|
||||
|
||||
handleCovers(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
let self = this;
|
||||
request.open("GET", "api/tapes/tracklist/" + e.target.id, true);
|
||||
request.onload = () => {
|
||||
if (request.status == 200) {
|
||||
let response = JSON.parse(request["response"]);
|
||||
//once playlist is loaded, flip to list mode
|
||||
self.tapeSelect.classList.remove("front");
|
||||
self.tapeSelect.classList.add("back-left");
|
||||
self.tapeTracklist.classList.remove("back-right");
|
||||
self.tapeTracklist.classList.add("front");
|
||||
self.tapeCover.src = e.target.src;
|
||||
self.tapeTitle.innerText = "VOL. " + response[0].tape;
|
||||
//open tape controls
|
||||
self.tapeControls.classList.remove("control-closed");
|
||||
self.tapeControls.classList.add("control-open");
|
||||
//set up player
|
||||
self.rp.setTrackList(response);
|
||||
} else {
|
||||
let error = JSON.parse(request["response"]);
|
||||
}
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
}
|
1311
assets/script/third/anime.es.js
Normal file
10
brain/Loader.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
spl_autoload_register(function ($className) {
|
||||
$file = dirname(__DIR__) . "\\" . $className . ".php";
|
||||
$file = str_replace("\\", DIRECTORY_SEPARATOR, $file);
|
||||
//echo $file;
|
||||
if (file_exists($file)) {
|
||||
include $file;
|
||||
}
|
||||
});
|
33
brain/controllers/APIController.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace brain\controllers;
|
||||
|
||||
class APIController
|
||||
{
|
||||
protected $tapes;
|
||||
public function __construct()
|
||||
{
|
||||
$this->tapes = new TapesAPI();
|
||||
}
|
||||
|
||||
public function handleRoute($params)
|
||||
{
|
||||
if (isset($params[1])) {
|
||||
//grap appropriate api class based on request params
|
||||
switch ($params[1]) {
|
||||
case "tapes":
|
||||
//run the request
|
||||
return $this->tapes->handleRequest($params);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return json_encode([
|
||||
"message" => "NO API Identifier provided",
|
||||
"type" => "ERROR",
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
15
brain/controllers/IndexController.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace brain\controllers;
|
||||
|
||||
class IndexController
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function start()
|
||||
{
|
||||
echo "got it";
|
||||
}
|
||||
}
|
36
brain/controllers/RouteController.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace brain\controllers;
|
||||
|
||||
use brain\controllers\APIController;
|
||||
|
||||
class RouteController
|
||||
{
|
||||
protected $api;
|
||||
public function __construct()
|
||||
{
|
||||
$this->api = new APIController();
|
||||
}
|
||||
|
||||
public function start($request)
|
||||
{
|
||||
$request = ltrim($request, " / ");
|
||||
$params = explode("/", $request);
|
||||
if ($params[0] == "") {
|
||||
require "brain/views/front.php";
|
||||
} else {
|
||||
switch ($params[0]) {
|
||||
case "api":
|
||||
//get api controller to handle route
|
||||
$result = $this->api->handleRoute($params);
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo $result;
|
||||
break;
|
||||
default:
|
||||
http_response_code(404);
|
||||
require "brain/views/404.php";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
96
brain/controllers/TapesAPI.php
Normal file
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
|
||||
namespace brain\controllers;
|
||||
|
||||
use Kiwilan\Audio\Audio;
|
||||
|
||||
class TapesAPI
|
||||
{
|
||||
private $tapesDir = "assets/audio/tapes";
|
||||
protected $params;
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function handleRequest($params)
|
||||
{
|
||||
if (isset($params[2])) {
|
||||
switch ($params[2]) {
|
||||
case "list":
|
||||
return $this->getList();
|
||||
break;
|
||||
case "tracklist":
|
||||
return $this->getTrackList($params[3]);
|
||||
break;
|
||||
default:
|
||||
return json_encode([
|
||||
"message" => "This method does not exist",
|
||||
"type" => "ERROR",
|
||||
]);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return json_encode([
|
||||
"message" => "This method does not exist",
|
||||
"type" => "ERROR",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTrackList($id)
|
||||
{
|
||||
$folder = $this->tapesDir . "/" . urldecode($id);
|
||||
$contents = scandir($folder);
|
||||
$tracklist = [];
|
||||
foreach ($contents as $key => $value) {
|
||||
$path = realpath($folder . DIRECTORY_SEPARATOR . $value);
|
||||
if (!is_dir($path) && $value != ".DS_Store") {
|
||||
$item = explode("/", $path);
|
||||
if ($item[9] != "cover.jpg") {
|
||||
$tags = Audio::read($path);
|
||||
//reading cover data is lil funky, so off for now
|
||||
//$cover = $tags->getCover();
|
||||
//$image = $cover->getContents();
|
||||
$album = "";
|
||||
if (empty($tags->getAlbum())) {
|
||||
$album = "None";
|
||||
} else {
|
||||
$album = $tags->getAlbum();
|
||||
}
|
||||
array_push($tracklist, [
|
||||
"title" => $tags->getTitle(),
|
||||
"album" => $album,
|
||||
"artist" => $tags->getArtist(),
|
||||
"time" => $tags->getDuration(),
|
||||
"file" => $item[9],
|
||||
"tape" => $item[8],
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
usort($tracklist, function ($a, $b) {
|
||||
return strnatcasecmp($a["file"], $b["file"]);
|
||||
});
|
||||
return json_encode($tracklist);
|
||||
}
|
||||
|
||||
public function getList($obj = false)
|
||||
{
|
||||
$current = scandir($this->tapesDir);
|
||||
$tapeList = [];
|
||||
foreach ($current as $key => $value) {
|
||||
$path = realpath($this->tapesDir . DIRECTORY_SEPARATOR . $value);
|
||||
if (!is_dir($path) && $value != ".DS_Store") {
|
||||
$results[] = $path;
|
||||
} elseif ($value != "." && $value != ".." && $value != ".DS_Store") {
|
||||
$titles = explode("/", $path);
|
||||
array_push($tapeList, ["path" => $path, "title" => $titles[8]]);
|
||||
}
|
||||
}
|
||||
if (!$obj) {
|
||||
return json_encode($tapeList);
|
||||
} else {
|
||||
return $tapeList;
|
||||
}
|
||||
}
|
||||
}
|
18
brain/views/404.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
include "parts/top.php"; ?>
|
||||
|
||||
<body>
|
||||
<main>
|
||||
<article class="splash-box">
|
||||
<img class="logo-splash" src="assets/images/global/logo-primary.png" />
|
||||
|
||||
<h1>Uh Oh</h1>
|
||||
|
||||
<p>
|
||||
This ain't it. Go back!
|
||||
</p>
|
||||
</article>
|
||||
</main>
|
||||
|
||||
<?php include "parts/bottom.php"; ?>
|
39
brain/views/front.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
use brain\controllers\TapesAPI;
|
||||
|
||||
$tapes = new TapesAPI();
|
||||
$covers = $tapes->getList(true);
|
||||
include "parts/top.php";
|
||||
?>
|
||||
<header>
|
||||
<img class="the-logo" src="assets/images/global/logo-primary.png" />
|
||||
<div class="audio-progress"></div>
|
||||
</header>
|
||||
<div id="tape-controls" class="control-closed">
|
||||
<img id="control-back" class="tape-control-button" src='assets/images/global/btn_back.png' />
|
||||
<label class="control-text">NOTHING PLAYING</label>
|
||||
<img id="control-next" class="tape-control-button" src='assets/images/global/btn_forward.png' />
|
||||
</div>
|
||||
<main>
|
||||
<article class="tape-select front">
|
||||
<?php foreach ($covers as $cover) {
|
||||
$title = $cover["title"]; ?>
|
||||
|
||||
<img id="<?php echo urlencode($title); ?>" class="covers" src="
|
||||
<?php echo "/assets/audio/tapes/" . $title . "/cover.jpg"; ?>" />
|
||||
|
||||
<?php
|
||||
//end for each loop
|
||||
} ?>
|
||||
</article>
|
||||
<article class="tape-tracklist back-right">
|
||||
|
||||
<img id="tape-cover" src='' />
|
||||
<h1 id="tape-title"></h1>
|
||||
<section id="playlist"></section>
|
||||
|
||||
</article>
|
||||
|
||||
</main>
|
||||
<?php include "parts/bottom.php"; ?>
|
4
brain/views/parts/bottom.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<script type="module" src="/assets/script/Start.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
17
brain/views/parts/top.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="theme-color" content="#03061e" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>
|
||||
The Vicious Tapes
|
||||
</title>
|
||||
<link rel="stylesheet" type="text/css" href="assets/css/front/start.css?=sdfsdf">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
0
|
||||
</script>
|
5
composer.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"require": {
|
||||
"kiwilan/php-audio": "^4.0"
|
||||
}
|
||||
}
|
170
composer.lock
generated
Normal file
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "462518448f6c07a1a14fd4cba92297f2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "james-heinrich/getid3",
|
||||
"version": "v1.9.23",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/JamesHeinrich/getID3.git",
|
||||
"reference": "06c7482532ff2b3f9111b011d880ca6699c8542b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/JamesHeinrich/getID3/zipball/06c7482532ff2b3f9111b011d880ca6699c8542b",
|
||||
"reference": "06c7482532ff2b3f9111b011d880ca6699c8542b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"php-parallel-lint/php-parallel-lint": "^1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-SimpleXML": "SimpleXML extension is required to analyze RIFF/WAV/BWF audio files (also requires `ext-libxml`).",
|
||||
"ext-com_dotnet": "COM extension is required when loading files larger than 2GB on Windows.",
|
||||
"ext-ctype": "ctype extension is required when loading files larger than 2GB on 32-bit PHP (also on 64-bit PHP on Windows) or executing `getid3_lib::CopyTagsToComments`.",
|
||||
"ext-dba": "DBA extension is required to use the DBA database as a cache storage.",
|
||||
"ext-exif": "EXIF extension is required for graphic modules.",
|
||||
"ext-iconv": "iconv extension is required to work with different character sets (when `ext-mbstring` is not available).",
|
||||
"ext-json": "JSON extension is required to analyze Apple Quicktime videos.",
|
||||
"ext-libxml": "libxml extension is required to analyze RIFF/WAV/BWF audio files.",
|
||||
"ext-mbstring": "mbstring extension is required to work with different character sets.",
|
||||
"ext-mysql": "MySQL extension is required to use the MySQL database as a cache storage (deprecated in PHP 5.5, removed in PHP >= 7.0, use `ext-mysqli` instead).",
|
||||
"ext-mysqli": "MySQLi extension is required to use the MySQL database as a cache storage.",
|
||||
"ext-rar": "RAR extension is required for RAR archive module.",
|
||||
"ext-sqlite3": "SQLite3 extension is required to use the SQLite3 database as a cache storage.",
|
||||
"ext-xml": "XML extension is required for graphic modules to analyze the XML metadata.",
|
||||
"ext-zlib": "Zlib extension is required for archive modules and compressed metadata."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"getid3/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"GPL-1.0-or-later",
|
||||
"LGPL-3.0-only",
|
||||
"MPL-2.0"
|
||||
],
|
||||
"description": "PHP script that extracts useful information from popular multimedia file formats",
|
||||
"homepage": "https://www.getid3.org/",
|
||||
"keywords": [
|
||||
"codecs",
|
||||
"php",
|
||||
"tags"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/JamesHeinrich/getID3/issues",
|
||||
"source": "https://github.com/JamesHeinrich/getID3/tree/v1.9.23"
|
||||
},
|
||||
"time": "2023-10-19T13:18:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kiwilan/php-audio",
|
||||
"version": "4.0.01",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kiwilan/php-audio.git",
|
||||
"reference": "028842cace360e8ba489df42ef24ebabb43a9c23"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/kiwilan/php-audio/zipball/028842cace360e8ba489df42ef24ebabb43a9c23",
|
||||
"reference": "028842cace360e8ba489df42ef24ebabb43a9c23",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"james-heinrich/getid3": "^v1.9.22",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "^1.2",
|
||||
"pestphp/pest": "^2.0",
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"spatie/ray": "^1.28"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Kiwilan\\Audio\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ewilan Rivière",
|
||||
"email": "ewilan.riviere@gmail.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "PHP package to parse and update audio files metadata, with `JamesHeinrich/getID3`.",
|
||||
"homepage": "https://github.com/kiwilan/php-audio",
|
||||
"keywords": [
|
||||
"aif",
|
||||
"aifc",
|
||||
"aiff",
|
||||
"alac",
|
||||
"audio",
|
||||
"audiobook",
|
||||
"flac",
|
||||
"id3",
|
||||
"id3v1",
|
||||
"id3v2",
|
||||
"m4a",
|
||||
"m4b",
|
||||
"m4v",
|
||||
"mka",
|
||||
"mkv",
|
||||
"mp3",
|
||||
"mp4",
|
||||
"music",
|
||||
"ogg",
|
||||
"opus",
|
||||
"php",
|
||||
"spx",
|
||||
"tta",
|
||||
"wav",
|
||||
"webm",
|
||||
"wma",
|
||||
"wv"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/kiwilan/php-audio/issues",
|
||||
"source": "https://github.com/kiwilan/php-audio/tree/v4.0.01"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/kiwilan",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-03T16:57:29+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
24
index.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
// Load all the classes we need
|
||||
require __DIR__ . "/brain/Loader.php";
|
||||
require __DIR__ . "/vendor/autoload.php";
|
||||
|
||||
use brain\controllers\RouteController;
|
||||
|
||||
// Capture URI
|
||||
$request = parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
|
||||
|
||||
// Strip leading /
|
||||
//$request = ltrim($request, " / ");
|
||||
|
||||
$route = new RouteController();
|
||||
|
||||
// Match route and dispatch
|
||||
try {
|
||||
$route->start($request);
|
||||
} catch (Exception $e) {
|
||||
// No route found
|
||||
http_response_code(404);
|
||||
require __DIR__ . "/src/views/404.php";
|
||||
}
|