Release v1.0.0rc1
Some checks failed
CI / Checks (push) Has been cancelled

This commit is contained in:
2025-08-18 07:09:27 +02:00
commit d909391ee6
383 changed files with 22792 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,94 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
html {
background-color: var(--bs-tertiary-body-bg);
}
body, html {
height: 100vh;
}
body > .ui-viewport {
padding-bottom: 3.5rem;
padding-top: 3.5rem;
}
body.ui-js-enabled .ui-noscript-show {
display: none;
}
body:not(.ui-js-enabled) .ui-noscript-hide {
display: none;
}
#navbar .ui-navbar-brand > img {
border-radius: 0.25rem;
height: 1.5rem;
vertical-align: top;
}
.ui-save-card {
height: 100%;
}
.ui-save-card .card-footer .spinner-border {
display: none;
}
.ui-save-card .card-footer .spinner-border.htmx-request {
display: block;
}
.ui-actions-menu-trigger {
background-color: transparent;
border-color: transparent;
outline-color: transparent;
}
.ui-actions-menu-trigger::after {
display: none !important;
}
#button-bar .nav-link {
font-size: 2rem;
line-height: 1;
}
@media screen and (max-width: 767px) {
#button-bar .navbar-nav {
flex-direction: row;
}
}
@supports (-webkit-touch-callout: none) {
body, html {
height: -webkit-fill-available;
}
body {
overscroll-behavior: none;
}
}
body.ui-mode-standalone #button-bar {
padding-bottom: 1rem;
}
body.ui-mode-standalone #offcanvas-controls .offcanvas-body {
padding-bottom: 1.5rem;
}
.ui-messages:empty {
display: none;
}
.ui-uname {
font-size: 0.625rem;
}
#BrowseSavesView-Search .form-select {
min-width: 10rem;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,38 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket) => {
class HotPocketHTMXConfirmPlugin {
constructor (app) {
this.app = app;
}
onLoad = (event) => {
document.addEventListener('htmx:confirm', this.onHTMXConfirm);
};
onHTMXConfirm = (event) => {
if (!event.detail.question) {
return;
}
event.preventDefault();
const modal = this.app.plugin('UI.Modal')({
triggerElement: event.detail.elt,
confirm: true,
onHide: (action) => {
if (action === 'confirm') {
event.detail.issueRequest(true);
}
},
});
modal.show();
};
}
HotPocket.addPlugin('htmx.confirm', (app) => {
return new HotPocketHTMXConfirmPlugin(app);
});
})(window.HotPocket);

View File

@@ -0,0 +1,18 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket, htmx) => {
class HotPocketHTMXPlugin {
constructor (app) {
if (app.options.debug) {
htmx.logAll();
}
}
}
window.HotPocket.addPlugin('htmx', (app) => {
return new HotPocketHTMXPlugin(app);
});
})(window.HotPocket, window.htmx);

View File

@@ -0,0 +1,66 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved. (https://bthlabs.pl/)
* Licensed under BTHLabs Source Available License Agreement
*
* Because I'm too stubborn to use React, LOL
*/
(() => {
const DEFAULT_OPTIONS = {
debug: false,
};
class HotPocketApp {
constructor (options) {
this.plugins = [];
this.options = {
...DEFAULT_OPTIONS,
...options,
}
}
initPlugins = (plugins) => {
for (let pluginSpec of plugins) {
const [name, pluginFactory] = pluginSpec;
this.plugins.push([name, pluginFactory(this)]);
}
}
plugin = (name) => {
const pluginSpec = this.plugins.find((pluginSpec) => {
return pluginSpec[0] === name;
});
if (pluginSpec !== undefined) {
return pluginSpec[1];
}
return null;
}
onLoad = (event) => {
console.log('HotPocketApp.onLoad()', event);
for (let pluginSpec of this.plugins) {
if (pluginSpec[1].onLoad) {
pluginSpec[1].onLoad(event);
}
}
}
}
const plugins = [];
window.HotPocket = {
app: null,
addPlugin: (name, pluginFactory) => {
plugins.push([name, pluginFactory]);
},
run: (options) => {
if (window.HotPocket.app === null) {
window.HotPocket.app = new HotPocketApp(options);
window.HotPocket.app.initPlugins(plugins);
document.addEventListener('DOMContentLoaded', (event) => {
window.HotPocket.app.onLoad(event);
});
}
}
};
})();

View File

@@ -0,0 +1,33 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket, htmx) => {
class BrowseSavesView {
constructor (app) {
this.app = app;
}
onLoad = (event) => {
document.addEventListener('HotPocket:BrowseSavesView:updateLoadMoreButton', (event) => {
const button = document.querySelector('#BrowseSavesView .ui-load-more-button');
if (button) {
if (event.detail.next_url) {
button.setAttribute('hx-get', event.detail.next_url);
button.classList.remove('disable');
button.removeAttribute('disabled', true);
} else {
button.classList.add('disable');
button.setAttribute('disabled', true);
}
htmx.process('#BrowseSavesView .ui-load-more-button');
}
});
};
}
HotPocket.addPlugin('UI.BrowseSavesView', (app) => {
return new BrowseSavesView(app);
});
})(window.HotPocket, window.htmx);

View File

@@ -0,0 +1,28 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket) => {
class HotPocketUIFormPlugin {
constructor (app) {
}
onLoad (event) {
for (let cancelButton of document.querySelectorAll('.ui-form-cancel-button')) {
cancelButton.addEventListener('click', this.onCancelButtonClick);
}
}
onCancelButtonClick = (event) => {
event.stopPropagation();
event.preventDefault();
window.history.back();
return false;
};
}
HotPocket.addPlugin('UI.Form', (app) => {
return new HotPocketUIFormPlugin(app);
});
})(window.HotPocket);

View File

@@ -0,0 +1,52 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket, bootstrap) => {
const LEVEL_TO_BOOTSTRAP_CLASS = {
'debug': 'alert-secondary',
'info': 'alert-info',
'success': 'alert-success',
'warning': 'alert-warning',
'error': 'alert-danger',
};
class HotPocketUIMessagesPlugin {
constructor (app) {
this.containerElement = null;
this.templateElement = null;
}
onLoad = (event) => {
this.containerElement = document.querySelector('.ui-messages');
this.templateElement = document.querySelector('#Messages-Alert');
for (let element of this.containerElement.querySelectorAll('.alert')) {
element.classList.add('alert-dismissible');
element.classList.add('fade');
element.classList.add('show');
new bootstrap.Alert(element);
}
document.addEventListener('HotPocket:UI:Messages:addMessage', this.onAddMessage);
};
onAddMessage = (event) => {
const alertContentElement = this.templateElement.content.cloneNode(true);
const alertElement = alertContentElement.querySelector('.alert');
alertElement.classList.add(LEVEL_TO_BOOTSTRAP_CLASS[event.detail.level] || 'alert-secondary');
if (event.detail.extra_tags) {
alertElement.classList.add(event.detail.extra_tags);
}
alertElement.querySelector('.ui-alert-message').innerHTML = event.detail.message;
new bootstrap.Alert(alertElement);
this.containerElement.appendChild(alertContentElement);
};
}
HotPocket.addPlugin('UI.Messages', (app) => {
return new HotPocketUIMessagesPlugin(app);
});
})(window.HotPocket, window.bootstrap);

View File

@@ -0,0 +1,78 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket, bootstrap) => {
const DEFAULT_OPTIONS = {
triggerElement: null,
confirm: false,
onHide: () => {},
};
class HotPocketModal {
constructor (app, options) {
this.app = app;
this.options = {
...DEFAULT_OPTIONS,
...options,
};
this.action = 'dismiss';
this.triggerElement = this.options.triggerElement;
if (options.confirm === false) {
this.triggerElement.addEventListener('click', this.onTriggerElementClick);
}
this.templateElement = document.querySelector(
this.triggerElement.dataset.uiModal,
);
this.modalElement = null;
this.modal = null;
this.triggerElement.HotPocketModal = this;
}
show = () => {
this.modalElement = this.templateElement.content.cloneNode(true).querySelector('.modal');
this.modalElement.querySelector('[data-ui-modal-action]').addEventListener(
'click', this.onActionClick,
);
this.modalElement.addEventListener('hidden.bs.modal', this.onModalHidden);
this.modal = new bootstrap.Modal(this.modalElement);
document.body.appendChild(this.modalElement);
this.modal.show();
};
onTriggerElementClick = (event) => {
event.preventDefault();
this.show();
return false;
};
onActionClick = (event) => {
this.action = event.target.dataset['uiModalAction'];
this.modal.hide();
};
onModalHidden = (event) => {
document.body.removeChild(this.modalElement);
this.modal = null;
this.modalElement = null;
this.options.onHide(this.action);
};
};
HotPocket.addPlugin('UI.Modal', (app) => {
return (options) => {
return new HotPocketModal(app, options);
};
});
})(window.HotPocket, window.bootstrap);

View File

@@ -0,0 +1,66 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket) => {
class ViewAssociationView {
constructor (app) {
this.app = app;
this.onWindowResizeTimeout = null;
}
clearOnWindowResizeTimeout () {
if (this.onWindowResizeTimeout) {
window.clearTimeout(this.onWindowResizeTimeout);
this.onWindowResizeTimeout = null;
}
}
onLoad = (event) => {
document.addEventListener('HotPocket:ViewAssociationView:loadEmbed', this.onWindowResize);
window.addEventListener('resize', (event) => {
this.clearOnWindowResizeTimeout();
this.onWindowResizeTimeout = window.setTimeout(
this.onWindowResize, 300,
);
});
this.onWindowResize();
for (let shareButton of document.querySelectorAll('#ViewAssociationView .ui-share-button')) {
if (navigator.share) {
shareButton.addEventListener('click', this.onShareButtonClick);
} else {
shareButton.addClass('d-none');
}
}
};
onWindowResize = (event) => {
const widthReference = document.querySelector('#ViewAssociationView .ui-width-reference');
const youtubeIFrame = document.querySelector('#ViewAssociationView .ui-youtube-iframe');
if (youtubeIFrame) {
const width = widthReference.offsetWidth - 8;
const height = Math.ceil(width / 1.6);
youtubeIFrame.setAttribute('width', width);
youtubeIFrame.setAttribute('height', height);
}
};
onShareButtonClick = (event) => {
event.preventDefault();
const shareUrl = new URL(window.location.href);
shareUrl.searchParams.set('share', 'true');
navigator.share({
title: document.title,
url: shareUrl.toString(),
});
return false;
};
}
HotPocket.addPlugin('UI.ViewAssociationView', (app) => {
return new ViewAssociationView(app);
});
})(window.HotPocket);

View File

@@ -0,0 +1,22 @@
/*!
* HotPocket by BTHLabs (https://hotpocket.app/)
* Copyright 2025-present by BTHLabs. All rights reserved.
* Licensed under BTHLabs Source Available License Agreement
*/
((HotPocket) => {
class HotPocketUIPlugin {
constructor (app) {
document.body.classList.add('ui-js-enabled');
if (window.navigator.standalone === true) {
document.querySelector('body').classList.add('ui-mode-standalone');
} else {
document.querySelector('body').classList.remove('ui-mode-standalone');
}
}
}
HotPocket.addPlugin('UI', (app) => {
return new HotPocketUIPlugin(app);
});
})(window.HotPocket);

File diff suppressed because one or more lines are too long