Compare commits

..

23 Commits

Author SHA1 Message Date
Hughes, Mike 9d5b71e2c7 Merge branch 'feature/ui-test' into 'feature/customdocument26'
# Conflicts:
#   electron/main/custom_document.html
2026-01-15 14:34:52 +01:00
santa fdfbdec75a Merge branch 'feature/customdocument26' of https://gitlab.rlp.net/proj-wise2526-video2document/video2document into feature/customdocument26 2026-01-15 14:19:32 +01:00
santa 977f2f8244 help page 2026-01-15 14:14:14 +01:00
MikeHughes-BIN ecece5009e minor changes to Text 2026-01-15 13:52:51 +01:00
Verena Schulz 66762b8251 Implemented hover effect 2026-01-14 19:04:27 +01:00
eric.minning bef9c44a2f Fixed a smal error in the document generation button of the costum document creation section 2026-01-12 18:37:39 +01:00
Verena Schulz 60b9f8a3b9 Small style changes 2026-01-12 17:15:38 +01:00
eric.minning 4dd7b512a1 Expanded the function to change the language of the program. Added the dedicated language dropdown list 2026-01-11 15:56:21 +01:00
Verena Schulz d21bbbce12 Implemented the visibility regulation of the custom document section 2026-01-10 19:51:29 +01:00
santa 6f722b68e1 help page step1-3 description and documenttypes edit, delete, safe 2026-01-10 19:34:06 +01:00
eric.minning 7bce7c8d36 Implemented the script part from the custom_document.html file into the base script.js and renderer.js 2026-01-10 19:04:37 +01:00
Verena Schulz 3c3d7a1d3e Joined custom_document html and css elements with index and style 2026-01-10 18:08:21 +01:00
Heyne, Stefan Norbert Robert 1c85272abc Merge branch 'feature/customdocument26' into 'feature/ui-test'
delete button and function implemented

See merge request proj-wise2526-video2document/video2document!84
2026-01-10 14:41:13 +01:00
Heyne, Stefan Norbert Robert 18b624736d Merge branch 'feature/ui-test' into 'feature/customdocument26'
# Conflicts:
#   electron/main/custom_document.html
#   electron/main/index.html
2026-01-10 14:38:40 +01:00
eric.minning c833d5bb74 Fixed errors and added the loading of step 3 document types 2026-01-08 17:18:43 +01:00
Heyne, Stefan Norbert Robert 43e21cfd8d Merge branch 'feature/customdocument26' into 'feature/ui-test'
Add start scripts for Windows and Unix environments that checks if node is...

See merge request proj-wise2526-video2document/video2document!82
2026-01-08 15:41:36 +01:00
eric.minning f3cc6b5798 Changed the language selection so it also shows the flags 2026-01-08 15:32:30 +01:00
Verena Schulz 0a5fa79668 Added comments and to do 2026-01-07 17:34:14 +01:00
eric.minning 30b94c4e62 Polished the code in the script.js and renderer.js 2026-01-07 16:14:22 +01:00
eric.minning cc883905bc Expanded the change languages file and function 2026-01-06 14:03:28 +01:00
Verena Schulz 40edcaa69d Some changes for step 5 2026-01-04 21:33:57 +01:00
Verena Schulz c7625e5713 Fixed download button positioning 2026-01-04 21:20:44 +01:00
Verena Schulz f5c2e2700b Added headings, some finetuning 2025-12-30 16:53:25 +01:00
9 changed files with 1303 additions and 842 deletions
-322
View File
@@ -54,325 +54,3 @@ Make sure that **ffmpeg** is installed on your system, as it may be required for
---
**Installation complete!** You're now ready to use Video2Document.
###General Despription
## Project Overview
V2D (Video to Document Framework) is a student project developed to convert video and audio content into structured, readable documents using AI-based text processing. The tool is designed to help users automatically generate documents such as meeting reports, summaries or structured texts from recorded videos or audio files.
The main problem V2D addresses is the time-consuming manual effort required to listen to recordings and write documents afterwards. By automating transcription, structuring and document generation, the tool improves efficiency and usability for students, teams and small organizations.
The project was created as part of a university software engineering course and is developed using agile methods (Scrum). It focuses on modular design, usability and extensibility, allowing new document types and features to be added easily.
### Used Packages and Dependencies
This project uses several Node.js packages to handle video processing, AI-based document generation, backend communication, and the desktop user interface. Below is an overview of the most important dependencies and their purpose.
##Core Dependencies:
Electron:
Used to build the desktop application. It allows the project to run as a cross-platform GUI application using web technologies.
Express:
Acts as a lightweight backend server that handles internal API requests and communication between different parts of the application.
Axios:
Used for making HTTP requests, for example when communicating with external APIs such as AI services.
dotenv:
Used to securely load API keys and other sensitive configuration values from environment variables instead of hardcoding them in the source code.
@google/genai:
Provides access to Googles Generative AI models. This package is used to generate structured documents from transcribed text based on configurable prompts.
ffmpeg-static:
Provides a static FFmpeg binary so that video and audio processing works without requiring FFmpeg to be installed separately on the system.
fluent-ffmpeg:
Used together with FFmpeg to process video and audio files, for example extracting audio tracks from uploaded videos.
puppeteer:
Used to render and process HTML content programmatically. This is helpful for document previews and automated content generation.
html-to-docx:
Converts generated HTML documents into downloadable DOCX files, which are provided to the user as the final output.
mocha:
A testing framework used to run unit tests and ensure that core functionalities work as expected.
##Development Dependencies:
TypeScript:
Used to add static typing to the project, improving code quality, readability, and maintainability.
ts-node:
Allows running TypeScript files directly without manually compiling them first.
@types/node:
Provides TypeScript type definitions for Node.js APIs.
@types/fluent-ffmpeg:
Type definitions for fluent-ffmpeg to improve development experience and error checking.
@types/cli-progress:
Provides type support for progress bar functionality used during processing tasks.
###Why These Packages Are Needed
Together, these packages enable:
*Processing video and audio files
*Communicating with AI models for document generation
*Secure handling of API keys
*Generating structured documents (DOCX)
*Providing a user-friendly desktop interface
*Ensuring code quality through testing
###API Keys and Configuration
The V2D Video to Document tool uses external AI and media processing services to convert video and audio content into structured documents.
To access these services, several API keys are required. For security reasons, API keys are not stored in the repository and must be provided via environment variables.
##Supported API Keys
The project currently supports the following API keys. Depending on the configuration and selected provider, one or more of these keys may be used.
Google Gemini API
Environment variable: GOOGLE_API_KEY
Usage:
Used for AI-based document generation. The Large Language Model processes transcripts and creates structured documents such as meeting reports.
OpenAI (ChatGPT)
Environment variable: OPENAI_API_KEY
Usage:
Alternative AI provider for text processing and document generation.
AssemblyAI
Environment variable: ASSEMBLYAI_API_KEY
Usage:
Speech-to-text processing for audio and video files.
Saya
Environment variable: SAYA_API_KEY
Usage:
Additional or experimental AI provider that can be integrated into the document generation pipeline.
##How to Set API Keys
API keys must be configured as environment variables before starting the application.
Linux / macOS
export GOOGLE_API_KEY="your_api_key_here"
export OPENAI_API_KEY="your_api_key_here"
export ASSEMBLYAI_API_KEY="your_api_key_here"
export SAYA_API_KEY="your_api_key_here"
Windows (PowerShell)
setx GOOGLE_API_KEY "your_api_key_here"
setx OPENAI_API_KEY "your_api_key_here"
setx ASSEMBLYAI_API_KEY "your_api_key_here"
setx SAYA_API_KEY "your_api_key_here"
Alternatively, for local development, a .env file can be used:
GOOGLE_API_KEY=your_api_key_here
OPENAI_API_KEY=your_api_key_here
ASSEMBLYAI_API_KEY=your_api_key_here
SAYA_API_KEY=your_api_key_here
⚠️ Important:
The .env file must not be committed to the repository and should be listed in .gitignore.
Security Notes:
*API keys are injected at runtime
*No secrets are stored in the source code
*Prevents accidental exposure of sensitive data
*Supports secure collaboration in GitLab and CI/CD environments
*Follows best practices for secret management
###End-to-End User Guide (Video → Final Document)
This section describes how a user can create a structured document from a video using the V2D Video to Document tool.
Start the Application:
Ensure all required API keys are configured as environment variables.
Install dependencies:
npm install
Start the application:
npm start
The Electron-based GUI will open.
#Upload a Video File:
In the application interface, select Upload Video.
Choose a supported video file (e.g. .mp4, .mov).
The video is loaded into the system for processing.
#Audio Extraction:
The application automatically extracts audio from the uploaded video.
This is handled internally using FFmpeg.
No user interaction is required for this step.
#Speech-to-Text Transcription:
The extracted audio is sent to the speech-to-text service.
The transcription process converts spoken content into text.
The generated transcript is stored internally and used for further processing.
#Select Document Type:
The user selects a document type (e.g. Meeting Report).
Each document type is based on a predefined prompt template.
The selected template defines the structure and style of the final document.
#Document Generation:
The transcript and selected prompt are sent to the AI service.
The AI model processes the input and generates a structured document.
The output is formatted in Markdown.
#Document Preview:
The generated document is displayed in the application preview.
Users can review the content before exporting.
No manual editing is required, but validation is possible.
#Export the Final Document:
The user exports the document in the desired format.
#Supported formats include:
Markdown (.md)
Word (.docx)
The document is saved locally.
#Completion:
The final document is now ready for use.
The user can repeat the process with another video if needed.
###Resources
This section lists the main technologies, libraries, and external resources used in the V2D (Video to Document) project. These resources are required to understand, run, and further develop the application.
##Project Dependencies
The following packages and tools are used in this project (as defined in package.json):
Application & Backend
Node.js JavaScript runtime environment used for backend processing
Electron Framework for building the desktop application
Express Backend web framework for handling requests and internal APIs
AI & API Communication
@google/genai Used for AI-based document generation
Axios HTTP client for communicating with external APIs (LLMs)
Video & Audio Processing
ffmpeg-static Extracts audio from uploaded video files
fluent-ffmpeg Controls FFmpeg operations programmatically
Document Generation & Preview
html-to-docx Converts structured content into Word documents
Puppeteer Renders HTML content for document preview and processing
Configuration & Security
dotenv Loads API keys securely from environment variables
Testing & Development
Mocha Unit testing framework
TypeScript Improves code quality and type safety
These dependencies enable the complete end-to-end workflow from video input to structured document output.
##Relevant Repositories
V2D Main Repository:
https://gitlab.rlp.net/proj-wise2526-video2document/video2document
This repository contains the full source code, configuration files, and documentation for the V2D project.
Downloads & External Resources
The following tools and documentation may be required to run or understand the project:
Node.js: https://nodejs.org
Electron Documentation: https://www.electronjs.org/docs
FFmpeg: https://ffmpeg.org
Google Generative AI: https://ai.google.dev
Puppeteer: https://pptr.dev
+13 -107
View File
@@ -6,96 +6,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Document</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f0f2f5;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.container {
background: white;
padding: 30px;
margin-top: 50px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 600px;
}
h1 {
text-align: center;
color: #333;
}
label {
font-weight: bold;
margin-top: 15px;
display: block;
color: #555;
}
input[type="text"],
textarea,
select {
width: 100%;
padding: 10px;
margin-top: 5px;
border-radius: 6px;
border: 1px solid #ccc;
font-size: 14px;
}
textarea {
height: 120px;
resize: vertical;
}
.buttons {
display: flex;
justify-content: space-between;
margin-top: 25px;
}
.hidden {
visibility: hidden;
}
button {
padding: 10px 20px;
font-size: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
transition: 0.2s;
background-color: #007BFF;
color: white;
}
button:hover {
background-color: #0056b3;
}
@media (max-width: 500px) {
.buttons {
flex-direction: column;
}
.buttons button {
width: 100%;
margin-top: 10px;
}
}
#result {
margin-top: 20px;
color: #333;
word-break: break-word;
}
</style>
</head>
@@ -103,26 +13,26 @@
<div class="container">
<h1>Manage document types</h1>
<label for="existingDocs">Vorhandene Dokumente auswählen (optional):</label>
<label for="existingDocs">Vorhandene Dokumententypen auswählen (optional):</label>
<!--Drop Down-->
<select name="existingDocs" id="existingDocs">
<option value="newDoc">-- Neues Dokument erstellen --</option>
<option value="newDoc">-- Neuen Dokumententyp erstellen --</option>
</select>
<div id="docNameWrapper">
<label for="docName">Dokumentname:</label>
<input type="text" id="docName" placeholder="Gib hier den Dokumentnamen ein">
<label for="docName">Name des Dokumententyps:</label>
<input type="text" id="docName" placeholder="Gib hier den Namen für den Dokumententyp ein">
</div>
<label for="prompt">Dein Prompt:</label>
<textarea id="prompt" placeholder="Schreibe hier den Prompt für dein Dokument..."></textarea>
<textarea id="prompt" placeholder="Schreibe hier den Prompt für dein Dokumententyp..."></textarea>
<div class="buttons">
<a href="index.html">
<button id="goBackBtn">Abbrechen</button>
</a>
<button id="deleteBtn">Dokument löschen</button>
<button id="generateBtn">Dokument speichern</button>
<button id="deleteBtn">Dokumententyp löschen</button>
<button id="generateBtn">Dokumententyp speichern</button>
</div>
<div id="result"></div>
@@ -144,14 +54,14 @@
const name = docNameInput.value.trim();
const content = promptInput.value.trim();
if (!name || !content) {
resultDiv.textContent = "Bitte Dokumentname und Prompt ausfüllen.";
resultDiv.textContent = "Bitte Name des Dokumententyps und Prompt ausfüllen.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
return;
}
window.api.saveTxtFile(name, content).then();
resultDiv.textContent = "Dokument erfolgreich gespeichert!";
resultDiv.textContent = "Dokumententyp erfolgreich gespeichert!";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
@@ -164,7 +74,7 @@
const name = docNameInput.value.trim();
if (!name) {
resultDiv.textContent = "Bitte Dokumentname angeben.";
resultDiv.textContent = "Bitte Name des Dokumententyps angeben.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
@@ -172,19 +82,19 @@
}
const confirmDelete = confirm(
`Möchtest du das Dokument "${name}" wirklich löschen?`
`Möchtest du den Dokumententyp "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => {
if (success) {
resultDiv.textContent = "Dokument erfolgreich gelöscht!";
resultDiv.textContent = "Dokumententyp erfolgreich gelöscht!";
reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change"));
} else {
resultDiv.textContent = "Dokument konnte nicht gelöscht werden.";
resultDiv.textContent = "Dokumententyp konnte nicht gelöscht werden.";
}
setTimeout(() => {
@@ -234,14 +144,10 @@
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
existingDocs.appendChild(option);
//customDocumentTypes.appendChild(option);
});
});
}
</script>
<script src="./renderer.js"></script>
</body>
+320
View File
@@ -0,0 +1,320 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Anleitung</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f0f2f5;
margin: 0;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* ===== CONTAINER ===== */
.container {
background: white;
width: 90%;
max-width: 800px;
height: 85vh;
/* feste Höhe */
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
}
/* ===== FIXER TOP-BEREICH ===== */
.top-bar {
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
flex-shrink: 0;
}
/* Buttons */
.back-btn,
.toc-toggle {
background: #007BFF;
color: white;
border: none;
padding: 8px 14px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.back-btn:hover,
.toc-toggle:hover {
background: #0056b3;
}
/* ===== TOC ===== */
.toc-wrapper {
position: relative;
}
.toc {
position: absolute;
right: 0;
top: 45px;
background: white;
border-radius: 8px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
padding: 10px;
min-width: 220px;
display: none;
z-index: 5;
}
.toc a {
display: block;
padding: 8px 10px;
color: #007BFF;
text-decoration: none;
border-radius: 6px;
}
.toc a:hover {
background: #f0f2f5;
}
.toc.show {
display: block;
}
/* ===== SCROLLBEREICH ===== */
.content {
padding: 30px;
overflow-y: auto;
flex: 1;
}
/* Inhalt */
h1 {
text-align: center;
color: #333;
}
.step {
margin-bottom: 20px;
margin-top: 20px;
}
.step h2 {
color: #0056b3;
}
.step h3 {
color: #555;
margin-bottom: 5px;
}
.step p {
color: #555;
line-height: 1.6;
}
.step img {
width: 100%;
max-height: 350px;
object-fit: contain;
border-radius: 8px;
margin-top: 15px;
border: 1px solid #ddd;
}
</style>
</head>
<body>
<div class="container">
<!-- FIXER OBERER TEIL -->
<div class="top-bar">
<a href="index.html">
<button class="back-btn">Zurück</button>
</a>
<h1>Programm Anleitung</h1>
<div class="toc-wrapper">
<button class="toc-toggle" onclick="toggleTOC()">Inhaltsverzeichnis</button>
<div class="toc" id="toc">
<a href="#convertVid" onclick="closeTOC()">Video zu Dokument umwandeln</a>
<a href="#firstStep" onclick="closeTOC()">Schritt 1 - Video auswählen</a>
<a href="#secondStep" onclick="closeTOC()">Schritt 2 - Konfiguration</a>
<a href="#thirdStep" onclick="closeTOC()">Schritt 3 - Dokumententyp auswählen</a>
<a href="#fourthStep" onclick="closeTOC()">Schritt 4 - Bestätigen</a>
<a href="#fifthStep" onclick="closeTOC()">Schritt 5 - Sprecher identifizieren</a>
<a href="#sixthStep" onclick="closeTOC()">Schritt 6 - Dokument speichern</a>
<a href="#createDoc" onclick="closeTOC()">Dokumententyp erstellen</a>
<a href="#editDoc" onclick="closeTOC()">Dokumententyp bearbeiten</a>
<a href="#deleteDoc" onclick="closeTOC()">Dokumententyp löschen</a>
</div>
</div>
</div>
<!-- NUR DIESER TEIL SCROLLT -->
<div class="content">
<div class="step" id="convertVid">
<h2>Video in ein Dokument umwandeln.</h2>
<div class="step" id="firstStep">
<h3>Schritt 1 - Video auswählen</h3>
<p id="firstStep">
- Ziehe eine Videodatei in das Drag-and-Drop-Feld oder klicke auf <strong>„Video
suchen“</strong>,<br>
um eine Datei über deinen Dateibrowser auszuwählen.<br>
- Klicke anschließend auf <strong>Schritt 2</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="secondStep">
<h3>Schritt 2 - Konfiguration</h3>
<p>
- Wähle im ersten Auswahlmenü die zu verwendende <strong>KI</strong>.<br>
- Wähle im zweiten Auswahlmenü das zu verwendende <strong>Transkriptions-Tool</strong>.<br>
- Wähle im dritten Auswahlmenü das <strong>Dateiformat</strong> des zu erstellenden
Dokuments.<br>
- Wähle im vierten Auswahlmenü die <strong>Sprache</strong> des zu erstellenden Dokuments.<br>
- Klicke anschließend auf <strong>Schritt 3</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="thirdStep">
<h3>Schritt 3 - Dokumententyp auswählen</h3>
<p>
- Wähle einen Dokumententyp über die Checkbox oder einen zuvor erstellten Dokumententyp aus dem
Dropdown-Menü aus.<br>
- Klicke anschließend auf <strong>Schritt 4</strong> oder auf den blauen Pfeil rechts, um
fortzufahren.
</p>
</div>
<div class="step" id="fourthStep">
<h3>Schritt 4 - Bestätigen</h3>
<p>
Klicke auf <strong>„Submit“</strong>, um die Dokumentengenerierung zu starten.<br>
Während der Verarbeitung werden vier Statuspunkte angezeigt, die sich schrittweise von rot zu
grün färben und den aktuellen Fortschritt darstellen:
<br><br>
Punkt 1: Upload und Vorbereitung der Videodatei.<br>
Punkt 2: Transkription des Videoinhalts.<br>
Punkt 3: KI-gestützte Verarbeitung und Dokumentenerstellung.<br>
Punkt 4: Abschluss der Generierung und Bereitstellung des Dokuments.
<br><br>
Nach erfolgreichem Abschluss klicke auf <strong>Schritt 5</strong> oder auf den blauen Pfeil
rechts, um fortzufahren.
</p>
</div>
<div class="step" id="fifthStep">
<h3>Schritt 5 - Sprecher identifizieren</h3>
<p>
Im Auswahlmenü kannst du einen erkannten Sprecher auswählen.<br>
Über den Play-Button lässt sich ein gesprochener Satz anhören, um den Sprecher eindeutig zu
identifizieren.<br>
Mit dem Lautsprecher-Symbol kannst du die Lautstärke anpassen.<br>
Über das Drei-Punkte-Menü lässt sich die Wiedergabegeschwindigkeit einstellen.<br><br>
Im Textfeld <strong>„Write name“</strong> gibst du den tatsächlichen Namen des Sprechers ein,
damit dieser im Dokument
anstelle von Platzhaltern wie z. B. „Sprecher A“ angezeigt wird.<br>
Bestätige die Eingabe mit <strong>„Rename Speaker“</strong>.<br><br>
Mit dem Button <strong>„Rewrite Document“</strong> werden anschließend alle
Sprecherbezeichnungen im Dokument ersetzt.<br><br>
Klicke danach auf <strong>Schritt 6</strong> oder auf den blauen Pfeil rechts, um fortzufahren.
</p>
</div>
<div class="step" id="sixthStep">
<h3>Schritt 6 - Dokument speichern</h3>
<p>
Klicke auf <strong>„Download“</strong>, um das Dokument zu speichern.<br>
Es öffnet sich anschließend ein Dateiexplorer, in dem du den gewünschten Speicherort auswählen
kannst.
</p>
</div>
</div>
<div class="step" id="createDoc">
<h2>Dokumententyp erstellen</h2>
<p>
- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü die Option <strong>„-- Neuen Dokumententyp erstellen
--“</strong>.<br>
- Vergib einen aussagekräftigen Namen für den neuen Dokumententyp.<br>
- Formuliere den Prompt für die KI-gestützte Verarbeitung sorgfältig.<br>
- Klicke auf <strong>Dokumententyp speichern</strong>.<br><br>
<strong>Hinweis:</strong> <br>Der eingegebene Prompt wird unverändert an einen KI-Dienst
übermittelt.
Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine
sensiblen oder personenbezogenen Daten ein.
</p>
</div>
<div class="step" id="editDoc">
<h2>Dokumententyp bearbeiten</h2>
<p>
- Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü den zu bearbeitenden Dokumententyp aus.<br>
- Überarbeite den bestehenden KI-Prompt oder formuliere einen neuen Prompt.<br>
- Klicke abschließend auf <strong>„Dokumententyp speichern“</strong>.<br><br>
<strong>Hinweis:</strong><br>
Der eingegebene Prompt wird unverändert an einen KI-Dienst übermittelt.
Achte daher unbedingt auf die Einhaltung der geltenden Datenschutzrichtlinien und gib keine
sensiblen oder personenbezogenen Daten ein.
</p>
</div>
<div class="step" id="deleteDoc">
<h2>Dokumententyp löschen</h2>
<p> - Öffne oben links das Burgermenü und wähle den Punkt <strong>„Dokumententypen
verwalten“</strong>.<br>
- Wähle anschließend im Auswahlmenü den zu löschenden Dokumententyp aus.<br>
- Klicke abschließend auf <strong>„Dokumententyp löschen“</strong>.<br><br>
<strong>Hinweis:</strong><br>
Nach Bestätigung des Löschvorgangs kann der Dokumententyp nicht wiederhergestellt werden.
</p>
</div>
</div>
</div>
<script>
function toggleTOC() {
document.getElementById("toc").classList.toggle("show");
}
function closeTOC() {
document.getElementById("toc").classList.remove("show");
}
document.addEventListener("click", function (e) {
const toc = document.getElementById("toc");
const toggle = document.querySelector(".toc-toggle");
if (!toc.contains(e.target) && !toggle.contains(e.target)) {
toc.classList.remove("show");
}
});
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

+72 -16
View File
@@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title id="title">Video to document</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/themes/light.css">
</head>
<body>
@@ -19,30 +20,66 @@
</label>
<nav class="menu1">
<a href="custom_document.html" class="li1">Manage document types</a>
<button id="customDocBtn" onclick="showCD()">Manage document types</button>
<a href="help_page.html" class="li1">Help</a>
</nav>
</nav>
</section>
<h1 id="h1">Video to document</h1>
<div class="gui-language">
<!-- to do: Ausprobieren mit li, a oder button, im Notfall ohne Flaggen Icons, kein hover-->
<select name="language_option" id="language_option"></select>
</div>
</div>
<div class="step-nav">
<div class="step-item active" data-step="1">1. Step</div>
<div class="step-item" data-step="2">2. Step</div>
<div class="step-item" data-step="3">3. Step</div>
<div class="step-item" data-step="4">4. Step</div>
<div class="step-item" data-step="5">5. Step</div>
<div class="step-item" data-step="6">6. Step</div>
<div class="step-item active" data-step="1" id="step_nav1">1. Step</div>
<div class="step-item" data-step="2" id="step_nav2">2. Step</div>
<div class="step-item" data-step="3" id="step_nav3">3. Step</div>
<div class="step-item" data-step="4" id="step_nav4">4. Step</div>
<div class="step-item" data-step="5" id="step_nav5">5. Step</div>
<div class="step-item" data-step="6" id="step_nav6">6. Step</div>
</div>
<div id="middleContainerWrapper" class="middle-container-wrapper">
<button id="prevBtn" class="navBtn" disabled>&larr;</button>
<!-- Visible middle part-->
<div class="mitte" id="mitte">
<!--Costum document section-->
<div class="container" id="cdContainer" style="display:none;">
<h1 id="cd_h1">Manage document types</h1>
<label for="existingDocs" id="cd_existingDocs">Select existing documents (optional):</label>
<!--Drop Down-->
<select name="existingDocs" id="existingDocs">
<option value="newDoc" id="newDoc">-- Create new document --</option>
</select>
<div id="docNameWrapper">
<label for="docName" id="cd_docName">Document name:</label>
<input type="text" id="docName" placeholder="Enter the document name here">
</div>
<label for="prompt" id="cd_promt">Your prompt:</label>
<textarea id="prompt" placeholder="Type the prompt for your document here..."></textarea>
<div class="buttons">
<button id="goBackBtn">Return</button>
<button id="deleteBtn">Delete document</button>
<button id="generateBtn">Save document</button>
</div>
<div id="result"></div>
</div>
<!-- Here starts code from step 1-->
<div class="step" id="step1">
<h2 class="h2">Upload your video here:</h2>
<div class="upload-container" id="uploadContainer">
<p id="p1">Drag and drop video file</p>
<video id="previewThumbnail" autoplay="false">
@@ -56,7 +93,9 @@
</div>
</div>
<!-- Here starts code from step 2-->
<div class="step" id="step2" style="display:none;">
<h2 class="h2">Choose your preferences:</h2>
<div class="KI-wrapper">
<label id="labelKI">Select ki:</label>
<select name="ai_type" id="ai_type"></select>
@@ -71,37 +110,48 @@
<label id="labelType">Select type:</label>
<select name="output_type" id="output_type">
<option value="pdf">.pdf</option>
<option value="word">.word</option>
<option value="word">.docx</option>
<option value="txt">.txt</option>
</select>
</div>
<div class="language-wrapper">
<label id="labelLanguage">Select language:</label>
<img id="labelLanguageFlag" src="flags/united-kingdom-flag-png-large.jpg" width="20" height="10" >
<select name="language_option" id="language_option">
<select name="document_language_option" id="document_language_option">
</select>
</div>
</div>
<!-- Here starts code from step 3-->
<!-- Hover Effekt für Dokumentenvorschau, Fragezeichen hinter Text, drüber hoven zeigt Beispieldokument -->
<div class="step" id="step3" style="display:none;">
<div class="checkbox-group">
<label id="checkbox-label" for="checkbox-group">Choose prefered document style:</label>
<h2 class="h2">Choose prefered document style:</h2>
<div class="checkbox-container">
<input type="checkbox" name ="docFormat" id="docFormat" value="followup-report">
<label id="label_format" for="docFormat">Follow-up Report</label>
<div class="figure1">
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png">
<img class="img-hover1" src="flags/germany-flag-png-large.jpg">
</div>
</div>
<div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary1" value="agenda">
<label id="label_summary" for="docFormatSummary">Agenda</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png">
</div>
<div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary2" value="result-protocol">
<label id="label_summary" for="docFormatSummary">Resultprotocol</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png">
</div>
<div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatSummary3" value="sprint-planning">
<label id="label_summary" for="docFormatSummary">Sprint Planning Note</label>
<img class="img-icon" src="icons/question-mark-button-icon--free-clip-art-30.png">
</div>
<div class="checkbox-container">
<input type="checkbox" name="docFormat" id="docFormatCustom" value="custom">
@@ -111,32 +161,36 @@
</div>
</div>
<!-- Here starts code from step 4-->
<div class="step" id="step4" style="display:none;">
<h2 class="h2">Click to submit:</h2>
<button class="submit-btn" id="submitButton" onclick="checkBoxes()" disabled>Submit</button>
<div class="testy" id="testy">
<div class="box2" id="box1">
</div>
<p>---Starting---</p>
<p id="box1_p1">---Starting---</p>
<div class="box2" id="box2">
</div>
<p>---Transkribing---</p>
<p id="box2_p2">---Transkribing---</p>
<div class="box2" id="box3">
</div>
<p>---Document creation---</p>
<p id="box3_p3">---Document creation---</p>
<div class="box2" id="box4">
</div>
</div>
</div>
<!-- Here starts code from step 5-->
<div class="step" id="step5" style="display:none;">
<h2 class="h2">Change names of the speakers:</h2>
<div class="speakerView" id="speakerView">
<label id="labelSpeaker">Select Speaker:</label>
<select name="cur_speaker" id="cur_speaker">
</select>
</div>
<div class="speakerAudio" id="speakerAutio">
<label id="labelSpeakerAudio">Selected Speaker</label>
<label id="labelSpeakerAudio">Selected Speaker:</label>
<audio controls id="speakerAudioViewer">
Currently there is no audio file here.
</audio>
@@ -151,7 +205,9 @@
</div>
</div>
<!-- Here starts code from step 6-->
<div class="step" id="step6" style="display:none;">
<h2 class="h2">Klick to download your document:</h2>
<button class="download-btn" id="downloadButton" onclick="fileDownload()">Download</button>
</div>
</div>
@@ -159,7 +215,7 @@
<button id ="nextBtn" class="navBtn">&rarr;</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/lc-select@1.3.0/lc_select.min.js"></script>
<script src="languages.js"></script>
<script src="script.js"></script>
<script src="./renderer.js"></script>
+92 -3
View File
@@ -12,7 +12,37 @@ var languageOptions = {
"checkbox_group": "Choose prefered document style:",
"label_format": "Meeting report",
"label_summary": "Summary with timestamps",
"submitButton": "Submit"
"submitButton": "Submit",
"step_nav1": "Step 1",
"step_nav2": "Step 2",
"step_nav3": "Step 3",
"step_nav4": "Step 4",
"step_nav5": "Step 5",
"step_nav6": "Step 6",
"h2": "Upload your video here:",
"labelSpeaker": "Select Speaker:",
"labelSpeakerAudio": "Selected Speaker:",
"labelSpeakerWriter": "Write name:",
"speakerLocker": "Rename speaker",
"speakerResender": "Rewrite document",
"downloadButton": "Download",
"box1_p1": "---Starting---",
"box2_p2": "---Transkribing---",
"box3_p3": "---Document creation---",
"labelType": "Select document type:",
"customDocBtn": "Manage document types",
"cd_h1": "Manage document types",
"cd_existingDocs": "Select existing documents (optional):",
"cd_docName": "Document name",
"docName": "Enter the document name here",
"cd_promt": "Your prompt:",
"prompt": "Type the prompt for your document here...",
"goBackBtn": "Return",
"deleteBtn": "Delete document",
"generateBtn": "Save document",
"newDoc": "-- Create new document --"
},
"de":{
"flagPath": "flags/germany-flag-png-large.jpg",
@@ -27,7 +57,36 @@ var languageOptions = {
"checkbox_group": "Bevorzugte Dokumentvarianten:",
"label_format": "Meeting Bericht",
"label_summary": "Zusammenfassung mit Zeitstempeln",
"submitButton": "Absenden"
"submitButton": "Absenden",
"step_nav1": "Schritt 1",
"step_nav2": "Schritt 2",
"step_nav3": "Schritt 3",
"step_nav4": "Schritt 4",
"step_nav5": "Schritt 5",
"step_nav6": "Schritt 6",
"h2": "Uploade dein Video hier:",
"labelSpeaker": "Wähle Sprecher:",
"labelSpeakerAudio": "Ausgewählter Sprecher:",
"labelSpeakerWriter": "Schreib Namen:",
"speakerLocker": "Ersetze Namen",
"speakerResender": "Überschreibe Dokument",
"downloadButton": "Download",
"box1_p1": "---Startet---",
"box2_p2": "---Transkribing---",
"box3_p3": "---Dokument kreieren---",
"labelType": "Wähle Dokumenttype:",
"customDocBtn": "Dokumenttypen verwalten",
"cd_h1": "Dokumenttypen verwalten",
"cd_existingDocs": "Vorhandene Dokumente auswählen (optional):",
"cd_docName": "Dokument Name",
"docName": "Geben Sie hier den Dokumentnamen ein",
"cd_promt": "Ihr Prompt:",
"prompt": "Geben Sie hier die Eingabeaufforderung für Ihr Dokument ein...",
"goBackBtn": "Zurück",
"deleteBtn": "Lösche Dokument",
"generateBtn": "Speicher Dokument",
"newDoc": "-- Neues Dokument erstellen --"
},
"in":{
"flagPath": "flags/india-flag-png-large.png",
@@ -42,7 +101,37 @@ var languageOptions = {
"checkbox_group": "पसंदीदा दस्तावेज़ शैली चुनें:",
"label_format": "बैठक रिपोर्ट",
"label_summary": "टाइमस्टैम्प के साथ सारांश",
"submitButton": "जमा करना"
"submitButton": "जमा करना",
"step_nav1": "स्टेप 1",
"step_nav2": "स्टेप 2",
"step_nav3": "स्टेप 3",
"step_nav4": "स्टेप 4",
"step_nav5": "स्टेप 5",
"step_nav6": "स्टेप 6",
"h2": "अपना वीडियो यहां अपलोड करें:",
"labelSpeaker": "स्पीकर चुनें:",
"labelSpeakerAudio": "चयनित वक्ता:",
"labelSpeakerWriter": "नाम लिखें:",
"speakerLocker": "स्पीकर का नाम बदलें",
"speakerResender": "दस्तावेज़ पुनः लिखें",
"downloadButton": "डाउनलोड करना",
"box1_p1": "---प्रारंभ---",
"box2_p2": "---प्रतिलेखन---",
"box3_p3": "---दस्तावेज़ निर्माण---",
"labelType": "दस्तावेज़ प्रकार चुनें:",
"customDocBtn": "दस्तावेज़ प्रकार प्रबंधित करें",
"cd_h1": "दस्तावेज़ प्रकार प्रबंधित करें",
"cd_existingDocs": "मौजूदा दस्तावेज़ों का चयन करें (वैकल्पिक):",
"cd_docName": "दस्तावेज़ का नाम",
"docName": "यहां दस्तावेज़ का नाम दर्ज करें",
"cd_promt": "आपका संकेत:",
"prompt": "अपने दस्तावेज़ के लिए प्रॉम्प्ट यहां टाइप करें...",
"goBackBtn": "वापस करना",
"deleteBtn": "दस्तावेज़ हटाएँ",
"generateBtn": "दस्तावेज़ सहेजें",
"newDoc": "-- नया दस्तावेज़ बनाएँ --"
}
};
+256 -108
View File
@@ -1,58 +1,102 @@
/*
uploadContainer.addEventListener("dragover", (e) =>{
Listeners for the program setup and changes
*/
//Listener for when the gui has been loaded so it can fill the dop down menus in step 2 and the language options
window.addEventListener('load', async (e) => {
try {
loadLanguageOptions();
const value = await window.onStartup.getModuleNames();
loadAiOptions(value.ai_modules);
loadTranscriptionOptions(value.transcription_modules);
} catch (error) {
console.log("Error in the window listener load in the renderer.js \n");
console.log(error);
}
});
//Listener if the language of the displayed text's in the gui should be changed
language_option.addEventListener('change', (e) => {
try {
const select = document.getElementById('language_option');
changeLanguage(select.value);
} catch (error) {
console.log("Error in the language_option change listener in the renderer.js");
console.log(error);
}
});
stepButtons.forEach(btn => {
btn.addEventListener("click", () => {
try {
e.stopPropagation();
e.preventDefault();
const step = parseInt(btn.dataset.step);
showStep(step);
} catch (error) {
console.log("Error in renderer.js dragover listener function")
}
});
});
//Listener if the button to change the current step to the previus one is pressed
prevBtn.addEventListener("click", () => {
try {
if (currentStep > 1) showStep(currentStep - 1);
} catch (error) {
}
});
//Listener if the button to change the current step to the next one is pressed
nextBtn.addEventListener("click", () => {
try {
if (currentStep < totalSteps) showStep(currentStep + 1);
} catch (error) {
}
});
/*
Listeners for Step 1
*/
//Listener if a file has been draged over the drop down field
uploadContainer.addEventListener("dragover", (e) => {
try {
e.stopPropagation();
e.preventDefault();
} catch (error) {
console.log("Error in renderer.js dragover listener function")
}
});
//listener for when a file get dropped on the drag&drop field
uploadContainer.addEventListener("drop", (e) => {
try {
e.stopPropagation()
e.preventDefault()
const files = e.dataTransfer.files
const filePath = window.explorer.onFileDrop(files[0])
const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathToLower = filePath.toLowerCase();
if(testEndings.some(e => pathToLower.endsWith(e))){
const files1 = e.dataTransfer.files;
handleFiles(files1);
}else{
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
}
} catch (error) {
console.log("Error in renderer.js with the listerner for the drop function");
console.log(error);
}
})
window.addEventListener('load', async (e) => {
try {
loadLanguageOptions();
const value = await window.onStartup.getModuleNames();
loadAiOptions(value.ai_modules);
loadTranscriptionOptions(value.transcription_modules);
e.stopPropagation()
e.preventDefault()
const files = e.dataTransfer.files
const filePath = window.explorer.onFileDrop(files[0])
const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathToLower = filePath.toLowerCase();
if (testEndings.some(e => pathToLower.endsWith(e))) {
const files1 = e.dataTransfer.files;
handleFiles(files1);
} else {
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
}
} catch (error) {
console.log("Error in renderer.js with the listerner for the drop function");
console.log(error);
}
});
language_option.addEventListener('change', (e)=>{
try {
const select = document.getElementById('language_option');
changeLanguage(select.value);
} catch (error) {
}
});
})
//listener for the file explorer search when something got selected
videoUpload.addEventListener("change", () => {
@@ -77,37 +121,39 @@ manualUploadBtn.addEventListener('click', () => {
});
stepButtons.forEach(btn => {
btn.addEventListener("click", () => {
try {
const step = parseInt(btn.dataset.step);
showStep(step);
} catch (error) {
/*
}
Listeners for Step 2
*/
/*
Listeners for Step 3
*/
window.api.getTxtFiles().then(files => {
var menu = document.getElementById('customDocumentTypes');
var l = document.getElementById('customDocumentTypes').options.length - 1;
for (i = l; i >= 0; i--) {
menu.remove(i);
}
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
menu.appendChild(option);
});
});
prevBtn.addEventListener("click", () => {
try {
if (currentStep > 1) showStep(currentStep - 1);
} catch (error) {
}
});
nextBtn.addEventListener("click", () => {
try {
if(currentStep < totalSteps) showStep(currentStep + 1);
} catch (error) {
}
});
//Checkboxlistener so that only one can be selected at a time
docFormat.addEventListener("change", (e) =>{
docFormat.addEventListener("change", (e) => {
try {
if(docFormat.checked){
if (docFormat.checked) {
docFormatSummary1.checked = false;
docFormatSummary2.checked = false;
docFormatSummary3.checked = false;
@@ -117,9 +163,9 @@ docFormat.addEventListener("change", (e) =>{
}
});
docFormatSummary1.addEventListener("change", (e) =>{
docFormatSummary1.addEventListener("change", (e) => {
try {
if(docFormatSummary1.checked){
if (docFormatSummary1.checked) {
docFormat.checked = false;
docFormatSummary2.checked = false;
docFormatSummary3.checked = false;
@@ -129,9 +175,9 @@ docFormatSummary1.addEventListener("change", (e) =>{
}
});
docFormatSummary2.addEventListener("change", (e) =>{
docFormatSummary2.addEventListener("change", (e) => {
try {
if(docFormatSummary2.checked){
if (docFormatSummary2.checked) {
docFormatSummary1.checked = false;
docFormat.checked = false;
docFormatSummary3.checked = false;
@@ -141,9 +187,9 @@ docFormatSummary2.addEventListener("change", (e) =>{
}
});
docFormatSummary3.addEventListener("change", (e) =>{
docFormatSummary3.addEventListener("change", (e) => {
try {
if(docFormatSummary3.checked){
if (docFormatSummary3.checked) {
docFormatSummary1.checked = false;
docFormatSummary2.checked = false;
docFormat.checked = false;
@@ -153,9 +199,9 @@ docFormatSummary3.addEventListener("change", (e) =>{
}
});
docFormatCustom.addEventListener("change", (e) =>{
docFormatCustom.addEventListener("change", (e) => {
try {
if(docFormatCustom.checked){
if (docFormatCustom.checked) {
docFormatSummary1.checked = false;
docFormatSummary2.checked = false;
docFormatSummary3.checked = false;
@@ -166,48 +212,40 @@ docFormatCustom.addEventListener("change", (e) =>{
}
});
//Speaker change listener
cur_speaker.addEventListener("change", (e) =>{
try {
document.getElementById("speakerAudioViewer").src = speakerAudios[document.getElementById("cur_speaker").value].src;
} catch (error) {
/*
}
});
window.audios.speakerAudios((event, arg) => {
loadSpeakerOptions(arg);
setSpeakerAudiosValue(arg);
});
Listeners for Step 4
*/
//Functions the the displayed progress in the progressbar can be changed out of the main process
window.electron.progress((event, arg) => {
if(arg.curstep == 1){
setCircleOne();
}else if(arg.curstep == 2){
setCircleZwo();
} else if(arg.curstep == 3){
setCircleThree();
}else if(arg.curstep == 4){
setCircleFour();
}
if (arg.curstep == 1) {
setCircleOne();
} else if (arg.curstep == 2) {
setCircleZwo();
} else if (arg.curstep == 3) {
setCircleThree();
} else if (arg.curstep == 4) {
setCircleFour();
}
});
function setCircleOne(){
function setCircleOne() {
try {
if(document.getElementById("box1").style.backgroundColor == "green"){
if (document.getElementById("box1").style.backgroundColor == "green") {
document.getElementById("box1").style.backgroundColor = "red";
}else{
} else {
document.getElementById("box1").style.backgroundColor = "green";
}
} catch (error) {
}
};
function setCircleZwo(){
function setCircleZwo() {
try {
if(document.getElementById("box2").style.backgroundColor == "green"){
if (document.getElementById("box2").style.backgroundColor == "green") {
document.getElementById("box2").style.backgroundColor = "red";
}else{
} else {
document.getElementById("box2").style.backgroundColor = "green";
}
} catch (error) {
@@ -215,11 +253,11 @@ function setCircleZwo(){
}
};
function setCircleThree(){
function setCircleThree() {
try {
if(document.getElementById("box3").style.backgroundColor == "green"){
if (document.getElementById("box3").style.backgroundColor == "green") {
document.getElementById("box3").style.backgroundColor = "red";
}else{
} else {
document.getElementById("box3").style.backgroundColor = "green";
}
} catch (error) {
@@ -227,11 +265,11 @@ function setCircleThree(){
}
};
function setCircleFour(){
function setCircleFour() {
try {
if(document.getElementById("box4").style.backgroundColor == "green"){
if (document.getElementById("box4").style.backgroundColor == "green") {
document.getElementById("box4").style.backgroundColor = "red";
}else{
} else {
document.getElementById("box4").style.backgroundColor = "green";
}
} catch (error) {
@@ -239,5 +277,115 @@ function setCircleFour(){
}
};
/*
Listeners for Step 5
*/
//Speaker change listener
cur_speaker.addEventListener("change", (e) => {
try {
document.getElementById("speakerAudioViewer").src = speakerAudios[document.getElementById("cur_speaker").value].src;
} catch (error) {
}
});
//Function so the main process can give the gui a json with the speakers and their audio
window.audios.speakerAudios((event, arg) => {
loadSpeakerOptions(arg);
setSpeakerAudiosValue(arg);
});
/*
Listeners for the costum documents section
*/
goBackBtn.addEventListener("click", () => {
showCD();
});
// dokumente speichern
generateBtn.addEventListener("click", () => {
const name = docName.value.trim();
const content = document.getElementById("prompt").value.trim();
if (!name || !content) {
result.textContent = "Bitte Dokumentname und Prompt ausfüllen.";
console.log(name + " " + content);
setTimeout(() => {
result.textContent = "";
}, 3000);
return;
}
window.api.saveTxtFile(name, content).then();
result.textContent = "Dokument erfolgreich gespeichert!";
setTimeout(() => {
result.textContent = "";
}, 3000);
reloadDocuments();
});
// dokumente löschen
deleteBtn.addEventListener("click", () => {
const name = docName.value.trim();
if (!name) {
result.textContent = "Bitte Dokumentname angeben.";
setTimeout(() => {
result.textContent = "";
}, 3000);
return;
}
const confirmDelete = confirm(
`Möchtest du das Dokument "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => {
if (success) {
result.textContent = "Dokument erfolgreich gelöscht!";
reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change"));
} else {
result.textContent = "Dokument konnte nicht gelöscht werden.";
}
setTimeout(() => {
result.textContent = "";
}, 3000);
});
});
//function to load existingDoc options to the drop down list
window.api.getTxtFiles().then(files => {
reloadDocuments();
});
//content anzeigen
existingDocs.addEventListener("change", async () => {
const existingDocsed = existingDocs.value;
const exampleText = "";
if (existingDocsed === "newDoc") {
docNameWrapper.classList.remove("hidden");
docName.value = "";
prompt.value = exampleText;
return;
}
docNameWrapper.classList.add("hidden");
const content = await window.api.readTxtFile(existingDocsed);
prompt.value = content;
docName.value = existingDocsed.replace(".txt", "");
});
+354 -206
View File
@@ -1,95 +1,73 @@
let currentVideoPath = null;
//function to check if one checkbox is at least klicked
function checkBoxes() {
try {
const checkboxes = document.querySelectorAll('input[name="docFormat"]');
let isChecked = false;
var checkedCounter = 0;
checkboxes.forEach(function(checkbox){
if(checkbox.checked){
isChecked = true;
checkedCounter++;
}
});
if (isChecked) {
//Code to submit the video
var selectedCheckboxes = {};
checkboxes.forEach(function(checkbox){
if(checkbox.checked){
selectedCheckboxes[checkbox.nextElementSibling.textContent] = "";
}
});
/*
const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathTest = window.electronAPI.getFilePath(videoUpload.files[0]);
var pathToLower = pathTest.toLowerCase();
if(testEndings.some(e => pathToLower.endsWith(e))){
//assembly of the json for the main
Functions used in the setup or affect most of the gui
var typeCheckbox;
if(document.getElementById("docFormat").checked) typeCheckbox = document.getElementById("docFormat").value;
if(document.getElementById("docFormatSummary1").checked) typeCheckbox = document.getElementById("docFormatSummary1").value;
if(document.getElementById("docFormatSummary2").checked) typeCheckbox = document.getElementById("docFormatSummary2").value;
if(document.getElementById("docFormatSummary3").checked) typeCheckbox = document.getElementById("docFormatSummary3").value;
if(document.getElementById("docFormatCustom").checked) typeCheckbox = document.getElementById("docFormatCustom").value;
document.getElementById("testy").style.visibility = "visible"
document.getElementById("box1").style.backgroundColor = "red";
document.getElementById("box2").style.backgroundColor = "red";
document.getElementById("box3").style.backgroundColor = "red";
document.getElementById("box4").style.backgroundColor = "red";
console.log(selectedCheckboxes);
const outputType = document.getElementById("output_type");
const transcriptionType = document.getElementById("transkript_type");
const aiType = document.getElementById("ai_type");
const sendingPackage = {
"video": {
"module":"extraction-video-to-audio",
"inputVideoPath": pathTest
},
"transcription": {
"module": transcriptionType.value
},
"document": {
"module":aiType.value,
"type": typeCheckbox,
"outputType": outputType.value
}
};
window.submit.submit(sendingPackage)
}else{
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
}
} else {
//language only english at the moment
alert('Please select at least one document type.');
}
} catch (error) {
console.log("Error in script.js checkBoxes function");
console.log(error);
*/
var showCDValue = 0;
function showCD() {
if(showCDValue == 0){
document.getElementById('cdContainer').style.display = "block";
document.getElementById('step1').style.display ="none";
document.getElementById('step2').style.display ="none";
document.getElementById('step3').style.display ="none";
document.getElementById('step4').style.display ="none";
document.getElementById('step5').style.display ="none";
document.getElementById('step6').style.display ="none";
showCDValue = 1;
} else {
currentStep = 1;
showCDValue = 0;
document.getElementById('cdContainer').style.display = "none";
showStep(1);
}
}
//language changing feature
//language changing feature => changes the language of every displayed text
function changeLanguage(language) {
try {
document.getElementById('labelLanguageFlag').src = languageOptions[language].flagPath;
//document.getElementById('labelLanguageFlag').src = languageOptions[language].flagPath;
document.getElementById('labelKI').textContent = languageOptions[language].labelKI;
document.getElementById('labelTranscription').textContent = languageOptions[language].labelTranscription;
document.getElementById('labelLanguage').textContent = languageOptions[language].labelLanguage;
document.getElementById('title').textContent = languageOptions[language].title;
document.getElementById('h1').textContent = languageOptions[language].h1;
//document.getElementById('h1').textContent = languageOptions[language].h1;
document.getElementById('p1').textContent = languageOptions[language].p1;
document.getElementById('fileName').textContent = languageOptions[language].fileName;
document.getElementById('manualUploadBtn').textContent = languageOptions[language].manualUploadBtn;
document.getElementById('checkbox_group').textContent = languageOptions[language].checkbox_group;
document.getElementById('label_format').textContent = languageOptions[language].label_format;
document.getElementById('label_summary').textContent = languageOptions[language].label_summary;
document.getElementById('submitButton').textContent = languageOptions[language].submitButton;
document.getElementById('step_nav1').textContent = languageOptions[language].step_nav1;
document.getElementById('step_nav2').textContent = languageOptions[language].step_nav2;
document.getElementById('step_nav3').textContent = languageOptions[language].step_nav3;
document.getElementById('step_nav4').textContent = languageOptions[language].step_nav4;
document.getElementById('step_nav5').textContent = languageOptions[language].step_nav5;
document.getElementById('step_nav6').textContent = languageOptions[language].step_nav6;
//document.getElementById('h2').textContent = languageOptions[language].h2;
document.getElementById('labelSpeaker').textContent = languageOptions[language].labelSpeaker;
document.getElementById('labelSpeakerAudio').textContent = languageOptions[language].labelSpeakerAudio;
document.getElementById('labelSpeakerWriter').textContent = languageOptions[language].labelSpeakerWriter;
document.getElementById('speakerLocker').textContent = languageOptions[language].speakerLocker;
document.getElementById('speakerResender').textContent = languageOptions[language].speakerResender;
document.getElementById('downloadButton').textContent = languageOptions[language].downloadButton;
document.getElementById('box1_p1').textContent = languageOptions[language].box1_p1;
document.getElementById('box2_p2').textContent = languageOptions[language].box2_p2;
document.getElementById('box3_p3').textContent = languageOptions[language].box3_p3;
document.getElementById('labelType').textContent = languageOptions[language].labelType;
document.getElementById('customDocBtn').textContent = languageOptions[language].customDocBtn;
document.getElementById('cd_h1').textContent = languageOptions[language].cd_h1;
document.getElementById('cd_existingDocs').textContent = languageOptions[language].cd_existingDocs;
document.getElementById('cd_docName').textContent = languageOptions[language].cd_docName;
document.getElementById('docName').placeholder = languageOptions[language].docName;
document.getElementById('cd_promt').textContent = languageOptions[language].cd_promt;
document.getElementById('prompt').placeholder = languageOptions[language].prompt;
document.getElementById('goBackBtn').textContent = languageOptions[language].goBackBtn;
document.getElementById('deleteBtn').textContent = languageOptions[language].deleteBtn;
document.getElementById('generateBtn').textContent = languageOptions[language].generateBtn;
document.getElementById('newDoc').textContent = languageOptions[language].newDoc;
} catch (error) {
console.log("Error in script.js changeLanguage function");
@@ -98,6 +76,43 @@ function changeLanguage(language) {
}
/*
Functions used for the step navigation
*/
//Step-navigation
const steps = document.querySelectorAll(".step");
const stepButtons = document.querySelectorAll(".step-item");
let currentStep = 1;
const totalSteps = steps.length;
function showStep(stepNumber) {
if (stepNumber < 1 || stepNumber > totalSteps) {
console.error("StepNumber out of Bounds", stepNumber);
return;
}
steps.forEach(step => step.style.display = "none");
document.getElementById("step" + stepNumber).style.display = "flex";
stepButtons.forEach(btn => btn.classList.remove("active"));
document.querySelector(`.step-item[data-step="${stepNumber}"]`).classList.add("active");
const activeBtn = document.querySelector(`.step-item[data-step="${stepNumber}"]`);
if (activeBtn) activeBtn.classList.add("active");
prevBtn.disabled = stepNumber == 1;
nextBtn.disabled = stepNumber === totalSteps;
currentStep = stepNumber;
}
/*
Functions used in Step 1
*/
//function to display the file path in the drop down box
function handleFiles(files) {
try {
@@ -119,6 +134,220 @@ function handleFiles(files) {
}
//Video thumbnail generation. Shows a scene from the selected video file as a preview
function generateThumbnail(path) {
try {
const videoElement = document.getElementById("previewThumbnail");
while (videoElement.firstChild) videoElement.removeChild(videoElement.firstChild);
videoElement.src = path;
videoElement.type = "video/mov";
videoElement.load();
videoElement.style.maxWidth = 40;
videoElement.style.maxHeight = 40;
videoElement.autoplay = false;
} catch (error) {
console.log("Error in the generateThumbnail function in the script.js file \n");
console.log(error);
}
}
/*
Functions used in Step 2
*/
//function to load ai options to the drop down list
function loadAiOptions(options) {
try {
var menu = document.getElementById('ai_type');
var object_holdy;
var choice;
object_holdy = options
for (i = 0; i < options.length; i++) {
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js loadAiOptions function");
console.log(error);
}
}
//function to load transcription options to the drop down list
function loadTranscriptionOptions(options) {
try {
var menu = document.getElementById('transkript_type');
var object_holdy;
var choice;
object_holdy = options
for (i = 0; i < options.length; i++) {
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js function loadTranscriptionOptions");
console.log(error);
}
}
//function to load data type options to the drop down list
function loadDataTypeOptions(options) {
try {
var menu = document.getElementById('output_type');
var object_holdy;
var choice;
object_holdy = options
for (i = 0; i < options.length; i++) {
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js function loadDataTypeOptions");
console.log(error);
}
}
//function to load language options to the drop down list
function loadLanguageOptions() {
try {
var menu = document.getElementById('language_option');
var menu_doc = document.getElementById('document_language_option');
var object_holdy;
var choice;
var choice2;
object_holdy = Object.keys(languageOptions);
for (i = 0; i < object_holdy.length; i++) {
choice = document.createElement('option');
choice.textContent = object_holdy[i];
choice.value = object_holdy[i];
choice.setAttribute('data-image', languageOptions[object_holdy[i]].flagPath);
choice2 = document.createElement('option');
choice2.textContent = object_holdy[i];
choice2.value = object_holdy[i];
choice2.setAttribute('data-image', languageOptions[object_holdy[i]].flagPath);
menu_doc.appendChild(choice2);
menu.appendChild(choice);
}
new lc_select(document.getElementById('language_option')); //loads the flag images so they get displayed in the gui
new lc_select(document.getElementById('document_language_option'));
} catch (error) {
console.log("Error in script.js loadLanguageOptions function");
console.log(error);
}
}
/*
Functions used in Step 3
*/
/*
Functions used in Step 4
*/
//function to check if one checkbox is at least clicked. Final controll function before sending the input to the generation
function checkBoxes() {
try {
const checkboxes = document.querySelectorAll('input[name="docFormat"]');
let isChecked = false;
var checkedCounter = 0;
checkboxes.forEach(function (checkbox) {
if (checkbox.checked) {
isChecked = true;
checkedCounter++;
}
});
if (isChecked) {
//Code to submit the video
var selectedCheckboxes = {};
checkboxes.forEach(function (checkbox) {
if (checkbox.checked) {
selectedCheckboxes[checkbox.nextElementSibling.textContent] = "";
}
});
const testEndings = [".mp4", ".mov", ".avi", ".mkv"];
var pathTest = window.electronAPI.getFilePath(videoUpload.files[0]);
var pathToLower = pathTest.toLowerCase();
if (testEndings.some(e => pathToLower.endsWith(e))) {
//assembly of the json for the main
var typeCheckbox;
if (document.getElementById("docFormat").checked) typeCheckbox = document.getElementById("docFormat").value;
if (document.getElementById("docFormatSummary1").checked) typeCheckbox = document.getElementById("docFormatSummary1").value;
if (document.getElementById("docFormatSummary2").checked) typeCheckbox = document.getElementById("docFormatSummary2").value;
if (document.getElementById("docFormatSummary3").checked) typeCheckbox = document.getElementById("docFormatSummary3").value;
if (document.getElementById("docFormatCustom").checked) typeCheckbox = document.getElementById("docFormatCustom").value;
document.getElementById("testy").style.visibility = "visible"
document.getElementById("box1").style.backgroundColor = "red";
document.getElementById("box2").style.backgroundColor = "red";
document.getElementById("box3").style.backgroundColor = "red";
document.getElementById("box4").style.backgroundColor = "red";
console.log(selectedCheckboxes);
const outputType = document.getElementById("output_type");
const transcriptionType = document.getElementById("transkript_type");
const aiType = document.getElementById("ai_type");
const sendingPackage = {
"video": {
"module": "extraction-video-to-audio",
"inputVideoPath": pathTest
},
"transcription": {
"module": transcriptionType.value
},
"document": {
"module": aiType.value,
"type": typeCheckbox,
"outputType": outputType.value
}
};
window.submit.submit(sendingPackage)
} else {
alert('The given file is not compatible. These are the available types: [".mp4", ".mov", ".avi", ".mkv"].');
}
} else {
//language only english at the moment
alert('Please select at least one document type.');
}
} catch (error) {
console.log("Error in script.js checkBoxes function");
console.log(error);
}
}
//function the the submit button on step 4 can be pressed
function activateSubmitBtn(hasFile) {
try {
document.getElementById("submitButton").disabled = !hasFile;
} catch (error) {
console.log(error);
}
}
//function to regulate the progress on the progressbar
function updateProgressBar(bar, value) {
try {
@@ -132,94 +361,34 @@ function updateProgressBar(bar, value) {
}
//function to load ai options to the drop down list
function loadAiOptions(options){
//function to hide the progressbar
function deaktivateProgressbar() {
try {
var menu = document.getElementById('ai_type');
var object_holdy;
var choice ;
object_holdy = options
for(i = 0; i < options.length; i++){
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
document.getElementById("progressbar").style.visibility = "hidden";
} catch (error) {
console.log("Error in script.js loadAiOptions function");
console.log(error);
}
}
//function to load transcription options to the drop down list
function loadTranscriptionOptions(options){
try {
var menu = document.getElementById('transkript_type');
var object_holdy;
var choice ;
object_holdy = options
for(i = 0; i < options.length; i++){
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js function loadTranscriptionOptions");
console.log(error);
}
}
/*
//function to load data type options to the drop down list
function loadDataTypeOptions(options){
try {
var menu = document.getElementById('output_type');
var object_holdy;
var choice ;
object_holdy = options
for(i = 0; i < options.length; i++){
choice = document.createElement('option');
choice.textContent = object_holdy[i].displayname;
choice.value = object_holdy[i].name;
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js function loadDataTypeOptions");
console.log(error);
}
}
Functions used in Step 5
*/
//function to load language options to the drop down list
function loadLanguageOptions(){
try {
var menu = document.getElementById('language_option');
var object_holdy;
var choice ;
object_holdy = Object.keys(languageOptions);
for(i = 0; i < object_holdy.length; i++){
choice = document.createElement('option');
choice.textContent = object_holdy[i];
choice.value = object_holdy[i];
menu.appendChild(choice);
}
} catch (error) {
console.log("Error in script.js loadLanguageOptions function");
console.log(error);
}
}
//function to load speaker options to the drop down list
function loadSpeakerOptions(options){
function loadSpeakerOptions(options) {
try {
var menu = document.getElementById('cur_speaker');
var l = document.getElementById('cur_speaker').options.length -1;
for(i = l; i >= 0; i--){
var l = document.getElementById('cur_speaker').options.length - 1;
for (i = l; i >= 0; i--) {
menu.remove(i);
}
var object_holdy;
var choice;
object_holdy = Object.keys(options);
for(i = 0; i < object_holdy.length; i++){
for (i = 0; i < object_holdy.length; i++) {
choice = document.createElement('option');
choice.textContent = options[object_holdy[i]].name;
choice.value = object_holdy[i];
@@ -233,7 +402,7 @@ function loadSpeakerOptions(options){
}
//function to load speaker audio file options to the drop down list
function loadSpeakerAudio(option){
function loadSpeakerAudio(option) {
try {
var menu = document.getElementById('speakerAudioViewer');
var aud = document.createElement("source");
@@ -245,65 +414,10 @@ function loadSpeakerAudio(option){
}
}
function activateSubmitBtn(hasFile){
try {
document.getElementById("submitButton").disabled = !hasFile;
} catch (error) {
console.log(error);
}
}
function deaktivateProgressbar(){
try {
document.getElementById("progressbar").style.visibility = "hidden";
} catch (error) {
console.log(error);
}
}
//Video thumbnail generation
function generateThumbnail(path){
const videoElement = document.getElementById("previewThumbnail");
while (videoElement.firstChild) videoElement.removeChild(videoElement.firstChild);
videoElement.src = path;
videoElement.type = "video/mov";
videoElement.load();
videoElement.style.maxWidth = 40;
videoElement.style.maxHeight = 40;
videoElement.autoplay = false;
}
//Step-navigation
const steps = document.querySelectorAll(".step");
const stepButtons = document.querySelectorAll(".step-item");
let currentStep = 1;
const totalSteps = steps.length;
function showStep(stepNumber) {
if (stepNumber < 1 || stepNumber > totalSteps){
console.error("StepNumber out of Bounds", stepNumber);
return;
}
steps.forEach(step => step.style.display = "none");
document.getElementById("step" + stepNumber).style.display = "flex";
stepButtons.forEach(btn => btn.classList.remove("active"));
document.querySelector(`.step-item[data-step="${stepNumber}"]`).classList.add("active");
const activeBtn = document.querySelector(`.step-item[data-step="${stepNumber}"]`);
if(activeBtn) activeBtn.classList.add("active");
prevBtn.disabled = stepNumber == 1;
nextBtn.disabled = stepNumber === totalSteps;
currentStep = stepNumber;
}
//Audio value setter
var speakerAudios = {};
var speakerEndValues = {};
function setSpeakerAudiosValue(valy){
function setSpeakerAudiosValue(valy) {
try {
speakerAudios = valy;
speakerRewriten = valy;
@@ -312,8 +426,8 @@ function setSpeakerAudiosValue(valy){
}
}
function rewriteSpeakerName(){
//Function to rewrite the speaker name in the json
function rewriteSpeakerName() {
try {
var tempy = document.getElementById("cur_speaker").value;
speakerAudios[tempy].name = document.getElementById("newSpeaker").value;
@@ -322,15 +436,21 @@ function rewriteSpeakerName(){
console.log("\n\n\n" + error + "\n\n\n")
}
}
function sendSpeakerPackages(){
//Function to send the json with the given names back to the program to rewrite the document file
function sendSpeakerPackages() {
try {
window.submitSpeaker.speaker_submit(speakerAudios);
} catch (error) {
console.log(error);
}
}
/*
Functions for Step 6
*/
function fileDownload() {
try {
window.download.file_download();
@@ -338,3 +458,31 @@ function fileDownload() {
console.error("Download failed:", error);
}
}
/*
Functions for the custom document section
*/
//reload drop down
function reloadDocuments() {
[...existingDocs.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove());
window.api.getTxtFiles().then(files => {
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
existingDocs.appendChild(option);
});
});
}
+205 -89
View File
@@ -22,10 +22,10 @@ body {
#h1-wrapper {
position: relative;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
width: 770px;
width: 780px;
height: 60px;
background-color: #FFF;
box-shadow: 0px 4px 10px rgba(0,0,0,0.1);
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
border-radius: 5px;
margin-bottom: 10px;
display: flex;
@@ -36,7 +36,7 @@ body {
background: white;
padding: 40px;
border-radius: 12px;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
text-align: center;
width: 350px;
height: 200px;
@@ -78,7 +78,7 @@ body {
width: 200px;
height: auto;
border-radius: 10px;
box-shadow: 0px 4px 10px rgba(0,0,0,0.1);
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
object-fit: cover;
}
@@ -109,11 +109,11 @@ body {
}
#step2 {
gap: 30px;
gap: 25px;
}
.KI-wrapper {
margin-top: 40px;
margin-top: 10px;
}
input[type="file"] {
@@ -121,58 +121,64 @@ input[type="file"] {
}
.checkbox-group {
--borderColor: #007bfff5;
--borderWidth: .125em;
}
--borderColor: #007bfff5;
--borderWidth: .125em;
}
.checkbox-group input[type=checkbox] {
-webkit-appearance: none;
appearance: none;
vertical-align: middle;
background: #fff;
font-size: 1.8em;
border-radius: 0.125em;
display: inline-block;
border: var(--borderWidth) solid var(--borderColor);
width: 1em;
height: 1em;
position: relative;
}
.checkbox-group input[type=checkbox]:before,
.checkbox-group input[type=checkbox]:after {
content: "";
position: absolute;
background: var(--borderColor);
width: calc(var(--borderWidth) * 3);
height: var(--borderWidth);
top: 50%;
left: 10%;
transform-origin: left center;
}
.checkbox-group input[type=checkbox]:before {
transform: rotate(45deg) translate(calc(var(--borderWidth) / -2), calc(var(--borderWidth) / -2)) scaleX(0);
transition: transform 200ms ease-in 200ms;
}
.checkbox-group input[type=checkbox]:after {
width: calc(var(--borderWidth) * 5);
transform: rotate(-45deg) translateY(calc(var(--borderWidth) * 2)) scaleX(0);
transform-origin: left center;
transition: transform 200ms ease-in;
}
.checkbox-group input[type=checkbox]:checked:before {
transform: rotate(45deg) translate(calc(var(--borderWidth) / -2), calc(var(--borderWidth) / -2)) scaleX(1);
transition: transform 200ms ease-in;
}
.checkbox-group input[type=checkbox]:checked:after {
width: calc(var(--borderWidth) * 5);
transform: rotate(-45deg) translateY(calc(var(--borderWidth) * 2)) scaleX(1);
transition: transform 200ms ease-out 200ms;
}
.checkbox-group input[type=checkbox]:focus {
outline: calc(var(--borderWidth) / 2) dotted rgba(0, 0, 0, 0.25);
}
.checkbox-group input[type=checkbox] {
-webkit-appearance: none;
appearance: none;
vertical-align: middle;
background: #fff;
font-size: 1.8em;
border-radius: 0.125em;
display: inline-block;
border: var(--borderWidth) solid var(--borderColor);
width: 1em;
height: 1em;
position: relative;
}
.checkbox-container{
.checkbox-group input[type=checkbox]:before,
.checkbox-group input[type=checkbox]:after {
content: "";
position: absolute;
background: var(--borderColor);
width: calc(var(--borderWidth) * 3);
height: var(--borderWidth);
top: 50%;
left: 10%;
transform-origin: left center;
}
.checkbox-group input[type=checkbox]:before {
transform: rotate(45deg) translate(calc(var(--borderWidth) / -2), calc(var(--borderWidth) / -2)) scaleX(0);
transition: transform 200ms ease-in 200ms;
}
.checkbox-group input[type=checkbox]:after {
width: calc(var(--borderWidth) * 5);
transform: rotate(-45deg) translateY(calc(var(--borderWidth) * 2)) scaleX(0);
transform-origin: left center;
transition: transform 200ms ease-in;
}
.checkbox-group input[type=checkbox]:checked:before {
transform: rotate(45deg) translate(calc(var(--borderWidth) / -2), calc(var(--borderWidth) / -2)) scaleX(1);
transition: transform 200ms ease-in;
}
.checkbox-group input[type=checkbox]:checked:after {
width: calc(var(--borderWidth) * 5);
transform: rotate(-45deg) translateY(calc(var(--borderWidth) * 2)) scaleX(1);
transition: transform 200ms ease-out 200ms;
}
.checkbox-group input[type=checkbox]:focus {
outline: calc(var(--borderWidth) / 2) dotted rgba(0, 0, 0, 0.25);
}
.checkbox-container {
margin-top: 8px;
display: flex;
justify-items: left;
@@ -180,13 +186,38 @@ input[type="file"] {
gap: 5px;
}
.figure1 {
position: relative;
}
.img-hover1 {
position: absolute;
width: 200px;
height: 200px;
top: 0;
right: 40%;
left: 0;
bottom: 0;
object-fit: contain;
display: none;
transition: opacity .2s;
}
.figure1:hover .img-hover1 {
display: flex;
}
.img-icon {
width: 15px;
height: 15px;
}
.submit-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 10px 20px;
margin: 130px auto 10px auto;
margin: 110px auto 10px auto;
background-color: #007BFF;
color: white;
border: none;
@@ -204,19 +235,19 @@ input[type="file"] {
.mitte {
background-color: #FFF;
display: flex;
width: 700px;
width: 780px;
height: 500px;
flex-direction: column;
align-items: center;
padding: 40px;
gap: 10px;
border: 0px;
border-color: black;
border-style: solid;
border-radius: 6px;
box-shadow: 0px 4px 10px rgba(0,0,0,0.1);
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
}
.progressbar{
.progressbar {
position: relative;
width: 210px;
height: 30px;
@@ -227,14 +258,14 @@ input[type="file"] {
visibility: hidden;
}
.progress_fill{
.progress_fill {
width: 0%;
height: 100%;
background: green;
transition: all 0.2s;
}
.progress_text{
.progress_text {
position: absolute;
top: 50%;
right: 5px;
@@ -252,7 +283,9 @@ input[type="file"] {
padding: 2px 10px 2px 10px;
}
#ai_type, #transkript_type, #language_option {
#ai_type,
#transkript_type,
#language_option {
padding: 3px;
}
@@ -260,7 +293,7 @@ input[type="file"] {
gap: 60px;
display: flex;
justify-content: center;
overflow-wrap:inherit;
overflow-wrap: inherit;
padding-bottom: 20px;
margin-top: 40px;
margin-bottom: 10px;
@@ -274,7 +307,9 @@ input[type="file"] {
background: #fff;
padding: 10px 30px;
border-radius: 6px;
box-shadow: 0 4px 10px rgba(0,0,0,0.1);
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
max-width: 720px;
min-width: 720px;
}
.step-item {
@@ -297,10 +332,12 @@ input[type="file"] {
/*panels*/
.step {
margin-top: 70px;
margin-top: 40px;
margin-bottom: 40px;
;
display: flex;
flex-direction: column;
min-height: 400px;
min-height: 425px;
}
/*Navigation arrows*/
@@ -336,7 +373,7 @@ input[type="file"] {
cursor: not-allowed;
}
.testy{
.testy {
background-color: #FFF;
display: flex;
width: auto;
@@ -352,13 +389,13 @@ input[type="file"] {
}
.box2 {
background-color: red;
width: 40px;
height: 40px;
padding: 5px;
border: 1px solid black;
margin: 5px;
border-radius: 100px;
background-color: red;
width: 40px;
height: 40px;
padding: 5px;
border: 1px solid black;
margin: 5px;
border-radius: 100px;
}
li {
@@ -394,24 +431,24 @@ li {
display: none;
}
#toggle1:checked + .hamburger1 .top {
#toggle1:checked+.hamburger1 .top {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
transform: rotate(-45deg);
margin-top: 22.5px;
}
#toggle1:checked + .hamburger1 .meat {
#toggle1:checked+.hamburger1 .meat {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
transform: rotate(45deg);
margin-top: -5px;
}
#toggle1:checked + .hamburger1 .bottom {
#toggle1:checked+.hamburger1 .bottom {
-webkit-transform: scale(0);
transform: scale(0);
transform: scale(0);
}
#toggle1:checked ~ .menu1 {
#toggle1:checked~.menu1 {
height: 150px;
width: 300px;
}
@@ -465,7 +502,9 @@ li {
transition: all 0.3s ease;
}
#step2, #step3, #step5 {
#step2,
#step3,
#step5 {
font-size: larger;
}
@@ -489,10 +528,7 @@ li {
align-items: center;
justify-content: center;
padding: 10px 20px;
margin-left: auto;
margin-right: 0px;
margin-top: 130px;
margin-bottom: 10px;
margin: 110px auto 10px auto;
background-color: #007BFF;
color: white;
border: none;
@@ -501,7 +537,8 @@ li {
font-size: 14px;
}
#speakerLocker, #speakerResender{
#speakerLocker,
#speakerResender {
padding: 10px 20px;
margin: 20px auto;
background-color: #007BFF;
@@ -511,3 +548,82 @@ li {
cursor: pointer;
font-size: 14px;
}
.h2 {
font-size: 25px;
}
.speakerView,
.speakerAudio,
.speakerWrite {
margin-top: auto;
margin-bottom: auto;
}
.container {
background: white;
padding: 30px;
margin-top: 50px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
width: 90%;
max-width: 650px;
}
input[type="text"],
textarea,
select {
width: 80%;
padding: 10px;
margin-top: 5px;
border-radius: 6px;
border: 1px solid #ccc;
font-size: 14px;
}
textarea {
height: 120px;
resize: vertical;
}
.buttons {
display: flex;
justify-content: space-between;
margin-top: 25px;
}
.hidden {
visibility: hidden;
}
button {
padding: 10px 20px;
font-size: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
transition: 0.2s;
background-color: #007BFF;
color: white;
}
button:hover {
background-color: #0056b3;
}
@media (max-width: 500px) {
.buttons {
flex-direction: column;
}
.buttons button {
width: 100%;
margin-top: 10px;
}
}
#result {
margin-top: 20px;
color: #333;
word-break: break-word;
}