site-libsoc/Server/app/svelte/src/manifesto-component.svelte

411 lines
13 KiB
Svelte

<svelte:options tag="manifesto-component" />
<script>
// Import statements
import { onMount } from 'svelte'
import { writable } from 'svelte/store';
import { getData } from "/js/libraries/serverTools.js"
import { px2rem } from "/js/libraries/miscTools.js"
import { loadLocaleContent } from "/js/libraries/serverTools.js"
// Import components
// Main code
let manifesto = []
let key
let contentButton
let contentArrow
let contentBlock
let buttons = []
let headingsObjects = {}
let contentHeadings = []
let contentTable
let lastTop = 0
let margin = 0
let root
let main
let loaded = writable(0)
let content = writable({})
loadLocaleContent(content,"countries",loaded)
let locale = loadLocaleContent(content,"manifesto-component",loaded)
const htmlDelims = ["ul","ol"]
getData("/locales/"+ locale + "/manifesto.txt",function(response) {
let splitText = response.split(/\r?\n/)
let currentChapter
let cnt = 0
for (let j=0;j<splitText.length;j++) {
let line = splitText[j]
let delimInd = htmlDelims.map((x) => line.includes("<"+x+">")).findIndex((x) => x)
if (delimInd!=-1) {
let delim = htmlDelims[delimInd]
let obj = {}
obj[delim] = []
let delimEndTag = "</"+delim+">"
while (true) {
j += 1
line = splitText[j]
if (line.includes(delimEndTag)) {
manifesto.push(obj)
break
}
else {
obj[delim].push(line)
}
}
}
else {
if (line.slice(0,3)=="###") {
let heading = line.slice(4,line.length)
let id = heading.toLowerCase().trim().replaceAll(" ","-")
currentChapter.push({
id: id,
name: heading,
index: cnt
})
cnt += 1
manifesto.push({type: "h3", id: id, line: heading, index: cnt})
}
else if (line.slice(0,2)=="##") {
let heading = line.slice(3,line.length)
let id = heading.toLowerCase().trim().replaceAll(" ","-")
contentHeadings.push({
id: heading.toLowerCase().trim().replaceAll(" ","-"),
name: heading,
index: cnt
})
cnt += 1
currentChapter = []
contentHeadings.push(currentChapter)
manifesto.push({type: "h2", id: id, line: heading, index: cnt})
}
else {
manifesto.push(line)
}
}
}
key += 1
})
function hideBlock(arrow,block) {
if (block.style.display=="none" || block.style.display=="") {
block.style.display = "initial"
arrow.style.transform = "scaleY(-1)"
localStorage.setItem("manifesto-hide-content", "false");
}
else {
block.style.display = "none"
arrow.style.transform = ""
localStorage.setItem("manifesto-hide-content", "true");
}
}
function goToChapter(id) {
headingsObjects[id].scrollIntoView({block: 'start'}, true);
}
addEventListener("scroll", (event) => {
if (window.innerWidth>1080) {
let top = px2rem(window.scrollY)
let textBottom = px2rem(root.getBoundingClientRect().bottom + window.scrollY)
let tableBottom = px2rem(contentTable.getBoundingClientRect().bottom + window.scrollY)
if ((top>lastTop && top<5) || (top<lastTop && top<5)) {
margin = -Math.min(px2rem(window.scrollY),5)
}
else if (tableBottom >= (textBottom - 1.5)) {
margin = margin - (tableBottom - (textBottom - 1.5))
}
else {
if (margin>-5) {
margin = -5
}
if (top<5 && top!=0) {
let dif = px2rem(contentTable.offsetHeight - window.innerHeight)
margin = -Math.min(px2rem(window.scrollY),5 + dif + 2.5)
}
else if (top<lastTop || margin==0) {
if (margin <-5) {
margin = margin + (lastTop-top)
}
else {
margin = -5
}
}
else {
if (contentTable.offsetHeight > window.innerHeight) {
let dif = px2rem(contentTable.offsetHeight) - px2rem(window.innerHeight)
if (margin > -(dif+8)) {
margin = margin + (lastTop-top)
}
else {
margin = -(dif+8)
}
}
}
}
contentTable.style.marginTop = margin + "rem"
lastTop = px2rem(window.scrollY)
}
else {
contentTable.style.marginTop = "0rem"
}
})
onMount(() => {
let hideBool = localStorage.getItem("manifesto-hide-content")
if (hideBool!=undefined && hideBool!=null) {
if (hideBool=="true") {
hideBlock(contentArrow,contentBlock)
}
}
})
</script>
{#key $loaded}
{#if $loaded==2}
<div id="container" bind:this={root}>
<div id="text-container">
{#key key}
<div bind:this={contentTable} id="table-content">
<button id="toggle-content" bind:this={contentButton} on:click={() => hideBlock(contentArrow,contentBlock)}>
{$content.tableOfContents}
<img bind:this={contentArrow} src="../assets/arrow_down.svg" alt="arrow down" style="transform: scaleY(-1)">
</button>
<div bind:this={contentBlock} class="module" style="display: initial;">
{#each contentHeadings as obj}
{#if Array.isArray(obj)}
{#each obj as obj2}
<div class="heading-button-wrapper">
<button bind:this={buttons[obj2.index]} on:click={() => goToChapter(obj2.id)} class="level1 heading-button">
{obj2.name}
</button>
</div>
{/each}
{:else}
<div class="heading-button-wrapper">
<button bind:this={buttons[obj.index]} on:click={() => goToChapter(obj.id)} class="level0 heading-button">
{obj.name}
</button>
</div>
{/if}
{/each}
</div>
</div>
<div id="main" bind:this={main}>
{#each manifesto as line}
{#if line!==""}
{#if typeof (line === 'object') && (Object.keys(line)[0]=="ul")}
<ul>
{#each line.ul as line2}
<li>{line2}</li>
{/each}
</ul>
{:else if typeof (line === 'object') && (Object.keys(line)[0]=="ol")}
<ol>
{#each line.ol as line2}
<li>
{@html line2}
</li>
{/each}
</ol>
{:else if typeof (line === 'object') && (line.type=="h3")}
<button on:click ={contentTable.scrollIntoView({block: 'start'}, true)} style="display: block; width: 100%;">
<h3 bind:this={headingsObjects[line.id]} id={line.id}>{@html line.line}</h3>
</button>
{:else if typeof (line === 'object') && (line.type=="h2")}
<button on:click ={contentTable.scrollIntoView({block: 'start'}, true)} style="display: block; width: 100%;">
<h2 bind:this={headingsObjects[line.id]} id={line.id}>{@html line.line}</h2>
</button>
{:else if line[0]=="#"}
<h1>{@html line.slice(2,line.length)}</h1>
{:else}
<p class="margin-end">
{@html line}
</p>
{/if}
{:else if false}
<b></b>
{/if}
{/each}
</div>
{/key}
</div>
</div>
{/if}
{/key}
<style>
@import '/css/common.css';
#main b {
color: #d50400;
}
#table-content {
position: fixed;
display: flex;
flex-direction: column;
border: #cdcdcd 0.1rem solid;
border-radius: 1rem;
padding: 2rem;
padding-top: 1rem;
padding-right: 0.8rem;
padding-bottom: 1.5rem;
margin-bottom: 2rem;
width: 20rem;
height: max-content;
}
#toggle-content {
position: relative;
width: 100%;
font-size: 1.2rem;
font-family: var(--sans-serif,sans-serif);
text-align: left;
padding-bottom: 1rem;
font-weight: bold;
padding-top: 0.3rem;
}
#toggle-content img {
position: absolute;
top: 0.3rem;
right: 0.8rem;
width: 1.5rem;
}
.module {
position: relative;
display: inline-block;
width: 100%;
height: max-content;
padding-right: 1.2rem;
}
.heading-button-wrapper {
position: relative;
}
.heading-button {
color: black;
height: auto;
width: 100%;
padding-top: 0.25rem;
padding-bottom: 0.35rem;
text-align: left;
font-family: var(--sans-serif,sans-serif);
font-size: 1.2rem;
}
.level0 {
position: relative;
padding-left: 0.5rem;
z-index: 1;
}
.level1 {
position: relative;
padding-left: 1.5rem;
z-index: 1;
margin-left: 1rem;
width: calc(100% - 1rem);
border-left: #cdcdcd 0.1rem solid;
}
.heading-button:hover {
background-color: hsla(344, 73%, 57%, 0.12);
}
.heading-button:active {
background-color: hsla(344, 73%, 57%, 0.5);
}
h1 {
margin-bottom: 1rem;
font-size: 2rem;
text-align: center;
}
h2 {
margin-bottom: 1rem;
text-align: center;
}
h3 {
margin-bottom: 1rem;
}
#text-container {
position: relative;
display: grid;
grid-template-columns: 20rem 700px 20rem;
grid-gap: 2rem;
max-width: calc(100vw - 4rem);
margin: auto;
}
#container {
display: flex;
align-content: center;
margin: auto;
max-width: min(1800px,100vw);
margin-top: 1rem;
margin-bottom: 4rem;
}
#main {
grid-column: 2;
}
#main>p {
margin-bottom: 1rem;
}
#container p {
text-align: justify;
}
@media only screen and (max-width: 1210px) {
#text-container {
position: relative;
display: grid;
grid-template-columns: auto;
grid-gap: 2rem;
max-width: calc(1800px,100vw - 4rem);
margin: auto;
}
#toggle-content img {
right: 0;
}
#table-content {
position: relative;
border: #a9a9a9 0.1rem solid;
border-radius: 1rem;
padding: 2rem;
padding-bottom: 1.5rem;
margin-bottom: 2rem;
height: max-content;
width: 100%;
}
.module {
padding-right: 0;
}
#main {
grid-column: 1;
}
#container {
max-width: min(700px,100vw);
}
}
</style>