Skip to content

Commit

Permalink
New UI and theme manager
Browse files Browse the repository at this point in the history
  • Loading branch information
Jared-Gross committed Dec 28, 2024
1 parent ab1ebb0 commit 837b7a9
Show file tree
Hide file tree
Showing 26 changed files with 1,359 additions and 3,481 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@ store_icon.png
settings.gradle
twa-manifest.json
gradle/
manifest-checksum.txt
manifest-checksum.txt
data/
compile_audio.py
generate.py
test.py
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"dependencies": {
"beercss": "^3.6.13",
"idb": "^8.0.1",
"remixicon": "^4.3.0"
},
"devDependencies": {
Expand Down Expand Up @@ -35,4 +36,4 @@
"url": "https://github.com/TheCodingJsoftware/Hutterite-Bookshelf/issues"
},
"homepage": "https://github.com/TheCodingJsoftware/Hutterite-Bookshelf#readme"
}
}
27 changes: 25 additions & 2 deletions src/baptismBooklet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
import 'beercss';
import 'material-dynamic-colors';
import 'remixicon/fonts/remixicon.css';
import '../static/css/style.css';
import '../static/css/theme.css';
import { loadTheme, loadAnimationStyleSheet } from "./utils/theme";

async function loadUIComponents() {
try {
const [themeDialogModule] = await Promise.all([
import("./dialogs/themeDialog"),
]);

const { SetThemeDialog } = themeDialogModule;

const setThemeDialog = new SetThemeDialog();
setThemeDialog.attachTo();
} catch (error) {
console.error("Error loading UI components:", error);
}
}

document.addEventListener("DOMContentLoaded", async () => {
loadTheme().then(() => {
setTimeout(() => {
loadAnimationStyleSheet();
}, 100);
}).catch(error => console.error('Failed to load theme:', error));
await loadUIComponents();
});
3 changes: 3 additions & 0 deletions src/books/alleluiaSing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class AlleluiaSing{

}
11 changes: 11 additions & 0 deletions src/dialogs/alleluiaSingDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BookTemplateDialog } from "./bookTemplateDialog";

export class AlleluiaSingDialog extends BookTemplateDialog {
constructor() {
super("Alleluia Sing");
}

public attachTo(parent: HTMLElement = document.body) {
parent.appendChild(this.dialog);
}
}
3 changes: 3 additions & 0 deletions src/dialogs/autoSize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface AutoSizeDialog {
adjustDialogForScreenSize(): void;
}
115 changes: 115 additions & 0 deletions src/dialogs/bookTemplateDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { AutoSizeDialog } from "./autoSize";
import { Overlay } from "./overlay";

export class BookTemplateDialog extends Overlay implements AutoSizeDialog {
title: string;
dialog: HTMLDialogElement;
searchInput: HTMLInputElement;
songList: HTMLDivElement;
closeButton: HTMLButtonElement;
clearSearchButton: HTMLButtonElement;

constructor(title: string) {
super();
super.attachTo();
this.title = title;
const template = document.createElement('template') as HTMLTemplateElement;
template.innerHTML = `
<dialog>
<h4 class="center-align">${title}</h4>
<div class="row">
<div class="field label prefix border small max">
<i>search</i>
<input type="search" type="text" id="search-input" spellcheck="false" autocapitalize="off" autocomplete="off" autofocusoff/>
<label>Search</label>
<span class="helper">Search using song titles or numbers</span>
</div>
<button class="transparent link circle" id="clear-search-button">
<i>close</i>
</button>
</div>
<div id="song-list">
</div>
<nav class="right-align">
<button class="transparent link small-round" id="close-dialog">
<span>Close</span>
</button>
</nav>
</dialog>
`.trim();

this.dialog = template.content.firstElementChild as HTMLDialogElement;
this.searchInput = this.dialog.querySelector("#search-input") as HTMLInputElement;
this.songList = this.dialog.querySelector("#song-list") as HTMLDivElement;
this.closeButton = this.dialog.querySelector("#close-dialog") as HTMLButtonElement;
this.clearSearchButton = this.dialog.querySelector("#clear-search-button") as HTMLButtonElement;
this.init();
}

init() {
let lastWidth = window.innerWidth;
this.adjustDialogForScreenSize();
window.addEventListener('resize', () => {
const currentWidth = window.innerWidth;
if (currentWidth !== lastWidth) {
this.adjustDialogForScreenSize();
lastWidth = currentWidth;
}
});
this.searchInput.addEventListener("input", () => {
const searchTerm = this.searchInput.value.toLowerCase();
this.addSearchToLocalStorage(searchTerm);
});
this.closeButton.onclick = () => this.close();
this.setSearchTermFromLocalStorage();

this.clearSearchButton.onclick = () => {
this.searchInput.value = "";
this.addSearchToLocalStorage("");
};
}

public addSearchToLocalStorage(searchTerm: string){
const key = `search-${this.title}`;
localStorage.setItem(key, searchTerm);
}

private setSearchTermFromLocalStorage() {
const key = `search-${this.title}`;
const searchTerm = localStorage.getItem(key);

if (searchTerm) {
this.searchInput.value = searchTerm;
}
}

private clearSearchFromLocalStorage() {
const key = `search-${this.title}`;
localStorage.removeItem(key);
}

public open(){
super.showOverlay();
this.dialog.show()
this.setSearchTermFromLocalStorage();
}

public close(){
super.hideOverlay();
this.dialog.close();
window.location.hash = "";
this.clearSearchFromLocalStorage();
}

public attachTo(parent: HTMLElement = document.body) {
parent.appendChild(this.dialog);
}

adjustDialogForScreenSize() {
if (window.innerWidth <= 600) {
this.dialog.classList.add('max');
} else {
this.dialog.classList.remove('max');
}
}
}
63 changes: 63 additions & 0 deletions src/dialogs/infoDialog.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { AutoSizeDialog } from "./autoSize";
import { Overlay } from "./overlay";

export class InfoDialog extends Overlay implements AutoSizeDialog {
private dialog: HTMLDialogElement;

constructor() {
super();
super.attachTo();
const template = document.createElement('template') as HTMLTemplateElement;
template.innerHTML = `
<dialog class="max" id="info-dialog">
<div class="row max center-align">
<img class="responsive circle border logo" style="max-width: 150px; height: auto;" fetchpriority="low" loading="lazy" src="/static/icons/icon.png" alt="" width="128" height="128">
</div>
<h5 class="small center-align">Hutterite Bookshelf <span class="small-text" id="app-version"></span></h5>
<br>
<p class="center-align no-line">A comprehensive app for accessing, managing, and sharing Hutterite literature.</p>
<br>
<p class="center-align">Developed with <button class="chip small-round circle no-border transparent no-margin"><i style="color: var(--error)">favorite</i><div class="tooltip top">love</div></button> by <a class="link" href="https://thecodingjsoftware.github.io/">TheCodingJ's</a></p>
<br>
<article class="border" style="margin-top: auto;">
<p class="center-align medium-width no-line">
For questions, comments, suggestions,
or concerns about this service please
email: <a class="link" href="mailto:jared@pinelandfarms.ca">jared@pinelandfarms.ca</a>.
</p>
</article>
<nav class="right-align no-space">
<button class="transparent link small-round" onclick="ui('#info-dialog')">Close</button>
</nav>
</dialog>
`.trim();

this.dialog = template.content.firstElementChild as HTMLDialogElement;

this.init();
}

init() {
let lastWidth = window.innerWidth;
this.adjustDialogForScreenSize();
window.addEventListener('resize', () => {
const currentWidth = window.innerWidth;
if (currentWidth !== lastWidth) {
this.adjustDialogForScreenSize();
lastWidth = currentWidth;
}
});
}

public attachTo(parent: HTMLElement = document.body) {
parent.appendChild(this.dialog);
}

adjustDialogForScreenSize() {
if (window.innerWidth <= 600) {
this.dialog.classList.add('max');
} else {
this.dialog.classList.remove('max');
}
}
}
28 changes: 28 additions & 0 deletions src/dialogs/overlay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export class Overlay {
private overlay: HTMLDivElement;

constructor() {
const template = document.createElement('template') as HTMLTemplateElement;
template.innerHTML = `
<div class="overlay blur"></div>
`.trim();

this.overlay = template.content.firstElementChild as HTMLDivElement;
this.overlay.addEventListener("click", () => {
this.hideOverlay();
window.location.hash = "";
});
}

public showOverlay() {
this.overlay.classList.add('active');
}

public hideOverlay() {
this.overlay.classList.remove('active');
}

public attachTo(parent: HTMLElement = document.body) {
parent.appendChild(this.overlay);
}
}
Loading

0 comments on commit 837b7a9

Please sign in to comment.