diff --git a/docker/nginx/conf.dev b/docker/nginx/conf.dev
index 7be13a7b8..ea1011924 100644
--- a/docker/nginx/conf.dev
+++ b/docker/nginx/conf.dev
@@ -83,7 +83,7 @@ http {
proxy_pass http://funkwhale-front/front/;
}
location /front/embed.html {
- add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
+ add_header Content-Security-Policy "default-src 'self'; script-src 'self' unpkg.com 'unsafe-inline' 'unsafe-eval'; style-src https: http: 'self' 'unsafe-inline'; img-src https: http: 'self' data:; font-src https: http: 'self' data:; object-src 'none'; media-src https: http: 'self' data:";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header X-Frame-Options "" always;
proxy_pass http://funkwhale-front/front/embed.html;
diff --git a/front/embed.html b/front/embed.html
deleted file mode 100644
index 18026f60c..000000000
--- a/front/embed.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
- Funkwhale Widget
-
-
-
-
-
-
-
-
-
-
diff --git a/front/public/embed.css b/front/public/embed.css
new file mode 100644
index 000000000..29af233b3
--- /dev/null
+++ b/front/public/embed.css
@@ -0,0 +1,207 @@
+:root {
+ --fw-darker: #1b1c1d;
+ --fw-dark: #2f3030;
+ --fw-light: #666666;
+ --fw-primary: #f2711c;
+ --fw-text: #fff;
+}
+
+[v-cloak] {
+ display: none;
+}
+
+body {
+ margin: 0;
+
+ font-family: sans-serif;
+
+ background-color: var(--fw-darker);
+ color: var(--fw-text);
+}
+
+main {
+ display: grid;
+ grid-template-rows: 166px 1fr;
+ height: 100vh;
+}
+
+/*
+ Player
+*/
+
+.player {
+ display: grid;
+ grid-template-areas: 'cover content content' 'cover controls logo';
+ grid-template-columns: 166px 1fr 50px;
+ align-items: flex-end;
+ padding: 8px;
+}
+
+img {
+ display: block;
+ object-fit: contain;
+ object-position: center;
+ aspect-ratio: 1;
+}
+
+h1, h2 {
+ margin: 0;
+}
+
+.cover-image {
+ grid-area: cover;
+ background-color: var(--fw-dark);
+ width: 150px;
+}
+
+.player-content {
+ grid-area: content;
+}
+
+.player-controls {
+ grid-area: controls;
+ height: 36px;
+
+ display: grid;
+ grid-template-columns: auto auto auto 1fr auto 100px;
+ gap: 8px;
+}
+
+button {
+ color: inherit;
+ background-color: transparent;
+ border: none;
+ font-size: 2em;
+ padding: 0;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+}
+
+button:hover {
+ color: var(--fw-primary);
+}
+
+button.play {
+ font-size: 2.5em;
+}
+
+button > svg {
+ height: 1em;
+ width: 1em;
+}
+
+.logo-link {
+ display: block;
+ aspect-ratio: 1;
+ background-color: var(--fw-primary);
+ padding: 4px;
+ margin: 8px -8px -8px 8px;
+}
+
+/*
+ Track list
+*/
+
+.track-list {
+ background-color: var(--fw-dark);
+ overflow-y: scroll;
+ padding: 16px 8px;
+}
+
+table {
+ border-collapse: collapse;
+ width: 100%;
+}
+
+tr {
+ font-weight: bold;
+ cursor: pointer;
+ background: var(--entry-bg, transparent);
+}
+
+tr.current {
+ --entry-bg: var(--fw-darker);
+}
+
+tr:hover {
+ --entry-bg: var(--fw-light);
+}
+
+td {
+ padding: 8px;
+ min-width: 40px;
+}
+
+td:first-child {
+ padding-left: 16px;
+ width: 0;
+}
+
+td:last-child {
+ text-align: right;
+ width: 0;
+}
+
+/*
+ Sliders
+*/
+
+input[type=range] {
+ background: transparent;
+ appearance: none;
+ height: 100%;
+ margin: 0;
+
+ --range-color: var(--fw-light);
+ --range-size: 0.6em;
+
+ --min: 0;
+ --max: 100;
+ --value: 50;
+ --range: calc(var(--max) - var(--min));
+ --ratio: calc((var(--value) - var(--min)) / var(--range));
+ --sx: calc(0.5 * var(--range-size) + var(--ratio) * (100% - var(--range-size)));
+}
+
+input[type=range]:focus {
+ outline: none;
+}
+
+input[type=range]::-webkit-slider-thumb {
+ appearance: none;
+ width: var(--range-size);
+ height: var(--range-size);
+ border-radius: calc(var(--range-size) / 2);
+ background: var(--range-color);
+ border: none;
+ box-shadow: none;
+}
+
+input[type=range]::-moz-range-thumb {
+ appearance: none;
+ width: var(--range-size);
+ height: var(--range-size);
+ border-radius: calc(var(--range-size) / 2);
+ background: var(--range-color);
+ border: none;
+ box-shadow: none;
+}
+
+input[type=range]::-moz-range-track {
+ appearance: none;
+ height: var(--range-size);
+ border: none;
+ border-radius: calc(var(--range-size) / 2);
+ box-shadow: none;
+ background: linear-gradient(var(--range-color),var(--range-color)) 0/var(--sx) 100% no-repeat, var(--fw-dark);
+}
+
+input[type=range]::-webkit-slider-runnable-track {
+ appearance: none;
+ height: var(--range-size);
+ border: none;
+ border-radius: calc(var(--range-size) / 2);
+ box-shadow: none;
+ background: linear-gradient(var(--range-color),var(--range-color)) 0/var(--sx) 100% no-repeat, var(--fw-dark);
+}
diff --git a/front/public/embed.html b/front/public/embed.html
new file mode 100644
index 000000000..c66db340a
--- /dev/null
+++ b/front/public/embed.html
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+ Funkwhale Widget
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
{{ tracks[player.current].title }}
+ {{ tracks[player.current].artist.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ index + 1 }}
+ |
+
+ {{ track.title }}
+ |
+
+ {{ track.artist.name }}
+ |
+
+ {{ track.album?.title }}
+ |
+
+ {{ formatDuration(track.sources[0].duration) }}
+ |
+
+
+
+
+
+
+
diff --git a/front/public/logo-white.svg b/front/public/logo-white.svg
new file mode 100644
index 000000000..e00515822
--- /dev/null
+++ b/front/public/logo-white.svg
@@ -0,0 +1,39 @@
+
diff --git a/front/vite.config.ts b/front/vite.config.ts
index 7cef5dfb4..fc749e042 100644
--- a/front/vite.config.ts
+++ b/front/vite.config.ts
@@ -40,14 +40,6 @@ export default defineConfig(({ mode }) => ({
'~': resolve(__dirname, './src')
}
},
- build: {
- rollupOptions: {
- input: {
- main: resolve(__dirname, './index.html'),
- embed: resolve(__dirname, './embed.html')
- }
- }
- },
test: {
environment: 'jsdom',
globals: true