mirror of
https://github.com/HeyPuter/puter.git
synced 2026-04-28 19:20:55 -05:00
@@ -0,0 +1,39 @@
|
||||
const Component = use('util.Component');
|
||||
|
||||
export default def(class ActionCard extends Component {
|
||||
static ID = 'ui.component.ActionCard';
|
||||
static RENDER_MODE = Component.NO_SHADOW;
|
||||
|
||||
static PROPERTIES = {
|
||||
title: {
|
||||
value: 'Title'
|
||||
},
|
||||
info: {},
|
||||
button_text: {},
|
||||
button_style: {},
|
||||
on_click: {},
|
||||
style: {},
|
||||
}
|
||||
|
||||
create_template ({ template }) {
|
||||
$(template).html(/*html*/`
|
||||
<div class="settings-card ${ this.get('style') ? this.get('style') : '' }">
|
||||
<div>
|
||||
<strong style="display: block">${ this.get('title') }</strong>
|
||||
<span style="display: block margin-top: 5px">${
|
||||
this.get('info')
|
||||
}</span>
|
||||
</div>
|
||||
<div style="flex-grow: 1">
|
||||
<button class="button ${ this.get('button_style') }" style="float: right;">${
|
||||
this.get('button_text')
|
||||
}</button>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
on_ready ({ listen }) {
|
||||
$(this.dom_).find('button').on('click', this.get('on_click') || (() => {}));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
const Component = use('util.Component');
|
||||
|
||||
export default def(class Frame extends Component {
|
||||
static ID = 'ui.component.Frame';
|
||||
static RENDER_MODE = Component.NO_SHADOW;
|
||||
|
||||
static PROPERTIES = {
|
||||
component: {},
|
||||
}
|
||||
|
||||
on_ready ({ listen }) {
|
||||
listen('component', component => {
|
||||
this.dom_.innerHTML = '';
|
||||
if ( ! component ) {
|
||||
return;
|
||||
}
|
||||
component.attach(this.dom_);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Component } from "../../util/Component.js";
|
||||
|
||||
export default def(class Glyph extends Component {
|
||||
static ID = 'ui.component.Glyph';
|
||||
|
||||
static PROPERTIES = {
|
||||
size: {
|
||||
value: 24,
|
||||
},
|
||||
codepoint: {
|
||||
value: '✅',
|
||||
},
|
||||
}
|
||||
|
||||
static CSS = `
|
||||
div {
|
||||
text-align: center;
|
||||
}
|
||||
`;
|
||||
|
||||
create_template ({ template }) {
|
||||
template.innerHTML = /*html*/`
|
||||
<div style="font-size: ${this.get('size')}px;">
|
||||
${this.get('codepoint')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
@@ -15,4 +15,13 @@ export default def(class JustHTML extends Component {
|
||||
$(this.dom_).find('span').html(html);
|
||||
});
|
||||
}
|
||||
|
||||
_set_dom_based_on_render_mode({ property_values }) {
|
||||
if ( property_values.no_shadow ) {
|
||||
this.dom_ = this;
|
||||
return;
|
||||
}
|
||||
|
||||
return super._set_dom_based_on_render_mode();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
const Component = use('util.Component');
|
||||
|
||||
export default def(class NotifCard extends Component {
|
||||
static ID = 'ui.component.NotifCard';
|
||||
static RENDER_MODE = Component.NO_SHADOW;
|
||||
|
||||
static PROPERTIES = {
|
||||
text: { value: 'no text' },
|
||||
style: {},
|
||||
}
|
||||
|
||||
create_template ({ template }) {
|
||||
$(template).html(/*html*/`
|
||||
<div class="settings-card thin-card ${ this.get('style') ? this.get('style') : '' }">
|
||||
<div>
|
||||
${ this.get('text') }
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
||||
on_ready ({ listen }) {
|
||||
$(this.dom_).find('button').on('click', this.get('on_click') || (() => {}));
|
||||
}
|
||||
});
|
||||
@@ -3,15 +3,19 @@ const Component = use('util.Component');
|
||||
export default def(class Spinner extends Component {
|
||||
static ID = 'ui.component.Spinner';
|
||||
|
||||
static PROPERTIES = {}
|
||||
static PROPERTIES = {
|
||||
size: {
|
||||
value: 24,
|
||||
},
|
||||
}
|
||||
// static RENDER_MODE = Component.NO_SHADOW;
|
||||
|
||||
create_template ({ template }) {
|
||||
console.log('template?', template);
|
||||
const size = '' + Number(this.get('size'));
|
||||
|
||||
template.innerHTML = /*html*/`
|
||||
<div>
|
||||
<svg style="display:block; margin: 0 auto; " xmlns="http://www.w3.org/2000/svg" height="24" width="24" viewBox="0 0 24 24">
|
||||
<svg style="display:block; margin: 0 auto; " xmlns="http://www.w3.org/2000/svg" height="${size}" width="${size}" viewBox="0 0 24 24">
|
||||
<title>circle anim</title>
|
||||
<g fill="#212121" class="nc-icon-wrapper">
|
||||
<g class="nc-loop-circle-24-icon-f">
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import Placeholder from '../../util/Placeholder.js';
|
||||
import UIWindow from '../UIWindow.js'
|
||||
|
||||
async function UIWindowSettings(options){
|
||||
@@ -26,6 +27,7 @@ async function UIWindowSettings(options){
|
||||
const svc_settings = globalThis.services.get('settings');
|
||||
|
||||
const tabs = svc_settings.get_tabs();
|
||||
const tab_placeholders = [];
|
||||
|
||||
let h = '';
|
||||
|
||||
@@ -42,9 +44,14 @@ async function UIWindowSettings(options){
|
||||
h += `<div class="settings-content-container">`;
|
||||
|
||||
tabs.forEach((tab, i) => {
|
||||
h += `<div class="settings-content ${i === 0 ? 'active' : ''}" data-settings="${tab.id}">
|
||||
${tab.html()}
|
||||
</div>`;
|
||||
h += `<div class="settings-content ${i === 0 ? 'active' : ''}" data-settings="${tab.id}">`;
|
||||
if ( tab.factory ) {
|
||||
tab_placeholders[i] = Placeholder();
|
||||
h += tab_placeholders[i].html;
|
||||
} else {
|
||||
h += tab.html();
|
||||
}
|
||||
h += `</div>`;
|
||||
});
|
||||
|
||||
h += `</div>`;
|
||||
@@ -85,7 +92,13 @@ async function UIWindowSettings(options){
|
||||
}
|
||||
});
|
||||
const $el_window = $(el_window);
|
||||
tabs.forEach(tab => tab.init($el_window));
|
||||
tabs.forEach((tab, i) => {
|
||||
tab.init && tab.init($el_window);
|
||||
if ( tab.factory ) {
|
||||
const component = tab.factory();
|
||||
component.attach(tab_placeholders[i]);
|
||||
}
|
||||
});
|
||||
|
||||
$(el_window).on('click', '.settings-sidebar-item', function(){
|
||||
const $this = $(this);
|
||||
|
||||
@@ -3709,6 +3709,10 @@ fieldset[name=number-code] {
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.thin-card {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.settings-card strong {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@ logger.info('start -> async initialization');
|
||||
|
||||
import './util/TeePromise.js';
|
||||
import './util/Component.js';
|
||||
import './UI/Components/Frame.js';
|
||||
import './UI/Components/Glyph.js';
|
||||
import './UI/Components/ActionCard.js';
|
||||
import './UI/Components/NotifCard.js';
|
||||
|
||||
logger.info('end -> async initialization');
|
||||
globalThis.init_promise.resolve();
|
||||
|
||||
+2
-1
@@ -84,7 +84,8 @@ logger.info('start -> blocking initialization');
|
||||
}
|
||||
|
||||
if ( registry_.classes_m[id] ) {
|
||||
throw new Error(`Class with ID ${id} already registered`);
|
||||
// throw new Error(`Class with ID ${id} already registered`);
|
||||
return;
|
||||
}
|
||||
|
||||
registry_.classes_m[id] = cls;
|
||||
|
||||
+29
-3
@@ -34,14 +34,23 @@ export const Component = def(class Component extends HTMLElement {
|
||||
});
|
||||
}
|
||||
|
||||
constructor (property_values) {
|
||||
super();
|
||||
|
||||
_set_dom_based_on_render_mode () {
|
||||
if ( this.constructor.RENDER_MODE === Component.NO_SHADOW ) {
|
||||
this.dom_ = this;
|
||||
} else {
|
||||
this.dom_ = this.attachShadow({ mode: 'open' });
|
||||
}
|
||||
}
|
||||
|
||||
constructor (property_values) {
|
||||
super();
|
||||
|
||||
property_values = property_values || {};
|
||||
|
||||
// We allow a subclass of component to define custom behavior
|
||||
// for the `RENDER_MODE` static property. This is so JustHTML
|
||||
// can have ths `no_shadow: true` option.
|
||||
this._set_dom_based_on_render_mode({ property_values });
|
||||
|
||||
this.values_ = {};
|
||||
|
||||
@@ -104,6 +113,10 @@ export const Component = def(class Component extends HTMLElement {
|
||||
}
|
||||
|
||||
get (key) {
|
||||
if ( ! this.values_.hasOwnProperty(key) ) {
|
||||
throw new Error(`Unknown property \`${key}\` in ${
|
||||
this.constructor.ID || this.constructor.name}`);
|
||||
}
|
||||
return this.values_[key].get();
|
||||
}
|
||||
|
||||
@@ -130,6 +143,11 @@ export const Component = def(class Component extends HTMLElement {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( destination instanceof ShadowRoot ) {
|
||||
destination.appendChild(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( destination.$ === 'placeholder' ) {
|
||||
destination.replaceWith(this);
|
||||
return;
|
||||
@@ -162,6 +180,14 @@ export const Component = def(class Component extends HTMLElement {
|
||||
get_api_ () {
|
||||
return {
|
||||
listen: (name, callback) => {
|
||||
if ( Array.isArray(name) ) {
|
||||
const names = name;
|
||||
for ( const name of names ) {
|
||||
this.values_[name].sub((_, more) => {
|
||||
callback(this, { ...more, name });
|
||||
});
|
||||
}
|
||||
}
|
||||
this.values_[name].sub(callback);
|
||||
callback(this.values_[name].get(), {});
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*
|
||||
* @returns {PlaceholderReturn}
|
||||
*/
|
||||
const Placeholder = () => {
|
||||
const Placeholder = def(() => {
|
||||
const id = Placeholder.get_next_id_();
|
||||
return {
|
||||
$: 'placeholder',
|
||||
@@ -29,7 +29,7 @@ const Placeholder = () => {
|
||||
place.replaceWith(el);
|
||||
}
|
||||
};
|
||||
};
|
||||
}, 'util.Placeholder');
|
||||
|
||||
const anti_collision = `94d2cb6b85a1`; // Arbitrary random string
|
||||
Placeholder.next_id_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user