Updated to work with live site
Added components from somewhere fixed some css background image
This commit is contained in:
		| @@ -13,8 +13,7 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "compression": "^1.7.4", | ||||
|     "polka": "next", | ||||
|     "sirv": "^1.0.6" | ||||
|     "polka": "next" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "npm-run-all": "^4.1.5", | ||||
| @@ -31,6 +30,7 @@ | ||||
|     "@rollup/plugin-replace": "^2.3.3", | ||||
|     "rollup": "^2.26.4", | ||||
|     "rollup-plugin-svelte": "^5.2.3", | ||||
|     "rollup-plugin-terser": "^7.0.0" | ||||
|     "rollup-plugin-terser": "^7.0.0", | ||||
|     "sirv": "^1.0.6" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										94
									
								
								src/components/Barcode.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/components/Barcode.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| <script> | ||||
|     import {onMount, tick, beforeUpdate} from 'svelte' ; | ||||
|  | ||||
|     let barcodeReady = false; | ||||
|     let mounted = false; | ||||
|  | ||||
|     onMount(() => { | ||||
|         // The payment-form is ready. | ||||
|         mounted = true; | ||||
|         //if (barcodeReady) { | ||||
|         loadBarcodeElements(); | ||||
|         //} | ||||
|     }); | ||||
|  | ||||
|     //export const  | ||||
|  | ||||
|     const target = (bc) => bc.length < 9 ? 7 : 12; | ||||
|  | ||||
|     let error; | ||||
|  | ||||
|     $: format = barcode.length < 9 ? "EAN8" : "EAN13"; | ||||
|  | ||||
|  | ||||
|     function padBarcode(bc, length, pad = 0) { | ||||
|         return bc; | ||||
|         while (bc.length < length) { | ||||
|             bc = pad + bc.toString(); | ||||
|         } | ||||
|  | ||||
|         return bc; | ||||
|     } | ||||
|  | ||||
|     const loadBarcodeElements = () => { | ||||
|         clearCanvas(document.getElementById("barcode").getContext("2d")); | ||||
|         error = null; | ||||
|         if (barcode != null && barcode.length > 0) { | ||||
|             //bwipjs.toCanvas("barcode", {bcid:format, text: padBarcode(barcode, target(barcode))}); | ||||
|             try { | ||||
|  | ||||
|                 const x = JsBarcode("#barcode", padBarcode(barcode, target(barcode)), {format: format}); | ||||
|                 console.log(x); | ||||
|             } catch { | ||||
|                 error = "Invalid barcode" | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     export let barcode = ""; | ||||
|  | ||||
|     beforeUpdate(async () => { | ||||
|         if (mounted) { | ||||
|             loadBarcodeElements(); | ||||
|         } | ||||
|         await tick(); | ||||
|     }); | ||||
|  | ||||
|     export const appendCheckDigit = () => { | ||||
|         if (barcode.length === 7 || barcode.length === 12) { | ||||
|             const check = eanCheckDigit(barcode); | ||||
|             //if (barcode[barcode.length-1] !== check) | ||||
|             //{ | ||||
|             barcode += check; | ||||
|             //} | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     function clearCanvas(context, canvas = context.canvas) { | ||||
|         context.clearRect(0, 0, canvas.width, canvas.height); | ||||
|         const w = canvas.width; | ||||
|         canvas.width = 1; | ||||
|         canvas.width = w; | ||||
|     } | ||||
|  | ||||
|     // definitely a hack. | ||||
|     export const eanCheckDigit = (s) => { | ||||
|         let x = JsBarcode("#barcode", s, {format: format}); | ||||
|  | ||||
|         //EAN barcodes by default have 5 parts (prefix -> left part -> middle seperator -> right part -> suffix) | ||||
|         // we only want left & right part (which contain a text | ||||
|         let calculated = ""; | ||||
|         x._encodings[0].filter(e => e.text !== "").forEach(e => calculated += e.text); | ||||
|         console.log(calculated); | ||||
|         return calculated[calculated.length - 1]; | ||||
|     } | ||||
|  | ||||
| </script> | ||||
|  | ||||
|  | ||||
| <canvas id="barcode" width="50%" height="100%"></canvas> | ||||
| {#if error} | ||||
|     <p>Error: {error}</p> | ||||
| {/if} | ||||
|  | ||||
							
								
								
									
										36
									
								
								src/components/Link.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/components/Link.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| <script> | ||||
|     import {getContext} from 'svelte'; | ||||
|     import {writable} from 'svelte/store'; | ||||
|  | ||||
|     const navigate = getContext('navigate'); | ||||
|     const navaid = getContext('navaid'); | ||||
|  | ||||
|     const base = navaid && navaid.base || writable('/'); | ||||
|     const library = navaid && navaid.library || writable(null); | ||||
|     let props; | ||||
|     let href; | ||||
|  | ||||
|     export let append; | ||||
|  | ||||
|     $: { | ||||
|         props = {...$$props}; | ||||
|         href = props.href; | ||||
|         delete props.href; | ||||
|         href = ($library && $library.prefix ? $library.prefix : '') + (!append ? $base : '') + href.replace(/^\//, ''); | ||||
|     } | ||||
|  | ||||
|     const click = () => { | ||||
|         navigate(href); | ||||
|     } | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
|     span { | ||||
|         text-decoration: none; | ||||
|         padding: 1rem 0.5rem; | ||||
|         display: block; | ||||
|         color: #005de6; | ||||
|     } | ||||
| </style> | ||||
|  | ||||
| <span {...props} on:click={click}><slot></slot></span> | ||||
							
								
								
									
										249
									
								
								src/components/Modal.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								src/components/Modal.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| <script> | ||||
|     import {setContext as baseSetContext, createEventDispatcher} from 'svelte'; | ||||
|     import {fade} from 'svelte/transition'; | ||||
|  | ||||
|     export let key = 'simple-modal'; | ||||
|     export let closeButton = true; | ||||
|     export let closeOnEsc = true; | ||||
|     export let closeOnOuterClick = true; | ||||
|     export let transitionBg = fade; | ||||
|     export let transitionBgProps = {duration: 250}; | ||||
|     export let transitionWindow = transitionBg; | ||||
|     export let transitionWindowProps = transitionBgProps; | ||||
|     export let styleBg = {top: 0, left: 0}; | ||||
|     export let styleWindow = {}; | ||||
|     export let styleContent = {}; | ||||
|     export let setContext = baseSetContext; | ||||
|  | ||||
|     let Component = null; | ||||
|     let props = null; | ||||
|  | ||||
|     let background; | ||||
|     let wrap; | ||||
|     let customStyleBg = {}; | ||||
|     let customStyleWindow = {}; | ||||
|     let customStyleContent = {}; | ||||
|  | ||||
|     let Callback = (props) => { | ||||
|     }; | ||||
|  | ||||
|     const dispatch = createEventDispatcher(); | ||||
|  | ||||
|     const camelCaseToDash = str => str | ||||
|         .replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase(); | ||||
|  | ||||
|     const toCssString = (props) => Object.keys(props) | ||||
|         .reduce((str, key) => `${str}; ${camelCaseToDash(key)}: ${props[key]}`, ''); | ||||
|  | ||||
|     $: cssBg = toCssString(Object.assign({}, styleBg, customStyleBg)); | ||||
|     $: cssWindow = toCssString(Object.assign({}, styleWindow, customStyleWindow)); | ||||
|     $: cssContent = toCssString(Object.assign({}, styleContent, customStyleContent)); | ||||
|  | ||||
|     const open = (NewComponent, newProps = {}, style = {bg: {}, window: {}, content: {}}, newCallback = () => { | ||||
|     }) => { | ||||
|         Component = NewComponent; | ||||
|         props = newProps; | ||||
|         Callback = newCallback; | ||||
|         customStyleBg = style.bg || {}; | ||||
|         customStyleWindow = style.window || {}; | ||||
|         customStyleContent = style.content || {}; | ||||
|     }; | ||||
|  | ||||
|     const close = () => { | ||||
|         Callback(props); | ||||
|         Component = null; | ||||
|         props = null; | ||||
|         customStyleBg = {}; | ||||
|         customStyleWindow = {}; | ||||
|         customStyleContent = {}; | ||||
|     }; | ||||
|  | ||||
|     const handleKeyup = ({key}) => { | ||||
|         if (closeOnEsc && Component && key === 'Escape') { | ||||
|             event.preventDefault(); | ||||
|             close(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     const handleOuterClick = (event) => { | ||||
|         if ( | ||||
|             closeOnOuterClick && ( | ||||
|                 event.target === background || event.target === wrap | ||||
|             ) | ||||
|         ) { | ||||
|             event.preventDefault(); | ||||
|             close(); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     setContext(key, {open, close}); | ||||
| </script> | ||||
|  | ||||
| <!-- | ||||
|  | ||||
| ** LICENSE ** | ||||
|  | ||||
| MIT License | ||||
|  | ||||
| Copyright (c) 2019 Fritz Lekschas | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
| of this software and associated documentation files (the "Software"), to deal | ||||
| in the Software without restriction, including without limitation the rights | ||||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
| copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all | ||||
| copies or substantial portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| SOFTWARE. | ||||
|  | ||||
| https://github.com/flekschas/svelte-simple-moda | ||||
| --> | ||||
|  | ||||
| <style> | ||||
|     * { | ||||
|         box-sizing: border-box; | ||||
|     } | ||||
|  | ||||
|     .bg { | ||||
|         position: fixed; | ||||
|         z-index: 1000; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: center; | ||||
|         width: 100vw; | ||||
|         height: 100vh; | ||||
|         background: rgba(0, 0, 0, 0.66); | ||||
|     } | ||||
|  | ||||
|     .window-wrap { | ||||
|         position: relative; | ||||
|         margin: 2rem; | ||||
|         max-height: 100%; | ||||
|     } | ||||
|  | ||||
|     .window { | ||||
|         position: relative; | ||||
|         width: 40rem; | ||||
|         max-width: 100%; | ||||
|         max-height: 100%; | ||||
|         margin: 2rem auto; | ||||
|         color: black; | ||||
|         border-radius: 0.5rem; | ||||
|         background: white; | ||||
|     } | ||||
|  | ||||
|     .content { | ||||
|         position: relative; | ||||
|         padding: 1rem; | ||||
|         max-height: calc(100vh - 4rem); | ||||
|         overflow: auto; | ||||
|     } | ||||
|  | ||||
|     .close { | ||||
|         display: block; | ||||
|         box-sizing: border-box; | ||||
|         position: absolute; | ||||
|         z-index: 1000; | ||||
|         top: 1rem; | ||||
|         right: 1rem; | ||||
|         margin: 0; | ||||
|         padding: 0; | ||||
|         width: 1.5rem; | ||||
|         height: 1.5rem; | ||||
|         border: 0; | ||||
|         color: black; | ||||
|         border-radius: 1.5rem; | ||||
|         background: white; | ||||
|         box-shadow: 0 0 0 1px black; | ||||
|         transition: transform 0.2s cubic-bezier(0.25, 0.1, 0.25, 1), | ||||
|         background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); | ||||
|         -webkit-appearance: none; | ||||
|     } | ||||
|  | ||||
|     .close:before, .close:after { | ||||
|         content: ''; | ||||
|         display: block; | ||||
|         box-sizing: border-box; | ||||
|         position: absolute; | ||||
|         top: 50%; | ||||
|         width: 1rem; | ||||
|         height: 1px; | ||||
|         background: black; | ||||
|         transform-origin: center; | ||||
|         transition: height 0.2s cubic-bezier(0.25, 0.1, 0.25, 1), | ||||
|         background 0.2s cubic-bezier(0.25, 0.1, 0.25, 1); | ||||
|     } | ||||
|  | ||||
|     .close:before { | ||||
|         -webkit-transform: translate(0, -50%) rotate(45deg); | ||||
|         -moz-transform: translate(0, -50%) rotate(45deg); | ||||
|         transform: translate(0, -50%) rotate(45deg); | ||||
|         left: 0.25rem; | ||||
|     } | ||||
|  | ||||
|     .close:after { | ||||
|         -webkit-transform: translate(0, -50%) rotate(-45deg); | ||||
|         -moz-transform: translate(0, -50%) rotate(-45deg); | ||||
|         transform: translate(0, -50%) rotate(-45deg); | ||||
|         left: 0.25rem; | ||||
|     } | ||||
|  | ||||
|     .close:hover { | ||||
|         background: black; | ||||
|     } | ||||
|  | ||||
|     .close:hover:before, .close:hover:after { | ||||
|         height: 2px; | ||||
|         background: white; | ||||
|     } | ||||
|  | ||||
|     .close:focus { | ||||
|         border-color: #3399ff; | ||||
|         box-shadow: 0 0 0 2px #3399ff; | ||||
|     } | ||||
|  | ||||
|     .close:active { | ||||
|         transform: scale(0.9); | ||||
|     } | ||||
|  | ||||
|     .close:hover, .close:focus, .close:active { | ||||
|         outline: none; | ||||
|     } | ||||
| </style> | ||||
|  | ||||
| <svelte:window on:keyup={handleKeyup}/> | ||||
|  | ||||
| <div> | ||||
|     {#if Component} | ||||
|         <div | ||||
|                 class="bg" | ||||
|                 on:click={handleOuterClick} | ||||
|                 bind:this={background} | ||||
|                 transition:transitionBg={transitionBgProps} | ||||
|                 style={cssBg}> | ||||
|             <div class="window-wrap" bind:this={wrap}> | ||||
|                 <div | ||||
|                         class="window" | ||||
|                         transition:transitionWindow={transitionWindowProps} | ||||
|                         style={cssWindow}> | ||||
|                     {#if closeButton} | ||||
|                         <button on:click={close} class="close"></button> | ||||
|                     {/if} | ||||
|                     <div class="content" style={cssContent}> | ||||
|                         <Component {...props} {close}/> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     {/if} | ||||
|     <slot></slot> | ||||
| </div> | ||||
							
								
								
									
										56
									
								
								src/components/Sidebar.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/components/Sidebar.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| {#if show} | ||||
|     <div class="overlay" data-close on:click={overlay_click}> | ||||
|         <nav transition:fly={{x: -250, opacity: 1}}> | ||||
|             <slot> | ||||
|                 <button on:click={click}>About</button> | ||||
|             </slot> | ||||
|         </nav> | ||||
|     </div> | ||||
| {/if} | ||||
|  | ||||
| <Modal bind:show={modal_show}/> | ||||
|  | ||||
| <script> | ||||
|     import {fly} from 'svelte/transition'; | ||||
|     import Modal from './Modal.svelte'; | ||||
|  | ||||
|     const click = () => { | ||||
|         modal_show = true; | ||||
|         show = false; | ||||
|     }; | ||||
|  | ||||
|     function overlay_click(e) { | ||||
|         if ('close' in e.target.dataset) | ||||
|             show = false; | ||||
|     } | ||||
|  | ||||
|     export let show = false; | ||||
|     let modal_show = false; | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
|     .overlay { | ||||
|         position: fixed; | ||||
|         top: 0; | ||||
|         left: 0; | ||||
|         right: 0; | ||||
|         bottom: 0; | ||||
|         background: rgba(0, 0, 0, 0); | ||||
|         z-index: 10; | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|         justify-content: center; | ||||
|     } | ||||
|  | ||||
|     nav { | ||||
|         position: fixed; | ||||
|         top: 0; | ||||
|         left: 0; | ||||
|         height: 100%; | ||||
|         padding: 2rem 1rem 0.6rem; | ||||
|         border-right: 1px solid #aaa; | ||||
|         background: #fff; | ||||
|         overflow-y: auto; | ||||
|         width: 20rem; | ||||
|     } | ||||
| </style> | ||||
							
								
								
									
										249
									
								
								src/components/SortableList.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								src/components/SortableList.svelte
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,249 @@ | ||||
| <script> | ||||
|  | ||||
|     import {quintOut} from "svelte/easing"; | ||||
|     import {crossfade} from "svelte/transition"; | ||||
|     import {flip} from "svelte/animate"; | ||||
|     // FLIP ANIMATION | ||||
|     const [send, receive] = crossfade({ | ||||
|         duration: d => Math.sqrt(d * 200), | ||||
|         fallback(node, params) { | ||||
|             const style = getComputedStyle(node); | ||||
|             const transform = style.transform === "none" ? "" : style.transform; | ||||
|             return { | ||||
|                 duration: 600, | ||||
|                 easing: quintOut, | ||||
|                 css: t => ` | ||||
| 					transform: ${transform} scale(${t}); | ||||
| 					opacity: ${t} | ||||
| 				` | ||||
|             }; | ||||
|         } | ||||
|     }); | ||||
|     // DRAG AND DROP | ||||
|     let isOver = false; | ||||
|     let isDragging = false; | ||||
|     const getDraggedParent = (node) => { | ||||
|         return node.dataset && node.dataset.index | ||||
|             ? node.dataset | ||||
|             : getDraggedParent(node.parentNode) | ||||
|     }; | ||||
|     const click = ev => { | ||||
|         dispatch("slotclick", { | ||||
|             source: ev.target.parentElement.dataset.index, | ||||
|             sourceItem: list[ev.target.parentElement.dataset.index] | ||||
|         }); | ||||
|     }; | ||||
|     const start = ev => { | ||||
|         isDragging = true; | ||||
|         ev.dataTransfer.setData("source", ev.target.dataset.index); | ||||
|     }; | ||||
|     const over = ev => { | ||||
|         ev.preventDefault(); | ||||
|         let dragged = getDraggedParent(ev.target); | ||||
|         if (isOver !== dragged.id) isOver = JSON.parse(dragged.id); | ||||
|     }; | ||||
|     const leave = ev => { | ||||
|         let dragged = getDraggedParent(ev.target); | ||||
|         if (isOver === dragged.id) isOver = false; | ||||
|     }; | ||||
|     const drop = ev => { | ||||
|         isOver = false; | ||||
|         ev.preventDefault(); | ||||
|         let dragged = getDraggedParent(ev.target); | ||||
|         let from = ev.dataTransfer.getData("source"); | ||||
|         let to = dragged.index; | ||||
|         reorder({from, to}); | ||||
|         isDragging = false; | ||||
|     }; | ||||
|     // DISPATCH REORDER | ||||
|     import {createEventDispatcher, onMount, afterUpdate, beforeUpdate, tick} from "svelte"; | ||||
|  | ||||
|     const dispatch = createEventDispatcher(); | ||||
|     const reorder = ({from, to}) => { | ||||
|         let newList = [...list]; | ||||
|         let temp = newList[from]; | ||||
|         newList[from] = newList[to]; | ||||
|         newList[to] = temp; | ||||
|         //newList[from] = [newList[to], (newList[to] = newList[from])][0]; | ||||
|         dispatch("sort", {data: newList, from: from, to: to}); | ||||
|     }; | ||||
|     // UTILS | ||||
|     const getKey = item => (key ? item[key] : item); | ||||
|     // PROPS | ||||
|     export let list; | ||||
|     export let key; | ||||
|     export let ulclass; | ||||
|  | ||||
|     export let breakon; | ||||
|  | ||||
|     export let breakComponent; | ||||
|     //    return `<><li class='${breakClass}' style='height:100%; grid-column: span 5;'><div style='width:100%;height:inherit;'></li>`; | ||||
|  | ||||
|     // export let breakPosition = "beforebegin"; | ||||
|     let breakClass = "group-break"; | ||||
|  | ||||
|     const Elements = () => document.getElementsByClassName(key); | ||||
|  | ||||
|     const removeOldBreaks = (parent) => { | ||||
|         if (breakon == null) return; | ||||
|         if (isDragging) return; | ||||
|  | ||||
|         if (parent.length) { | ||||
|             const old = parent[0].getElementsByClassName(breakClass); | ||||
|  | ||||
|             for (let i = 0; i < old.length; i = 0) { | ||||
|                 old[i].remove(); // removing the node from the DOM also removes it from this array (WTF??) | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     let lastCollection; | ||||
|  | ||||
|     let updatingBreakPoints = false; | ||||
|  | ||||
|     const updateBreak = () => { | ||||
|         if (isDragging || updatingBreakPoints) return; | ||||
|         if (breakon == null) return; | ||||
|  | ||||
|         try { | ||||
|             updatingBreakPoints = true; | ||||
|  | ||||
|             let breaks = 0; | ||||
|             let last = null; | ||||
|             let carry = 0; | ||||
|             let elements = Elements(); | ||||
|  | ||||
|  | ||||
|             for (let x = 0; x < list.length; x++) { | ||||
|  | ||||
|                 if (last != null) { | ||||
|                     if (list[x][breakon] > last) { | ||||
|  | ||||
|                         if (elements.length) { | ||||
|                             let targetIndex = x + breaks; | ||||
|  | ||||
|                             if (list.length !== elements[0].children.length - breaks) { | ||||
|                                 if (lastCollection) | ||||
|                                     if (lastCollection.length) | ||||
|                                         targetIndex += lastCollection.length; | ||||
|                             } | ||||
|                             //  elements[0].children[targetIndex].insertAdjacentHTML(breakPosition, breakHtml(carry + 1)); | ||||
|                             breaks++; | ||||
|                             carry = 0; | ||||
|                         } | ||||
|                     } else { | ||||
|                         carry++; | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 last = list[x][breakon] > last ? list[x][breakon] : last; | ||||
|             } | ||||
|  | ||||
|             lastCollection = list; | ||||
|         } finally { | ||||
|             updatingBreakPoints = false; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     //beforeUpdate(() => {updateBreak()}); | ||||
|  | ||||
|     let updating = false; | ||||
|  | ||||
|     afterUpdate(async () => { | ||||
|         if (isDragging) return; | ||||
|         if (breakon == null) return; | ||||
|  | ||||
|         updating = true; | ||||
|         removeOldBreaks(Elements()); | ||||
|         await tick(); | ||||
|         updateBreak(); | ||||
|  | ||||
|         updating = false; | ||||
|  | ||||
|     }); | ||||
|  | ||||
|     const getClass = () => { | ||||
|         let ret = ""; | ||||
|         if (key) | ||||
|             ret += ` ${key}`; | ||||
|         if (ulclass) | ||||
|             ret += ` ${ulclass}`; | ||||
|  | ||||
|         return ret; | ||||
|     } | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
|  | ||||
|     ul { | ||||
|         display: inline-grid; | ||||
|         list-style: none; | ||||
|         padding: 0; | ||||
|         width: 100%; | ||||
|     } | ||||
|  | ||||
|     li { | ||||
|         display: inline-block; | ||||
|         border: 2px dotted transparent; | ||||
|         transition: border 0.1s linear; | ||||
|         width: 100%; | ||||
|         height: 100%; | ||||
|         margin: .5%; | ||||
|     } | ||||
|  | ||||
|     .startsNewGroup { | ||||
|         grid-column-start: 1; | ||||
|     } | ||||
|  | ||||
|     .small { | ||||
|         grid-column-end: span 1; | ||||
|         grid-row: span 1; | ||||
|     } | ||||
|  | ||||
|     .medium { | ||||
|         grid-column-end: span 2; | ||||
|         grid-row: span 1; | ||||
|     } | ||||
|  | ||||
|     .large { | ||||
|         grid-column-end: span 2; | ||||
|         /*grid-row: span 2; large buttons are double height, but they also push the row below them down (they dont fit around eachother like css-grid) */ | ||||
|     } | ||||
|  | ||||
|     .over { | ||||
|         border-color: rgba(48, 12, 200, 0.2); | ||||
|     } | ||||
| </style> | ||||
|  | ||||
| {#if list && list.length} | ||||
|     <ul class={getClass()}> | ||||
|         {#each list as item, index (getKey(item))} | ||||
|             <li | ||||
|                     class:small={item.displayTileSize === 2} | ||||
|                     class:medium={item.displayTileSize === 3} | ||||
|                     class:large={item.displayTileSize === 4} | ||||
|                     class:startsNewGroup={item.startsNewGroup} | ||||
|                     class:endsGroup={item.endsGroup} | ||||
|                     data-index={index} | ||||
|                     data-item={JSON.stringify(item)} | ||||
|                     data-id={JSON.stringify(getKey(item))} | ||||
|                     draggable="true" | ||||
|                     on:dragstart={start} | ||||
|                     on:dragover={over} | ||||
|                     on:dragleave={leave} | ||||
|                     on:drop={drop} | ||||
|                     on:click={click} | ||||
|                     in:receive={{ key: getKey(item) }} | ||||
|                     out:send={{ key: getKey(item) }} | ||||
|                     animate:flip={{ duration: 300 }} | ||||
|                     class:over={getKey(item) === isOver}> | ||||
|  | ||||
|                 <slot {item} {index}> | ||||
|                     <p>{getKey(item)}</p> | ||||
|                 </slot> | ||||
|  | ||||
|             </li> | ||||
|         {/each} | ||||
|     </ul> | ||||
| {/if} | ||||
| @@ -1,6 +1,7 @@ | ||||
| <script> | ||||
|     export let name = "%USER%"; | ||||
|     export let icon; | ||||
|     export let onClick; | ||||
| </script> | ||||
|  | ||||
| <style> | ||||
| @@ -18,4 +19,4 @@ | ||||
| </style> | ||||
|  | ||||
|  | ||||
| <a href="404"> <img src="/user.svg"> </a> | ||||
| <a on:click={onClick} href="404"> <img src="/user.svg"> </a> | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| <script> | ||||
|     import Nav from '../components/Nav.svelte'; | ||||
|     import userManager from '../components/userManager.svelte' | ||||
|     import Modal from '../components/Modal.svelte' | ||||
|  | ||||
|     export let segment; | ||||
| </script> | ||||
| @@ -34,6 +35,7 @@ | ||||
|  | ||||
|     </style> | ||||
|  | ||||
| <Modal | ||||
| <Nav {segment} rightComponent={userManager}/> | ||||
|  | ||||
| <slot></slot> | ||||
|   | ||||
							
								
								
									
										6
									
								
								static/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								static/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										140
									
								
								static/css/global.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										140
									
								
								static/css/global.css
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| body { | ||||
|   font-family: 'Open Sans', sans-serif; | ||||
|   font-display: swap; | ||||
|   font-size: 1rem; | ||||
|   line-height: 1.8; | ||||
| } | ||||
|  | ||||
| .overlay { | ||||
|   display: flex; | ||||
|   background-size: cover; | ||||
|   background-position: center; | ||||
|   min-height: 200px; | ||||
|   text-align: center; | ||||
|   align-items: center; | ||||
|   justify-content: center; | ||||
| } | ||||
|  | ||||
| .title { | ||||
|   display: inline-block; | ||||
|   font-size: 3rem; | ||||
|   text-decoration: none; | ||||
| } | ||||
|  | ||||
| nav { | ||||
|   align-items: center; | ||||
|   display: flex; | ||||
|   flex-direction: row; | ||||
|   justify-content: space-between; | ||||
| } | ||||
|  | ||||
| /* flexbox navbar test*/ | ||||
| nav ul { | ||||
|   display: flex; | ||||
|   padding: 0; | ||||
|   margin: 0; | ||||
| } | ||||
|  | ||||
| nav ul li { | ||||
|   font-size: 1rem; | ||||
|   text-align: center; | ||||
|   padding: 5px; | ||||
| } | ||||
|  | ||||
| nav li { | ||||
|   list-style-type: none; | ||||
| } | ||||
|  | ||||
| /* Change color on hover */ | ||||
| nav li a { | ||||
|   margin-left: 20px; | ||||
|   margin-right: 20px; | ||||
|   text-decoration: none; | ||||
| } | ||||
|  | ||||
| main { | ||||
|   margin-top: 30px; | ||||
| } | ||||
|  | ||||
| /* Content types */ | ||||
| section { | ||||
|   border-radius: 5px; | ||||
|   padding: 5px 20px; | ||||
| } | ||||
|  | ||||
| /*Simple css to style it like a toggle switch*/ | ||||
| .theme-switch-wrapper { | ||||
|   display: flex; | ||||
|   align-items: center; | ||||
| } | ||||
|  | ||||
| .theme-switch { | ||||
|   display: inline-block; | ||||
|   height: 24px; | ||||
|   position: relative; | ||||
|   width: 40px; | ||||
| } | ||||
|  | ||||
| .theme-switch input { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| .slider { | ||||
|   background-color: #ccc; | ||||
|   bottom: 0; | ||||
|   cursor: pointer; | ||||
|   left: 0; | ||||
|   position: absolute; | ||||
|   right: 0; | ||||
|   top: 0; | ||||
|   transition: .2s; | ||||
| } | ||||
|  | ||||
| .slider:before { | ||||
|   background-color: #fff; | ||||
|   bottom: 4px; | ||||
|   content: ""; | ||||
|   height: 16px; | ||||
|   left: 4px; | ||||
|   position: absolute; | ||||
|   transition: .2s; | ||||
|   width: 16px; | ||||
| } | ||||
|  | ||||
| input:checked + .slider { | ||||
|   background-color: #66bb6a; | ||||
| } | ||||
|  | ||||
| input:checked + .slider:before { | ||||
|   transform: translateX(16px); | ||||
| } | ||||
|  | ||||
| .slider.round { | ||||
|   border-radius: 34px; | ||||
| } | ||||
|  | ||||
| .slider.round:before { | ||||
|   border-radius: 50%; | ||||
| } | ||||
|  | ||||
| /* Responsive layout - when the screen is less than 700px wide, make the two columns stack on top of each other instead of next to each other */ | ||||
| @media screen and (max-width: 700px) { | ||||
|   .title { | ||||
|     display: block; | ||||
|     text-align: center; | ||||
|   } | ||||
|  | ||||
|   nav { | ||||
|     flex-direction: column; | ||||
|   } | ||||
|  | ||||
|   nav ul { | ||||
|     flex-direction: column; | ||||
|     margin: 0 auto; | ||||
|   } | ||||
|  | ||||
|   nav ul li a { | ||||
|     text-align: center; | ||||
|     margin: 0 auto; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										43
									
								
								static/css/themes.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										43
									
								
								static/css/themes.css
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* Default theme */ | ||||
| :root { | ||||
|     --background-color: #222222; | ||||
|     --headings-color: #ffffff; | ||||
|     --font-color: #ffffff; | ||||
| } | ||||
|  | ||||
| /* Dark theme */ | ||||
| html[data-theme='dark'] { | ||||
|     --background-color: #222222; | ||||
|     --headings-color: #ffffff; | ||||
|     --font-color: #ffffff; | ||||
| } | ||||
|  | ||||
| body { | ||||
|     background-color: var(--background-color); | ||||
|     color: var(--font-color); | ||||
| } | ||||
|  | ||||
| h1, h2, h3, h4, h5 { | ||||
|     color: var(--headings-color); | ||||
| } | ||||
|  | ||||
| hr { | ||||
|     background-color: #eeeeee; | ||||
| } | ||||
|  | ||||
| .overlay { | ||||
|     border-bottom: 2px solid #eeeeee; | ||||
| } | ||||
|  | ||||
| li a:hover { | ||||
|     border-bottom: 3px solid white; | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| a { | ||||
|     color: #CC99FF; | ||||
| } | ||||
|  | ||||
| a:hover { | ||||
|     color: white; | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								static/img/bluenebula.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/bluenebula.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.6 MiB | 
							
								
								
									
										
											BIN
										
									
								
								static/img/bluenebula.webp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/bluenebula.webp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 3.9 KiB | 
							
								
								
									
										
											BIN
										
									
								
								static/img/favicon.ico
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/favicon.ico
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 15 KiB | 
							
								
								
									
										
											BIN
										
									
								
								static/img/friendscats1.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								static/img/friendscats1.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 140 KiB | 
							
								
								
									
										5
									
								
								static/img/user.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								static/img/user.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" | ||||
|      stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"> | ||||
|     <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> | ||||
|     <circle cx="12" cy="7" r="4"></circle> | ||||
| </svg> | ||||
| After Width: | Height: | Size: 322 B | 
		Reference in New Issue
	
	Block a user