Skip to content

Commit

Permalink
Starter yeast for issue #49, a metadata editor
Browse files Browse the repository at this point in the history
  • Loading branch information
codedread committed Dec 27, 2021
1 parent 93d3429 commit 4055bba
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 11 deletions.
3 changes: 2 additions & 1 deletion code/kthoom.css
Original file line number Diff line number Diff line change
Expand Up @@ -499,9 499,10 @@ button:focus {
border: solid 1px grey;
border-radius: 5px;
color: grey;
padding: 0;
height: 2em;
width: 2em;
padding: 0;
vertical-align: bottom;
}

.metadataButton:hover {
Expand Down
17 changes: 15 additions & 2 deletions code/metadata/book-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 16,7 @@ const ComicBookMetadataType = {
* - Publisher, querySelector('Publisher').textContent
* - Year, querySelector('Year').textContent
*/

const COMICRACK_KEYS = ['Series', 'Volume', 'Number', 'Publisher', 'Year'];
const COMICRACK_KEYS = ['Series', 'Volume', 'Number', 'Publisher', 'Year'];

/**
* A lightweight class to encapsulate metadata of a book. This will
Expand All @@ -41,6 40,20 @@ export class BookMetadata {
this.optimizedForStreaming_ = optimizedForStreaming;
}

/** @returns {BookMetadata} */
clone() {
return new BookMetadata(this.bookType_, this.tags_, this.optimizedForStreaming_);
}

/** @returns {string[]} */
getAllowedPropertyKeys() {
if (this.bookType_ === ComicBookMetadataType.COMIC_RACK) {
return COMICRACK_KEYS;
}
return [];
}

/** @returns {boolean} */
isOptimizedForStreaming() { return this.optimizedForStreaming_; }

/** @returns {Array<Array<string>>} A list of key-value pairs, similar to Object.entries(). */
Expand Down
69 changes: 67 additions & 2 deletions code/metadata/metadata-editor.js
Original file line number Diff line number Diff line change
@@ -1,10 1,75 @@
import { Book } from '../book.js';
import { BookMetadata } from './book-metadata.js';
import { getElem } from '../common/helpers.js';

// TODO: Add an equals() method to metadata that compares key-value pairs.
// TODO: Attach event listeners when the text field contents changes to update metadata.
// TODO: Attach event listeners when the option key changes to update metadata.
// TODO: Style the form fields appropriately.
// TODO: Handle if two rows get the same key.
// TODO: Add a button to remove a row.
// TODO: Add a save button that becomes visible if the editorMetadata differs.
// TODO: When close is clicked and there have been changes, ask user if they want to abandon.
// TODO: If save is clicked, ask to get save handle access.
// TODO: When save handle is obtained, do a zip (optimized for streaming).
// TODO: Once zip is done, save to file system.

/**
*/
export class MetadataEditor {
constructor() {
/** @private {HTMLDivElement} */
/**
* @param {Book} book
*/
constructor(book) {
/**
* @private
* @type {Book}
*/
this.book_ = book;

/**
* This is the editor's copy of the metadata.
* @private
* @type {BookMetadata}
*/
this.editorMetadata_ = book.getMetadata().clone();

/**
* @private
* @type {HTMLDivElement}
*/
this.contentDiv_ = getElem('metadataTrayContents');

this.rerender_();
}

/** @private */
rerender_() {
const tableTemplate = getElem('metadataTable');
const metadataContents = document.importNode(tableTemplate.content, true);
const tableElem = metadataContents.querySelector('table.metadataTable');
for (const [key, value] of this.editorMetadata_.propertyEntries()) {
if (key && value) {
let keyCellContent = `<td>
<select id="property-select">
<option value="${key}">${key}</option>`;
for (const otherKey of this.editorMetadata_.getAllowedPropertyKeys()) {
if (key === otherKey) continue;
keyCellContent = `<option value="${otherKey}">${otherKey}</option>`;
}
keyCellContent = `</select>
</td>
<td>
<input id="property-value" type="text" value="${value}">
</td>`;

const rowElem = document.createElement('tr');
rowElem.innerHTML = keyCellContent;
tableElem.append(rowElem);
}
}

this.contentDiv_.innerHTML = '';
this.contentDiv_.appendChild(tableElem);
}
}
40 changes: 34 additions & 6 deletions code/metadata/metadata-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 9,41 @@ export class MetadataViewer {
*/
this.book_ = null;

/** @private {HTMLDivElement} */
/**
* @private
* @type {HTMLDivElement}
*/
this.contentDiv_ = getElem('metadataTrayContents');

/** @private {HTMLTemplateElement} */
/**
* @private
* @type {HTMLTemplateElement}
*/
this.tableTemplate_ = getElem('metadataTable');

/**
* @private
* @type {MetadataEditor}
*/
this.editor_ = null;

getElem('metadataViewerButton').addEventListener('click', () => this.toggleOpen());
getElem('metadataViewerOverlay').addEventListener('click', (e) => this.toggleOpen());
getElem('closeMetadataButton').addEventListener('click', () => this.doClose());
}

doClose() {
if (!this.isOpen()) {
return;
}

if (this.editor_) {
// TODO: Call editor_.close() or something.
this.editor_ = null;
this.rerender_();
} else {
this.toggleOpen();
}
}

/**
Expand All @@ -27,10 54,11 @@ export class MetadataViewer {
if (!this.isOpen()) {
return false;
}
const code = evt.keyCode;
if (code === Key.ESCAPE) {
this.toggleOpen();

switch (evt.keyCode) {
case Key.ESCAPE: this.doClose(); break;
}

return true;
}

Expand Down Expand Up @@ -85,7 113,7 @@ export class MetadataViewer {
// Dynamically load Metadata Editor when the edit button is clicked.
editButton.addEventListener('click', evt => {
import('./metadata-editor.js').then(module => {
const editor = new module.MetadataEditor();
this.editor_ = new module.MetadataEditor(this.book_);
});
});
}
Expand Down

0 comments on commit 4055bba

Please sign in to comment.