(function(){ let nextTooltipKey = 0; var tooltipData = {}; var tootlipVisible = false; var tooltipEl = LN.$(`
`); function findTooltipData(el){ let tooltip = null; while (!tooltip) { tooltip = tooltipData[el.dataset['tooltip']]; el = el.parentElement; } return tooltip; } function tooltipShow(ev,tooltip){ tooltipEl.innerText = tooltip.value; tooltipEl.setAttribute("VISIBLE",""); tootlipVisible = true; } function tooltipHide(ev,tooltip){ tooltipEl.removeAttribute("VISIBLE"); tootlipVisible = false; } function tooltipMouseOver(ev){ if (!document.body.contains(tooltipEl)){ document.body.appendChild(tooltipEl); LN.$idle(()=>{ tooltipMouseOver(ev);}); return; } let tooltip = findTooltipData(ev.target); if (!tooltip) console.log(ev); if (tooltipEl){ tooltipEl.style.left = `${ev.pageX+3}px`; tooltipEl.style.top = `${ev.pageY+3}px`; } if (tooltip.timeout) clearTimeout(tooltip.timeout); if (tootlipVisible){ tooltip.timeout = setTimeout(() => { tooltipHide(ev,tooltip); }, (tooltip.delay ? (tooltip.delay / 4) : 200)); } else { tooltip.timeout = setTimeout(() => { tooltipShow(ev,tooltip); }, tooltip.delay || 800); } } function tooltipMouseOut(ev){ let tooltip = findTooltipData(ev.target); if (tooltip.timeout) clearTimeout(tooltip.timeout); tooltipHide(ev,tooltip); } Vue.directive('tooltip',{ bind: function(el, binding, vnode){ let tooltip = { value: binding.value, timeout: null, delay: null, }; let tooltipKey = nextTooltipKey++; tooltipData[tooltipKey] = tooltip; el.dataset['tooltip'] = tooltipKey; el.addEventListener('mousemove',tooltipMouseOver); el.addEventListener('mouseout',tooltipMouseOut); }, update: function(el, binding, vnode, oldVnode){ let tooltip = findTooltipData(el); tooltip.value = binding.value; }, unbind: function(el, binding, vnode){ el.removeEventListener('mouseover',tooltipMouseOver); el.removeEventListener('mouseout',tooltipMouseOut); }, }); Vue.component('ln-statusbar',{ data: function(){ return { current: LN.Promise.getCurrentPromises(), }; }, computed: { CurrentPromises: function(){ return this.current; } }, template: `
{{ LNVue.$_.statusText }}
NOT LOGGED IN {{ LNVue.$_.identity.IdentityName }}
{{ LNVue.$_.socket && LNVue.$_.socket._state }}
{{ Object.keys(CurrentPromises).length || "No" }} Background Tasks
{{ promise.label }}
{{ LNVue.$_.Version() }}
`, }); Vue.component('ln-navitem',{ props: { value: { type: Object, required: true, }, key: String, }, template: `
{{ value.label || value.path }} {{ value.label }}
`, }); Vue.component('ln-navbar',{ props: { value: { type: Object, default: function(){ return LNVue.$_.navigation; } }, component: { type: [ Object, String ], default: 'ln-navitem', }, }, template: `
{{ item.label || item.path }}
` }); Vue.component('ln-textfield',{ props: { value: { type: String, required: true, }, }, template: ``, }); Vue.component('ln-password',{ props: { value: { type: String, required: true, }, }, template: ``, }); Vue.component('ln-textarea',{ props: { value: { type: String, required: true, }, }, template: ``, }); Vue.component('ln-number',{ model: { prop: "value", event: "input", }, props: { value: { required: false, type: Number, }, float: { type: Boolean, default: false, }, }, template: ` `, }); Vue.component('ln-slider',{ model: { prop: 'value', event: 'change', }, props: { value: { type: Number, default: 1, }, min: { type: Number, default: 0, }, max: { type: Number, default: 100, }, step: { type: Number, default: 1, }, islogarithmic: { type: Boolean, default: false, }, values: { default: null, } }, data: function(){ let d = { }; if (this.values instanceof Array){ this.min = 0; this.max = this.values.length - 1; this.step = 1; } else if (this.values instanceof Object){ this.min = 0; this.max = Object.keys(this.values).length - 1; this.step = 1; } else if (this.islogarithmic){ /* ToDo: Implement */ } else { } // console.log(`min=${this.min} max=${this.max} step=${this.step} value=${this.value}`); return d; }, computed: { keys: function(){ if (this.values instanceof Array) { let keys = new Array(this.values.length); for (let n=0;n {{ displayValue }} `, }); Vue.component("ln-file",{ props: { file: { type: Object, required: true, }, remove: { type: Function, required: false, } }, methods: { }, template: `
{{ file.name }} ({{ file.size }}bytes)
` }); Vue.component('ln-upload',{ model: { prop: "files", event: "change", }, props: { maxSize: { type: Number, default: 0, }, files: { type: Array, default: [], } }, data: function(){ return { maxSize: this.maxSize, files: this.files, }; }, methods: { drop: function(dropEvent){ dropEvent.preventDefault(); for (let n=0;nDateien hierher ziehen oder auswählen:

`, }); Vue.component('ln-select',{ model: { prop: "value", event: "change", }, props: { items: { required: true, }, value: { required: true, }, empty: { type: Boolean, default: true, }, }, computed: { prepared: { get: function(){ let prepared = {}; LN.$each(this.items,(element,index) => { prepared[index] = element; }); return prepared; }, }, }, methods: { changed: function(ev){ this.$emit("change", ev.target.value ); }, }, template: `
`, }); Vue.component('ln-identity',{ data: function(){ return { popupVisible: false, }; }, methods: { logout(){ LNVue.$_.authenticate("",null,"",""); this.popupVisible = false; }, popup(){ this.popupVisible = !this.popupVisible; }, }, template: `
{{ LNVue.$_.identity.IdentityName }}
Not logged in
`, }); Vue.component('ln-popup',{ props: { title: String, visible: { type: Boolean, default: false } }, methods: { show: function(){ this.visible = true; }, hide: function(){ this.visible = false; } }, template: `
{{ title }}
`, }); Vue.component('ln-login-pane',{ props: { }, methods: { stage1: function(){ console.log("login stage1", this.identityName); LNVue.$_ .requestChallenges(this.identityName) .then((challenges)=>{ challenges = challenges.message.Challenges; if (challenges.length > 0){ LNVue.$_.identity.IdentityName = this.identityName; LNVue.$_.identity.challenges = challenges; } }); }, logout(){ LNVue.$_.authenticate("",null,"",""); }, authenticateSeededPassword(challenge){ let encoder = new TextEncoder(); let seed = LNVue.decodeHex(challenge.AuthenticationParameters); let password = encoder.encode(challenge.prove); let secretSource = ArrayBuffer.combine(seed, password, seed); crypto.subtle.digest("SHA-256",secretSource) .then((secret)=>{ let challengebytes = LN.Base64.decode(challenge.Challenge); secret = new Uint8Array(secret); let proveSource = ArrayBuffer.combine(challengebytes, secret, challengebytes); crypto.subtle.digest("SHA-256",proveSource) .then((prove)=>{ prove = LN.Base64.encode(new Uint8Array(prove)); LNVue.$_.authenticate(this.identityName,challenge.SecureAttributeID,challenge.Challenge,prove); }); }); } }, data: ()=>{ return { identityName: "", }; }, template: `
Logged in as
{{ LNVue.$_.identity.IdentityName }}
{{ challenge.SecureAttributeLabel }}
`, }); })();