Skip to content

Commit

Permalink
support for images
Browse files Browse the repository at this point in the history
  • Loading branch information
DominikPeters committed Nov 24, 2023
1 parent da49b7a commit c9ce44c
Show file tree
Hide file tree
Showing 11 changed files with 3,691 additions and 2,141 deletions.
Binary file added img/placeholder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
238 changes: 188 additions & 50 deletions index.html

Large diffs are not rendered by default.

9 changes: 4 additions & 5 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { setTextAreaContent, displayChapterList, updateChapterListBasedOnTextare
import { loadFile } from './src/FileLoader.js';
import { exportFile } from './src/FileExport.js';
import { initializeDragDrop } from './src/dragDropHandler.js';
import { initializeImageHandling } from './src/ImageHandler.js';

const chapters = new ChapterList();
window.chapters = chapters;
Expand Down Expand Up @@ -48,6 +49,8 @@ chapters.addEventListener((chapters) => {
});

document.addEventListener('DOMContentLoaded', function () {
initializeImageHandling();

const textInput = document.getElementById('text-input');
textInput.addEventListener('blur', updateChapterListBasedOnTextarea);
textInput.addEventListener('mousedown', editText);
Expand Down Expand Up @@ -79,11 +82,6 @@ document.addEventListener('DOMContentLoaded', function () {
});
});

function addImage(lineIndex) {
console.log('Add image at line', lineIndex);
// Implement your image adding logic here
}

const wave = WaveSurfer.create({
container: '#wave',
waveColor: 'violet',
Expand Down Expand Up @@ -124,6 +122,7 @@ wave.on('ready', () => {
player.addEventListener('loaded-data', () => {
addChaptersToPlayer();
});

player.addEventListener('play', () => {
addChaptersToPlayer();
});
Expand Down
5,167 changes: 3,116 additions & 2,051 deletions node-id3-browserify.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion src/ChapterList.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export class ChapterList {

set duration(newDuration) {
this._duration = newDuration;
this.setChapters(this.chapters);
if (newDuration != -1) {
this.setChapters(this.chapters);
}
}

get duration() {
Expand Down
89 changes: 62 additions & 27 deletions src/ChapterListEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,40 @@ const linkSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
<path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243z"/>
</svg>`;

function extractUrl(str) {
const urlRegex = / https?:\/\/[^\s]+$/;
const match = str.match(urlRegex);
if (match) {
const url = match[0];
const stringWithoutUrl = str.replace(urlRegex, '').trim();
return { url, stringWithoutUrl };
} else {
// No URL found, return null for the URL and the original string
return { url: null, stringWithoutUrl: str };
const imageSVG = `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-image" viewBox="0 0 16 16">
<path d="M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0"/>
<path d="M2.002 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2h-12zm12 1a1 1 0 0 1 1 1v6.5l-3.777-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12V3a1 1 0 0 1 1-1h12"/>
</svg>`;

function removeLastOccurrence(str, substring) {
const index = str.lastIndexOf(substring);
if (index === -1) {
return str;
}
return str.substring(0, index) + str.substring(index + substring.length);
}

function extractElements(str) {
const urlRegex = /https?:\/\/[^\s]+/g;
const imgTagRegex = /<img-(\d+)>/g;

let urlMatches = str.match(urlRegex);
let imgTagMatches = str.match(imgTagRegex);

let url = urlMatches ? urlMatches[urlMatches.length - 1].trim() : null;
let imgTag = imgTagMatches ? imgTagMatches[imgTagMatches.length - 1].match(/\d+/)[0] : null;

let stringWithoutElements = str;

// Remove the last occurrence of each element
if (url) {
stringWithoutElements = removeLastOccurrence(stringWithoutElements, url);
}
if (imgTag) {
stringWithoutElements = removeLastOccurrence(stringWithoutElements, imgTagMatches[imgTagMatches.length - 1].trim());
}

return { url, imgTag, stringWithoutElements };
}

export function updateChapterListBasedOnTextarea() {
Expand All @@ -42,11 +65,15 @@ export function updateChapterListBasedOnTextarea() {
}
chapter.start = time;

const { url, stringWithoutUrl } = extractUrl(title);
chapter.title = stringWithoutUrl;
if (url) {
chapter.url = url.trim();
const { url, imgTag, stringWithoutElements } = extractElements(title);
chapter.title = stringWithoutElements.trim();
if (imgTag != null) {
chapter.imageId = parseInt(imgTag);
if (chapter.imageId < 0 || chapter.imageId >= window.chapterImages.length) {
chapter.error = 'Invalid image id';
}
}
chapter.url = url;
} catch (e) {
chapter.error = 'Invalid time format';
chapter.start = -1;
Expand Down Expand Up @@ -80,7 +107,7 @@ export function displayChapterList() {
// Show time
if (chapter.start != -1) {
const a = document.createElement('span');
a.className = 'highlight';
a.className = 'timestamp';
a.textContent = secondsToString(chapter.start);
a.addEventListener('click', (e) => {
player.currentTime = chapter.start;
Expand All @@ -107,8 +134,25 @@ export function displayChapterList() {
url = url.substring(0, 35) + '...';
}
urlSpan.innerHTML = `${linkSVG}${url}`;
tippy(urlSpan, { content: chapter.url });
lineSpan.appendChild(urlSpan);
}
// Show image
if (chapter.imageId != undefined) {
const imageSpan = document.createElement('span');
imageSpan.className = 'image';
imageSpan.innerHTML = `${imageSVG}&lt;img-${chapter.imageId}&gt;`;
lineSpan.appendChild(imageSpan);
// tippy
const image = window.chapterImages[chapter.imageId];
const imageElement = document.createElement('img');
const blob = new Blob([image.imageBuffer], { type: image.mime });
const url = URL.createObjectURL(blob);
imageElement.src = url;
imageElement.loading = 'lazy';
imageElement.className = 'chapter-image-tooltip';
tippy(imageSpan, { content: imageElement, allowHTML: true });
}
// Show error
if (chapter.error) {
const errorSpan = document.createElement('span');
Expand All @@ -123,13 +167,6 @@ export function displayChapterList() {
warningSpan.innerHTML = `${chapter.warning}`; //${alertSVG}
lineSpan.appendChild(warningSpan);
}

// Add button
// const button = document.createElement('button');
// button.textContent = 'Add image';
// button.className = 'add-image';
// button.onclick = () => addImage(index);
// buttonContainer.appendChild(button);
}

const scrollTop = textInput.scrollTop;
Expand All @@ -148,11 +185,9 @@ export function setTextAreaContent() {
if (chapter.start === -1) {
return chapter.title;
} else {
if (chapter.url) {
return `${secondsToString(chapter.start)} ${chapter.title} ${chapter.url}`;
} else {
return `${secondsToString(chapter.start)} ${chapter.title}`;
}
const url = chapter.url ? ` ${chapter.url}` : '';
const image = chapter.imageId != undefined ? ` <img-${chapter.imageId}>` : '';
return `${secondsToString(chapter.start)} ${chapter.title}${url}${image}`;
}
});
textInput.value = lines.join('\n');
Expand Down
16 changes: 14 additions & 2 deletions src/FileExport.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function exportFileBasedOnOldTags(file, tags) {
console.log(tags);
import { encodeImage } from './ImageHandler.js';

async function exportFileBasedOnOldTags(file, tags) {
const chapterTag = [];
const tocTag = {
elementID: 'toc',
Expand All @@ -23,13 +23,21 @@ function exportFileBasedOnOldTags(file, tags) {
url: chapter.url,
}
}
if (chapter.hasOwnProperty('imageId')) {
try {
chapterObject.tags.image = await encodeImage(window.chapterImages[chapter.imageId]);
} catch (error) {
console.error('Error encoding image:', error);
}
}
chapterTag.push(chapterObject);
tocTag.elements.push(`chp${chapterIndex}`);
chapterIndex++;
}
}
tags.chapter = chapterTag;
tags.tableOfContents = tocTag;
// console.log("Exporting", chapterTag);

for (let field of window.fieldNames) {
const input = document.getElementById(`field-${field}`);
Expand All @@ -38,6 +46,10 @@ function exportFileBasedOnOldTags(file, tags) {
}
}

if (window.coverImage != null) {
tags.image = await encodeImage(window.coverImage);
}

// Call the addTags function from your bundle
addTags(tags, file, function (taggedBuffer) {
// Convert buffer to Blob
Expand Down
23 changes: 21 additions & 2 deletions src/FileLoader.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { buildGallery } from "./ImageHandler.js";

export function loadFile(file, wave, player) {
wave.loadBlob(file);
player.src = { src: file, type: 'audio/object' };
window.currentFilename = file.name;
window.currentFile = file;
window.chapters.duration = -1;
window.chapterImages = [];
wave.loadBlob(file);
player.src = { src: file, type: 'audio/object' };

let tags;
readTags(file, (fileTags) => {
tags = fileTags;
console.log(tags);
if (tags.hasOwnProperty('chapter')) {
const parsedChapters = [];
for (let chapter of tags.chapter) {
Expand All @@ -17,6 +22,10 @@ export function loadFile(file, wave, player) {
if (chapter.tags.hasOwnProperty('userDefinedUrl')) {
chapterObject.url = chapter.tags.userDefinedUrl[0].url;
}
if (chapter.tags.hasOwnProperty('image')) {
window.chapterImages.push(chapter.tags.image);
chapterObject.imageId = window.chapterImages.length - 1;
}
parsedChapters.push(chapterObject);
}
window.chapters.setChapters(parsedChapters);
Expand Down Expand Up @@ -44,6 +53,16 @@ export function loadFile(file, wave, player) {
input.dataset.oldValue = "";
}
}

if (tags.hasOwnProperty('image')) {
console.log(tags.image);
const img = document.getElementById('cover-image');
const blob = new Blob([tags.image.imageBuffer], { type: tags.image.mime });
const url = URL.createObjectURL(blob);
img.src = url;
}

buildGallery();
});

document.getElementById('filename').innerText = file.name;
Expand Down
Loading

0 comments on commit c9ce44c

Please sign in to comment.