mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +00:00
Add text components and styling
This commit is contained in:
parent
f9c5a688b1
commit
a95fcc96be
@ -7,22 +7,36 @@ import { Component } from "../../util/Component.js";
|
||||
export default class Flexer extends Component {
|
||||
static PROPERTIES = {
|
||||
children: {},
|
||||
gap: { value: '20pt' },
|
||||
}
|
||||
|
||||
static CSS = `
|
||||
:host > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
`;
|
||||
|
||||
create_template ({ template }) {
|
||||
// TODO: The way we handle loading assets doesn't work well
|
||||
// with web components, so for now it goes in the template.
|
||||
$(template).html(`
|
||||
<slot name="inside"></slot>
|
||||
<div><slot name="inside"></slot></div>
|
||||
`);
|
||||
}
|
||||
|
||||
on_ready () {
|
||||
on_ready ({ listen }) {
|
||||
console.log('Flexer on_ready called');
|
||||
for ( const child of this.get('children') ) {
|
||||
child.setAttribute('slot', 'inside');
|
||||
child.attach(this);
|
||||
}
|
||||
|
||||
listen('gap', gap => {
|
||||
console.log('gap called', gap);
|
||||
$(this.dom_).find('div').first().css('gap', gap);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
66
src/UI/Components/StepHeading.js
Normal file
66
src/UI/Components/StepHeading.js
Normal file
@ -0,0 +1,66 @@
|
||||
import { Component } from "../../util/Component.js";
|
||||
|
||||
/**
|
||||
* StepHeading renders a heading with a leading symbol.
|
||||
* The leading symbol is styled inside a cricle and is
|
||||
* optimized for single-digit numbers.
|
||||
*/
|
||||
export default class StepHeading extends Component {
|
||||
static PROPERTIES = {
|
||||
symbol: {
|
||||
description: 'The symbol to display',
|
||||
value: '1',
|
||||
},
|
||||
text: {
|
||||
description: 'The heading to display',
|
||||
value: 'Heading',
|
||||
},
|
||||
}
|
||||
|
||||
static CSS = /*css*/`
|
||||
.heading {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.circle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
background-color: #3e5362;
|
||||
color: #FFFFFF;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.text {
|
||||
margin-left: 20px;
|
||||
font-size: 30px;
|
||||
color: hsl(220, 25%, 31%);
|
||||
}
|
||||
`
|
||||
|
||||
create_template ({ template }) {
|
||||
$(template).html(/*html*/`
|
||||
<div class="heading">
|
||||
<div class="circle">
|
||||
${html_encode(this.get('symbol'))}
|
||||
</div>
|
||||
<div class="text">
|
||||
${html_encode(this.get('text'))}
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This is necessary because files can be loaded from
|
||||
// both `/src/UI` and `/UI` in the URL; we need to fix that
|
||||
if ( ! window.__component_stepHeading ) {
|
||||
window.__component_stepHeading = true;
|
||||
|
||||
customElements.define('c-step-heading', StepHeading);
|
||||
}
|
46
src/UI/Components/StringView.js
Normal file
46
src/UI/Components/StringView.js
Normal file
@ -0,0 +1,46 @@
|
||||
import { Component } from "../../util/Component.js";
|
||||
|
||||
/**
|
||||
* A simple component that displays a string in the
|
||||
* specified style.
|
||||
*/
|
||||
export default class StringView extends Component {
|
||||
static PROPERTIES = {
|
||||
text: { value: '' },
|
||||
heading: { value: 0 },
|
||||
}
|
||||
|
||||
static CSS = /*css*/`
|
||||
h2 {
|
||||
margin: 0;
|
||||
color: hsl(220, 25%, 31%);
|
||||
}
|
||||
`;
|
||||
|
||||
create_template ({ template }) {
|
||||
$(template).html(`<span></span>`);
|
||||
}
|
||||
|
||||
on_ready ({ listen }) {
|
||||
// TODO: listener composition, to avoid this
|
||||
const either = ({ heading, text }) => {
|
||||
console.log('---', { heading, text });
|
||||
const wrapper_nodeName = heading ? 'h' + heading : 'span';
|
||||
$(this.dom_).find('span').html(`<${wrapper_nodeName}>${html_encode(text)}</${wrapper_nodeName}>`);
|
||||
};
|
||||
listen('heading', heading => {
|
||||
either({ heading, text: this.get('text') });
|
||||
});
|
||||
listen('text', text => {
|
||||
either({ heading: this.get('heading'), text });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This is necessary because files can be loaded from
|
||||
// both `/src/UI` and `/UI` in the URL; we need to fix that
|
||||
if ( ! window.__component_stringView ) {
|
||||
window.__component_stringView = true;
|
||||
|
||||
customElements.define('c-string-view', StringView);
|
||||
}
|
@ -14,38 +14,10 @@ export default async function UIComponentWindow (options) {
|
||||
const placeholder = Placeholder();
|
||||
|
||||
await UIWindow({
|
||||
title: 'Instant Login!',
|
||||
app: 'instant-login',
|
||||
single_instance: true,
|
||||
icon: null,
|
||||
uid: null,
|
||||
is_dir: false,
|
||||
...options,
|
||||
|
||||
body_content: placeholder.html,
|
||||
has_head: false,
|
||||
selectable_body: false,
|
||||
allow_context_menu: false,
|
||||
is_resizable: false,
|
||||
is_droppable: false,
|
||||
init_center: true,
|
||||
allow_native_ctxmenu: false,
|
||||
allow_user_select: false,
|
||||
backdrop: true,
|
||||
width: 550,
|
||||
height: 'auto',
|
||||
dominant: true,
|
||||
show_in_taskbar: false,
|
||||
draggable_body: true,
|
||||
onAppend: function(this_window){
|
||||
},
|
||||
window_class: 'window-qr',
|
||||
body_css: {
|
||||
width: 'initial',
|
||||
height: '100%',
|
||||
'background-color': 'rgb(245 247 249)',
|
||||
'backdrop-filter': 'blur(3px)',
|
||||
padding: '20px',
|
||||
},
|
||||
})
|
||||
});
|
||||
|
||||
options.component.attach(placeholder);
|
||||
options.component.focus();
|
||||
|
@ -477,6 +477,9 @@ async function UIWindow(options) {
|
||||
const el_openfiledialog_open_btn = document.querySelector(`#window-${win_id} .openfiledialog-open-btn`);
|
||||
const el_directorypicker_select_btn = document.querySelector(`#window-${win_id} .directorypicker-select-btn`);
|
||||
|
||||
// attach optional event listeners
|
||||
el_window.on_before_exit = options.on_before_exit;
|
||||
|
||||
// disable menubar by default
|
||||
$(el_window).find('.window-menubar').hide();
|
||||
|
||||
@ -2813,6 +2816,12 @@ $.fn.close = async function(options) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log('deos ')
|
||||
if ( this.on_before_exit ) {
|
||||
console.log('this happens??');
|
||||
if ( ! await this.on_before_exit() ) return false;
|
||||
}
|
||||
|
||||
// Process window close if this is a window
|
||||
if($(this).hasClass('window')){
|
||||
const win_id = parseInt($(this).attr('data-id'));
|
||||
|
@ -23,8 +23,11 @@ import CodeEntryView from "./Components/CodeEntryView.js";
|
||||
import Flexer from "./Components/Flexer.js";
|
||||
import QRCodeView from "./Components/QRCode.js";
|
||||
import RecoveryCodesView from "./Components/RecoveryCodesView.js";
|
||||
import StepHeading from "./Components/StepHeading.js";
|
||||
import StepView from "./Components/StepView.js";
|
||||
import StringView from "./Components/StringView.js";
|
||||
import TestView from "./Components/TestView.js";
|
||||
import UIAlert from "./UIAlert.js";
|
||||
import UIComponentWindow from "./UIComponentWindow.js";
|
||||
|
||||
const UIWindow2FASetup = async function UIWindow2FASetup () {
|
||||
@ -63,9 +66,24 @@ const UIWindow2FASetup = async function UIWindow2FASetup () {
|
||||
children: [
|
||||
new Flexer({
|
||||
children: [
|
||||
new StepHeading({
|
||||
symbol: '1',
|
||||
text: 'Open Authenticator App',
|
||||
}),
|
||||
new StringView({
|
||||
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ornare augue eu est pharetra, non faucibus eros finibus. Morbi metus sapien, pretium consequat erat eu, accumsan imperdiet metus. Donec varius libero tellus, malesuada rhoncus nunc viverra eget. Quisque ultrices scelerisque ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non purus varius, molestie nibh vitae, elementum urna. Suspendisse ultricies porta gravida. Nulla eu consequat mi, id mattis leo.',
|
||||
}),
|
||||
new StepHeading({
|
||||
symbol: '2',
|
||||
text: 'Scan This QR Code',
|
||||
}),
|
||||
new QRCodeView({
|
||||
value: data.url,
|
||||
}),
|
||||
new StepHeading({
|
||||
symbol: '3',
|
||||
text: 'Enter Verification Code',
|
||||
}),
|
||||
new CodeEntryView({
|
||||
_ref: me => code_entry = me,
|
||||
async [`property.value`] (value, { component }) {
|
||||
@ -86,9 +104,20 @@ const UIWindow2FASetup = async function UIWindow2FASetup () {
|
||||
}),
|
||||
new Flexer({
|
||||
children: [
|
||||
new StepHeading({
|
||||
symbol: '4',
|
||||
text: 'Copy Recovery Codes',
|
||||
}),
|
||||
new StringView({
|
||||
text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ornare augue eu est pharetra, non faucibus eros finibus. Morbi metus sapien, pretium consequat erat eu, accumsan imperdiet metus. Donec varius libero tellus, malesuada rhoncus nunc viverra eget. Quisque ultrices scelerisque ante. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec non purus varius, molestie nibh vitae, elementum urna. Suspendisse ultricies porta gravida. Nulla eu consequat mi, id mattis leo.',
|
||||
}),
|
||||
new RecoveryCodesView({
|
||||
values: data.codes,
|
||||
}),
|
||||
new StepHeading({
|
||||
symbol: '5',
|
||||
text: 'Confirm Recovery Codes',
|
||||
}),
|
||||
]
|
||||
}),
|
||||
]
|
||||
@ -97,6 +126,55 @@ const UIWindow2FASetup = async function UIWindow2FASetup () {
|
||||
|
||||
UIComponentWindow({
|
||||
component,
|
||||
on_before_exit: async () => {
|
||||
console.log('this was called?');
|
||||
return await UIAlert({
|
||||
message: i18n('cancel_2fa_setup'),
|
||||
buttons: [
|
||||
{
|
||||
label: i18n('yes'),
|
||||
value: true,
|
||||
type: 'primary',
|
||||
},
|
||||
{
|
||||
label: i18n('no'),
|
||||
value: false,
|
||||
},
|
||||
]
|
||||
});
|
||||
},
|
||||
|
||||
title: 'Instant Login!',
|
||||
app: 'instant-login',
|
||||
single_instance: true,
|
||||
icon: null,
|
||||
uid: null,
|
||||
is_dir: false,
|
||||
// has_head: false,
|
||||
selectable_body: true,
|
||||
// selectable_body: false,
|
||||
allow_context_menu: false,
|
||||
is_resizable: false,
|
||||
is_droppable: false,
|
||||
init_center: true,
|
||||
allow_native_ctxmenu: false,
|
||||
allow_user_select: false,
|
||||
// backdrop: true,
|
||||
width: 550,
|
||||
height: 'auto',
|
||||
dominant: true,
|
||||
show_in_taskbar: false,
|
||||
draggable_body: true,
|
||||
onAppend: function(this_window){
|
||||
},
|
||||
window_class: 'window-qr',
|
||||
body_css: {
|
||||
width: 'initial',
|
||||
height: '100%',
|
||||
'background-color': 'rgb(245 247 249)',
|
||||
'backdrop-filter': 'blur(3px)',
|
||||
padding: '20px',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -39,6 +39,7 @@ import { BroadcastService } from './services/BroadcastService.js';
|
||||
import { ProcessService } from './services/ProcessService.js';
|
||||
import { PROCESS_RUNNING } from './definitions.js';
|
||||
import { LocaleService } from './services/LocaleService.js';
|
||||
import UIWindow2FASetup from './UI/UIWindow2FASetup.js';
|
||||
|
||||
const launch_services = async function () {
|
||||
const services_l_ = [];
|
||||
@ -66,6 +67,10 @@ const launch_services = async function () {
|
||||
const svc_process = globalThis.services.get('process');
|
||||
svc_process.get_init().chstatus(PROCESS_RUNNING);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
UIWindow2FASetup();
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
// This code snippet addresses the issue flagged by Lighthouse regarding the use of
|
||||
|
@ -4,6 +4,10 @@ export class Component extends HTMLElement {
|
||||
// Render modes
|
||||
static NO_SHADOW = Symbol('no-shadow');
|
||||
|
||||
static TODO = [
|
||||
'value bindings for create_template',
|
||||
]
|
||||
|
||||
constructor (property_values) {
|
||||
super();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user