first commit

This commit is contained in:
raiper34
2024-06-22 17:06:41 +02:00
commit da9cf53c69
53 changed files with 20449 additions and 0 deletions
+59
View File
@@ -0,0 +1,59 @@
<section class="hero is-primary">
<div class="hero-body">
<p class="title">
<span><i class="fa-solid fa-music"></i> Spooty</span>
</p>
<p class="subtitle"><i class="fa-solid fa-house"></i> Self-hosted <i class="fa-brands fa-spotify"></i> spotify <i class="fa-solid fa-download"></i>downloader</p>
</div>
</section>
<section class="hero">
<div class="hero-body">
<div class="box">
<p class="subtitle">Download</p>
<div class="is-flex">
<input class="input" type="text" [(ngModel)]="url" placeholder="Paste playlist/song/artist url"/>
<button class="button is-primary" (click)="download()">
<i class="fa-solid fa-download"></i> Download
</button>
</div>
</div>
<hr>
<div class="box">
<div class="is-flex is-align-items-center">
<p class="subtitle">List</p>
<button class="button" (click)="get()"><i class="fa-solid fa-arrows-rotate"></i> Refresh</button>
</div>
<article class="panel is-primary" *ngFor="let playlist of playlists">
<p class="panel-heading is-flex is-justify-content-space-between">
<span><i class="fa-solid fa-caret-down"></i> {{playlist.name}}</span>
<a [href]="playlist.spotifyUrl" target="_blank" class="is-color-black"><i class="fa-brands fa-spotify"></i></a>
</p>
<a class="panel-block is-flex is-justify-content-space-between" *ngFor="let track of playlist.tracks">
<div>
<a href="http://localhost:3000/track/download/{{track.id}}" class="panel-icon is-color-info" download>
<i class="fa-solid fa-download"></i>
</a>
<span>{{track.artist}} - {{track.song}}</span>&nbsp;
<a [href]="track.spotifyUrl" target="_blank" class="is-color-primary margin-left">
<i class="fa-brands fa-spotify"></i>
</a>&nbsp;
<a [href]="track.youtubeUrl" target="_blank" class="is-color-danger is-color-black">
<i class="fa-brands fa-youtube"></i>
</a>
</div>
<div>
<ng-container [ngSwitch]="track.status">
<span *ngSwitchCase="0" class="tag is-info">New</span>
<span *ngSwitchCase="1" class="tag is-warning">Queued</span>
<span *ngSwitchCase="2" class="tag is-success">Completed</span>
</ng-container>
</div>
</a>
</article>
</div>
</div>
</section>
+7
View File
@@ -0,0 +1,7 @@
.panel-heading {
padding: 5px 10px;
}
.panel-block {
padding: 5px 10px;
}
+29
View File
@@ -0,0 +1,29 @@
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [AppComponent],
}).compileComponents();
});
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have the 'spooty-fe' title`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('spooty-fe');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('h1')?.textContent).toContain('Hello, spooty-fe');
});
});
+34
View File
@@ -0,0 +1,34 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {HttpClient} from "@angular/common/http";
import {FormsModule} from "@angular/forms";
import {NgFor, NgSwitch, NgSwitchCase} from "@angular/common";
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, FormsModule, NgFor, NgSwitch, NgSwitchCase],
templateUrl: './app.component.html',
styleUrl: './app.component.scss'
})
export class AppComponent {
url = ''
playlists: any[] = [];
tracks = [
{code: 'CC', name: 'Aaaa'},
{code: 'CrC', name: 'Aaaadfdfd'},
]
constructor(private readonly http: HttpClient) {
this.get();
}
download(): void {
this.http.post('/api/playlist', {spotifyUrl: this.url}).subscribe(() => this.get());
}
get(): void {
this.http.get('/api/playlist').subscribe(data => this.playlists = data as any);
}
}
+13
View File
@@ -0,0 +1,13 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import {provideHttpClient} from "@angular/common/http";
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideHttpClient(),
]
};
+3
View File
@@ -0,0 +1,3 @@
import { Routes } from '@angular/router';
export const routes: Routes = [];
+13
View File
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SpootyFe</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
+6
View File
@@ -0,0 +1,6 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent, appConfig)
.catch((err) => console.error(err));
+8
View File
@@ -0,0 +1,8 @@
/* You can add global styles to this file, and also import other style files */
@import "bulma/bulma.scss";
@import "@fortawesome/fontawesome-free/css/all.css";
body {
padding: 0;
margin: 0;
}