MOVED frontend out of Vaadin/Spring
This commit is contained in:
@@ -1,23 +1,31 @@
|
|||||||
|
import { VideoMetadata } from "Frontend/utils/Endpoints";
|
||||||
|
|
||||||
type prop = {
|
type prop = {
|
||||||
setWidth: Function;
|
setMetadata: Function;
|
||||||
setHeight: Function;
|
|
||||||
setFps: Function;
|
|
||||||
setFileSize: Function;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ClipConfig({setWidth, setHeight, setFps, setFileSize}: prop) {
|
export default function ClipConfig({setMetadata}: prop) {
|
||||||
const updateRes = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
const updateRes = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
var vals = e.target.value.split(",");
|
var vals = e.target.value.split(",");
|
||||||
setWidth(parseInt(vals[0]))
|
setMetadata((prevState: VideoMetadata) => ({
|
||||||
setHeight(parseInt(vals[1]))
|
...prevState,
|
||||||
|
width: parseInt(vals[0]),
|
||||||
|
height: parseInt(vals[1])
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateFps = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
const updateFps = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
setFps(parseInt(e.target.value))
|
setMetadata((prevState: VideoMetadata) => ({
|
||||||
|
...prevState,
|
||||||
|
fps: parseInt(e.target.value)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateFileSize = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const updateFileSize = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setFileSize(parseInt(e.target.value))
|
setMetadata((prevState: VideoMetadata) => ({
|
||||||
|
...prevState,
|
||||||
|
fileSize: parseInt(e.target.value) * 1000
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -2,20 +2,20 @@ import RangeSlider from 'react-range-slider-input';
|
|||||||
import 'react-range-slider-input/dist/style.css';
|
import 'react-range-slider-input/dist/style.css';
|
||||||
import {useRef} from "react";
|
import {useRef} from "react";
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import VideoMetadata from "Frontend/generated/com/ddf/vodsystem/entities/VideoMetadata";
|
import { VideoMetadata } from "../utils/Endpoints"
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
videoRef: HTMLVideoElement | null;
|
videoRef: HTMLVideoElement | null;
|
||||||
videoMetadata: VideoMetadata;
|
videoMetadata: VideoMetadata;
|
||||||
setSliderValue: Function;
|
setSliderValue: Function;
|
||||||
setClipRangeValue: Function;
|
setMetadata: Function;
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ClipRangeSlider({videoRef,
|
export default function ClipRangeSlider({videoRef,
|
||||||
videoMetadata,
|
videoMetadata,
|
||||||
setSliderValue,
|
setSliderValue,
|
||||||
setClipRangeValue,
|
setMetadata,
|
||||||
className}: Props) {
|
className}: Props) {
|
||||||
const previousRangeSliderInput = useRef<[number, number]>([0, 0]);
|
const previousRangeSliderInput = useRef<[number, number]>([0, 0]);
|
||||||
|
|
||||||
@@ -30,7 +30,12 @@ export default function ClipRangeSlider({videoRef,
|
|||||||
setSliderValue(val[1]);
|
setSliderValue(val[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setClipRangeValue(val);
|
setMetadata((prevState: VideoMetadata) => ({
|
||||||
|
...prevState,
|
||||||
|
startPoint: val[0],
|
||||||
|
endPoint: val[1]
|
||||||
|
}
|
||||||
|
))
|
||||||
previousRangeSliderInput.current = val;
|
previousRangeSliderInput.current = val;
|
||||||
};
|
};
|
||||||
|
|
||||||
9
frontend/components/Sidebar.tsx
Normal file
9
frontend/components/Sidebar.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export default function Sidebar() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ul>
|
||||||
|
<li>Create Clip</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
14
frontend/layouts/MainLayout.tsx
Normal file
14
frontend/layouts/MainLayout.tsx
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// layout/MainLayout.jsx
|
||||||
|
import Sidebar from 'Frontend/components/Sidebar';
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
|
||||||
|
const MainLayout = () => (
|
||||||
|
<div className="flex">
|
||||||
|
<Sidebar />
|
||||||
|
<div className="flex-1 p-4">
|
||||||
|
<Outlet /> {/* This renders the nested route content */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default MainLayout;
|
||||||
@@ -1,90 +1,42 @@
|
|||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import Playbar from "./../../components/Playbar";
|
import Playbar from "./../components/Playbar";
|
||||||
import PlaybackSlider from "./../../components/PlaybackSlider";
|
import PlaybackSlider from "./../components/PlaybackSlider";
|
||||||
import ClipRangeSlider from "./../../components/ClipRangeSlider";
|
import ClipRangeSlider from "./../components/ClipRangeSlider";
|
||||||
import ClipConfig from "./../../components/ClipConfig";
|
import ClipConfig from "./../components/ClipConfig";
|
||||||
import * as editService from "../../generated/EditService";
|
import { VideoMetadata, editFile, getMetadata } from "../utils/Endpoints"
|
||||||
import * as metadataService from "../../generated/MetadataService"
|
|
||||||
import VideoMetadata from "Frontend/generated/com/ddf/vodsystem/entities/VideoMetadata";
|
|
||||||
|
|
||||||
function exportFile(uuid: string,
|
const ClipEdit = () => {
|
||||||
startPoint: number,
|
|
||||||
endPoint: number,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
fps: number,
|
|
||||||
fileSize: number,
|
|
||||||
setProgress: Function,
|
|
||||||
setDownloadable: Function) {
|
|
||||||
|
|
||||||
setDownloadable(false);
|
|
||||||
const metadata: VideoMetadata = {
|
|
||||||
startPoint: startPoint,
|
|
||||||
endPoint: endPoint,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
fps: fps,
|
|
||||||
fileSize: fileSize*1000
|
|
||||||
}
|
|
||||||
|
|
||||||
editService.edit(uuid, metadata)
|
|
||||||
.then(r => {
|
|
||||||
editService.process(uuid);
|
|
||||||
});
|
|
||||||
|
|
||||||
// get progress updates
|
|
||||||
const interval = setInterval(async () => {
|
|
||||||
try {
|
|
||||||
const result = await editService.getProgress(uuid);
|
|
||||||
setProgress(result);
|
|
||||||
|
|
||||||
if (result >= 1) {
|
|
||||||
clearInterval(interval);
|
|
||||||
setDownloadable(true);
|
|
||||||
console.log('Progress complete');
|
|
||||||
} else {
|
|
||||||
setDownloadable(false);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Failed to fetch progress', err);
|
|
||||||
clearInterval(interval);
|
|
||||||
}
|
|
||||||
}, 200); // 0.5 seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function VideoId() {
|
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const videoRef = useRef<HTMLVideoElement | null>(null);
|
const videoRef = useRef<HTMLVideoElement | null>(null);
|
||||||
const videoUrl = `api/v1/download/input/${id}`
|
const videoUrl = `api/v1/download/input/${id}`
|
||||||
|
|
||||||
const [metadata, setMetadata] = useState<VideoMetadata | null>(null);
|
const [metadata, setMetadata] = useState<VideoMetadata | null>(null);
|
||||||
const [playbackValue, setPlaybackValue] = useState(0);
|
const [playbackValue, setPlaybackValue] = useState(0);
|
||||||
const [clipRangeValue, setClipRangeValue] = useState([0, 1]);
|
|
||||||
const [width, setWidth] = useState(1280);
|
const [outputMetadata, setOutputMetadata] = useState<VideoMetadata>({
|
||||||
const [height, setHeight] = useState(720);
|
// default values
|
||||||
const [fps, setFps] = useState(30);
|
startPoint: 0,
|
||||||
const [fileSize, setFileSize] = useState(10);
|
endPoint: 5,
|
||||||
|
width: 1280,
|
||||||
|
height: 720,
|
||||||
|
fps: 30,
|
||||||
|
fileSize: 10000
|
||||||
|
});
|
||||||
|
|
||||||
const [progress, setProgress] = useState(0);
|
const [progress, setProgress] = useState(0);
|
||||||
const [downloadable, setDownloadable] = useState(false);
|
const [downloadable, setDownloadable] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!id) return;
|
|
||||||
|
|
||||||
metadataService.getInputFileMetadata(id)
|
|
||||||
.then((data) => setMetadata(data ?? null)) // 👈 Normalize undefined to null
|
|
||||||
.catch((err) => console.error("Metadata fetch failed:", err));
|
|
||||||
}, [id]);
|
|
||||||
|
|
||||||
const sendData = () => {
|
const sendData = () => {
|
||||||
if (!id) return
|
if (!id) return;
|
||||||
exportFile(id,clipRangeValue[0], clipRangeValue[1], width, height, fps, fileSize, setProgress, setDownloadable);
|
editFile(id, outputMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDownload = async (filename: string | undefined) => {
|
const handleDownload = async (filename: string | undefined) => {
|
||||||
if (!filename) return;
|
if (!filename) return;
|
||||||
|
|
||||||
const response = await fetch(`/api/v1/download/output/${id}`);
|
const response = await fetch(`/api/v1/download/output/${id}`);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error('Download failed');
|
console.error('Download failed');
|
||||||
return;
|
return;
|
||||||
@@ -93,6 +45,7 @@ export default function VideoId() {
|
|||||||
const blob = await response.blob();
|
const blob = await response.blob();
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
|
||||||
a.href = url;
|
a.href = url;
|
||||||
a.download = filename;
|
a.download = filename;
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a);
|
||||||
@@ -101,6 +54,13 @@ export default function VideoId() {
|
|||||||
window.URL.revokeObjectURL(url);
|
window.URL.revokeObjectURL(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
getMetadata(id)
|
||||||
|
.then((data) => setMetadata(data ?? null))
|
||||||
|
.catch((err) => console.error("Metadata fetch failed:", err));
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"grid grid-cols-[70%_30%]"}>
|
<div className={"grid grid-cols-[70%_30%]"}>
|
||||||
@@ -115,10 +75,7 @@ export default function VideoId() {
|
|||||||
|
|
||||||
|
|
||||||
<ClipConfig
|
<ClipConfig
|
||||||
setWidth={setWidth}
|
setMetadata={setOutputMetadata}
|
||||||
setHeight={setHeight}
|
|
||||||
setFileSize={setFileSize}
|
|
||||||
setFps={setFps}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{metadata &&
|
{metadata &&
|
||||||
@@ -141,7 +98,7 @@ export default function VideoId() {
|
|||||||
videoRef={videoRef.current}
|
videoRef={videoRef.current}
|
||||||
videoMetadata={metadata}
|
videoMetadata={metadata}
|
||||||
setSliderValue={setPlaybackValue}
|
setSliderValue={setPlaybackValue}
|
||||||
setClipRangeValue={setClipRangeValue}
|
setMetadata={setOutputMetadata}
|
||||||
className={"w-full mb-10 bg-primary"}
|
className={"w-full mb-10 bg-primary"}
|
||||||
/>
|
/>
|
||||||
</div>}
|
</div>}
|
||||||
@@ -168,4 +125,6 @@ export default function VideoId() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default ClipEdit;
|
||||||
@@ -1,23 +1,21 @@
|
|||||||
import {useState} from "react";
|
import {useState} from "react";
|
||||||
import {UploadService} from "Frontend/generated/endpoints";
|
import {useNavigate} from "react-router-dom";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { uploadFile } from "../utils/Endpoints"
|
||||||
import "./../index.css";
|
|
||||||
|
|
||||||
export default function main() {
|
const clipUpload = () => {
|
||||||
const [file, setFile] = useState<File | null>(null);
|
const [file, setFile] = useState<File | null>(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const [error, setError] = useState(false);
|
const [noFileError, setNoFileError] = useState(false);
|
||||||
|
const press = (() => {
|
||||||
function press() {
|
|
||||||
if (file) {
|
if (file) {
|
||||||
UploadService.upload(file)
|
uploadFile(file)
|
||||||
.then(uuid => navigate(`video/${uuid}`))
|
.then(uuid => navigate(`video/${uuid}`))
|
||||||
.catch(e => console.error(e));
|
.catch(e => console.error(e));
|
||||||
} else {
|
} else {
|
||||||
setError(true);
|
setNoFileError(true);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={"flex flex-col justify-between"}>
|
<div className={"flex flex-col justify-between"}>
|
||||||
@@ -30,14 +28,16 @@ export default function main() {
|
|||||||
className={"block w-full cursor-pointer rounded-lg border border-dashed border-gray-400 bg-white p-4 text-center hover:bg-gray-50 transition"}
|
className={"block w-full cursor-pointer rounded-lg border border-dashed border-gray-400 bg-white p-4 text-center hover:bg-gray-50 transition"}
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
onClick={() => press()}
|
onClick={press}
|
||||||
className={"text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"}
|
className={"text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800"}
|
||||||
>Upload</button>
|
>Upload</button>
|
||||||
|
|
||||||
{error &&
|
{noFileError &&
|
||||||
<label className={"text-center text-red-500"}>Please choose a file</label>
|
<label className={"text-center text-red-500"}>Please choose a file</label>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
};
|
||||||
|
|
||||||
|
export default clipUpload;
|
||||||
96
frontend/utils/Endpoints.ts
Normal file
96
frontend/utils/Endpoints.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
type VideoMetadata = {
|
||||||
|
startPoint: number,
|
||||||
|
endPoint: number,
|
||||||
|
fps: number,
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
fileSize: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadFile = async (file: File): Promise<string> => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('api/v1/upload', {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
console.log("File uploaded successfully");
|
||||||
|
return await response.text();
|
||||||
|
} else {
|
||||||
|
console.log("File upload failed");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error uploading file:', error);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const editFile = async (uuid: string, videoMetadata: VideoMetadata): Promise<boolean> => {
|
||||||
|
const formData = new URLSearchParams();
|
||||||
|
Object.entries(videoMetadata).forEach(([key, value]) => {
|
||||||
|
if (value !== undefined && value !== null) {
|
||||||
|
formData.append(key, value.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/v1/edit/${uuid}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded"
|
||||||
|
},
|
||||||
|
body: formData.toString()
|
||||||
|
});
|
||||||
|
|
||||||
|
return response.ok;
|
||||||
|
} catch (error){
|
||||||
|
console.error('Error editing file:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const processFile = async (uuid: string): Promise<boolean> => {
|
||||||
|
const response = await fetch(`/api/v1/process/${uuid}`);
|
||||||
|
return response.ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getProgress = async (uuid: string): Promise<number> => {
|
||||||
|
const response = await fetch(`/api/v1/progress/${uuid}`);
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMetadata = async (uuid: string): Promise<VideoMetadata> => {
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/v1/metadata/${uuid}`);
|
||||||
|
return response.json();
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
startPoint: 0,
|
||||||
|
endPoint: 0,
|
||||||
|
fps: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
fileSize: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
VideoMetadata,
|
||||||
|
uploadFile,
|
||||||
|
editFile,
|
||||||
|
processFile,
|
||||||
|
getProgress,
|
||||||
|
getMetadata
|
||||||
|
}
|
||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "vodSystem",
|
"name": "VoD-System",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
|
|||||||
59
pom.xml
59
pom.xml
@@ -27,14 +27,9 @@
|
|||||||
<url/>
|
<url/>
|
||||||
</scm>
|
</scm>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>24</java.version>
|
<java.version>21</java.version>
|
||||||
<vaadin.version>24.7.3</vaadin.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
<artifactId>spring-boot-devtools</artifactId>
|
||||||
@@ -48,8 +43,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.postgresql</groupId>
|
<groupId>org.postgresql</groupId>
|
||||||
@@ -66,17 +60,6 @@
|
|||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<dependencyManagement>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-bom</artifactId>
|
|
||||||
<version>${vaadin.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</dependencyManagement>
|
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
@@ -108,42 +91,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<profiles>
|
|
||||||
<profile>
|
|
||||||
<id>production</id>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-core</artifactId>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-dev</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
<build>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>com.vaadin</groupId>
|
|
||||||
<artifactId>vaadin-maven-plugin</artifactId>
|
|
||||||
<version>${vaadin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>frontend</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>prepare-frontend</goal>
|
|
||||||
<goal>build-frontend</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
</profile>
|
|
||||||
</profiles>
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
@theme {
|
|
||||||
--font-display: "Satoshi", "sans-serif";
|
|
||||||
|
|
||||||
/* Breakpoints */
|
|
||||||
--breakpoint-3xl: 1920px;
|
|
||||||
|
|
||||||
--color-primary: oklch(0.55 0.21 254); /* Modern Blue (#2563EB) */
|
|
||||||
--color-secondary: oklch(0.94 0.01 250); /* Light Gray (#E5E7EB) */
|
|
||||||
--color-accent: oklch(0.68 0.20 288); /* Indigo Accent (#6366F1) */
|
|
||||||
--color-text: oklch(0.17 0.01 270); /* Dark Slate (#111827) */
|
|
||||||
--color-background: oklch(0.98 0.005 250);/* Soft off-white (#F9FAFB) */
|
|
||||||
|
|
||||||
--color-primary-pressed: oklch(0.55 0.21 254 / 0.5);
|
|
||||||
|
|
||||||
/* Easing */
|
|
||||||
--ease-fluid: cubic-bezier(0.3, 0, 0, 1);
|
|
||||||
--ease-snappy: cubic-bezier(0.2, 0, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#range-slider .range-slider__range{
|
|
||||||
background: var(--color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
#range-slider .range-slider__thumb{
|
|
||||||
background: var(--color-primary);
|
|
||||||
}
|
|
||||||
@@ -4,8 +4,6 @@ import com.ddf.vodsystem.entities.JobStatus;
|
|||||||
import com.ddf.vodsystem.exceptions.JobNotFinished;
|
import com.ddf.vodsystem.exceptions.JobNotFinished;
|
||||||
import com.ddf.vodsystem.exceptions.JobNotFound;
|
import com.ddf.vodsystem.exceptions.JobNotFound;
|
||||||
import com.ddf.vodsystem.entities.Job;
|
import com.ddf.vodsystem.entities.Job;
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
|
||||||
import com.vaadin.hilla.Endpoint;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
@@ -14,8 +12,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Endpoint
|
|
||||||
@AnonymousAllowed
|
|
||||||
public class DownloadService {
|
public class DownloadService {
|
||||||
|
|
||||||
private final JobService jobService;
|
private final JobService jobService;
|
||||||
|
|||||||
@@ -3,13 +3,9 @@ package com.ddf.vodsystem.services;
|
|||||||
import com.ddf.vodsystem.entities.VideoMetadata;
|
import com.ddf.vodsystem.entities.VideoMetadata;
|
||||||
import com.ddf.vodsystem.entities.Job;
|
import com.ddf.vodsystem.entities.Job;
|
||||||
import com.ddf.vodsystem.entities.JobStatus;
|
import com.ddf.vodsystem.entities.JobStatus;
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
|
||||||
import com.vaadin.hilla.Endpoint;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Endpoint
|
|
||||||
@AnonymousAllowed
|
|
||||||
public class EditService {
|
public class EditService {
|
||||||
private final JobService jobService;
|
private final JobService jobService;
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import com.ddf.vodsystem.entities.VideoMetadata;
|
|||||||
import com.ddf.vodsystem.exceptions.FFMPEGException;
|
import com.ddf.vodsystem.exceptions.FFMPEGException;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
|
||||||
import com.vaadin.hilla.Endpoint;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -17,8 +15,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Endpoint
|
|
||||||
@AnonymousAllowed
|
|
||||||
public class MetadataService {
|
public class MetadataService {
|
||||||
private static Logger logger = LoggerFactory.getLogger(MetadataService.class);
|
private static Logger logger = LoggerFactory.getLogger(MetadataService.class);
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package com.ddf.vodsystem.services;
|
|||||||
|
|
||||||
import com.ddf.vodsystem.entities.Job;
|
import com.ddf.vodsystem.entities.Job;
|
||||||
import com.ddf.vodsystem.entities.VideoMetadata;
|
import com.ddf.vodsystem.entities.VideoMetadata;
|
||||||
import com.vaadin.flow.server.auth.AnonymousAllowed;
|
|
||||||
import com.vaadin.hilla.Endpoint;
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -24,8 +22,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Endpoint
|
|
||||||
@AnonymousAllowed
|
|
||||||
public class UploadService {
|
public class UploadService {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(UploadService.class);
|
private static final Logger logger = LoggerFactory.getLogger(UploadService.class);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
vaadin.launch-browser=true
|
|
||||||
spring.application.name=vodSystem
|
spring.application.name=vodSystem
|
||||||
|
|
||||||
# VODs
|
# VODs
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.ddf.vodsystem;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class VodSystemApplicationTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void contextLoads() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user