Updating to version 2.3.1
UX improvement 1. Exporting options are in a context menu for easier access to mobile devices. 2. Added the submit button for submitting new content to the app. 3. Options will be available as per the user's privilege level. 4. Export options on desktop will be displayed as soon as a selection is made. 5. Added option to logout and clear local data. 6. Added icons to actions for better understanding. UI improvements 1. Blur effect for popups and dialogs boxes( !Experimental chromium only). 2. Fixed issue with scroll arrows not disappearing on the desktop when the last element is reached. 3. Fixed issue with web fonts not rendering properly. **Other minor UI/UX improvements and bug fixes.
This commit is contained in:
parent
99b967468c
commit
bc6e973fdc
@ -6,9 +6,10 @@
|
|||||||
<meta name="keywords" content="blockchain,ContentCollaboration,RanchiMall">
|
<meta name="keywords" content="blockchain,ContentCollaboration,RanchiMall">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<meta name="description" content="This web app can be used to collaborate between various teams using blockchain technology.">
|
<meta name="description" content="This web app can be used to collaborate between various teams using blockchain technology.">
|
||||||
<link href="https://fonts.googleapis.com/css?family=Quicksand|Roboto&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Quicksand:400,700|Roboto:300,400,500,700&display=swap" rel="stylesheet">
|
||||||
<!--<link rel="stylesheet" href="css/main.css">-->
|
<!--<link rel="stylesheet" href="css/main.css">-->
|
||||||
<style>html {
|
<style>html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +48,7 @@
|
|||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2, h3, h4, h5 {
|
h1, h2, h3, h4, h5, span, p {
|
||||||
font-family: 'Quicksand', sans-serif;
|
font-family: 'Quicksand', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +69,22 @@
|
|||||||
background: #555;
|
background: #555;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hide-completely {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
._2rem-stroke svg {
|
||||||
|
stroke-width: 0.2rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
._5rem-stroke svg {
|
||||||
|
stroke-width: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-fill svg, .no-fill path, .no-fill polyline {
|
||||||
|
fill: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
display: -webkit-inline-box;
|
display: -webkit-inline-box;
|
||||||
display: -ms-inline-flexbox;
|
display: -ms-inline-flexbox;
|
||||||
@ -81,11 +98,12 @@
|
|||||||
border: none;
|
border: none;
|
||||||
-webkit-transition: background 0.2s ease;
|
-webkit-transition: background 0.2s ease;
|
||||||
transition: background 0.2s ease;
|
transition: background 0.2s ease;
|
||||||
font-weight: bold;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
button svg {
|
button svg {
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
|
width: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover {
|
button:hover {
|
||||||
@ -114,6 +132,54 @@
|
|||||||
font-size: 1rem !important;
|
font-size: 1rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#clear_export svg {
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
background-color: #222;
|
||||||
|
width: -webkit-max-content;
|
||||||
|
width: -moz-max-content;
|
||||||
|
width: max-content;
|
||||||
|
text-align: right;
|
||||||
|
-webkit-box-shadow: 0.2rem 0.4rem 0.6rem rgba(0, 0, 0, 0.24);
|
||||||
|
box-shadow: 0.2rem 0.4rem 0.6rem rgba(0, 0, 0, 0.24);
|
||||||
|
z-index: 2;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-content button svg {
|
||||||
|
fill: none;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown:hover .dropdown-content {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex: 1;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.popup-container {
|
.popup-container {
|
||||||
display: -ms-grid;
|
display: -ms-grid;
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -124,9 +190,11 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
place-items: center;
|
place-items: center;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
-webkit-backdrop-filter: blur(0.5rem);
|
||||||
|
backdrop-filter: blur(0.5rem);
|
||||||
z-index: 4;
|
z-index: 4;
|
||||||
-webkit-transition: opacity 0.2s ease;
|
-webkit-transition: opacity 0.3s ease;
|
||||||
transition: opacity 0.2s ease;
|
transition: opacity 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popup-container .popup {
|
.popup-container .popup {
|
||||||
@ -150,6 +218,10 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#context_menu {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#article_creation_modal {
|
#article_creation_modal {
|
||||||
max-height: 24rem;
|
max-height: 24rem;
|
||||||
width: 24rem;
|
width: 24rem;
|
||||||
@ -246,7 +318,7 @@
|
|||||||
|
|
||||||
#edit_article header button svg {
|
#edit_article header button svg {
|
||||||
stroke: var(--primary-color);
|
stroke: var(--primary-color);
|
||||||
stroke-width: 0.2rem;
|
stroke-width: 0.3rem;
|
||||||
fill: none;
|
fill: none;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -324,24 +396,33 @@
|
|||||||
.article-body .article-header h5 {
|
.article-body .article-header h5 {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: #82DDF0;
|
color: #82DDF0;
|
||||||
font-family: 'roboto', sans-serif;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-body .card-body {
|
.article-body .card-body {
|
||||||
|
position: relative;
|
||||||
-webkit-box-flex: 1;
|
-webkit-box-flex: 1;
|
||||||
-ms-flex: 1;
|
-ms-flex: 1;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-body .card-body .content-div {
|
.article-body .card-body .content-div {
|
||||||
padding: 0 1rem;
|
padding: 0 1rem 4rem 1rem;
|
||||||
min-height: 12rem;
|
min-height: 12rem;
|
||||||
line-height: 1.4rem;
|
line-height: 1.2rem;
|
||||||
max-height: 60vh;
|
max-height: 60vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
font-family: 'Quicksand', serif;
|
font-weight: 400;
|
||||||
font-weight: normal !important;
|
}
|
||||||
font-size: 1.1rem;
|
|
||||||
|
.article-body .card-body .content-div * {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-body .card-body button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
margin-right: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-body .card-footer {
|
.article-body .card-footer {
|
||||||
@ -363,24 +444,24 @@
|
|||||||
-webkit-box-align: center;
|
-webkit-box-align: center;
|
||||||
-ms-flex-align: center;
|
-ms-flex-align: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.article-body .card-footer h5:first-of-type {
|
|
||||||
margin-left: auto;
|
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.article-body .card-footer h5:nth-of-type(2) {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-body .card-footer h5:nth-of-type(2):hover svg {
|
||||||
|
fill: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
.article-body .card-footer h5 svg {
|
.article-body .card-footer h5 svg {
|
||||||
stroke: var(--primary-color);
|
stroke: var(--primary-color);
|
||||||
width: 1.2rem;
|
width: 1.2rem;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.article-body .card-footer h5 svg:hover {
|
|
||||||
fill: var(--primary-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.show {
|
.show {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
@ -400,6 +481,10 @@
|
|||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.snippet-selected {
|
||||||
|
outline: 1px solid var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
.no-transformations {
|
.no-transformations {
|
||||||
-webkit-transform: none !important;
|
-webkit-transform: none !important;
|
||||||
transform: none !important;
|
transform: none !important;
|
||||||
@ -420,7 +505,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
color: white;
|
color: white;
|
||||||
background: #222;
|
background: #222;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem 1rem;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,6 +533,12 @@
|
|||||||
stroke: var(--primary-color);
|
stroke: var(--primary-color);
|
||||||
stroke-width: 0.2rem;
|
stroke-width: 0.2rem;
|
||||||
margin-right: 0.5rem;
|
margin-right: 0.5rem;
|
||||||
|
fill: none;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.floating-btn {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#loader_container {
|
#loader_container {
|
||||||
@ -455,7 +546,11 @@
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
top: 0;
|
top: 0;
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.4);
|
||||||
|
-webkit-backdrop-filter: blur(0.5rem);
|
||||||
|
backdrop-filter: blur(0.5rem);
|
||||||
|
-webkit-transition: opacity 0.6s ease;
|
||||||
|
transition: opacity 0.6s ease;
|
||||||
display: -ms-grid;
|
display: -ms-grid;
|
||||||
display: grid;
|
display: grid;
|
||||||
place-content: center;
|
place-content: center;
|
||||||
@ -477,6 +572,10 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#loader_container button {
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.pulse .first-orb {
|
.pulse .first-orb {
|
||||||
-webkit-animation: pulse 1s infinite ease;
|
-webkit-animation: pulse 1s infinite ease;
|
||||||
animation: pulse 1s infinite ease;
|
animation: pulse 1s infinite ease;
|
||||||
@ -522,6 +621,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spin svg {
|
||||||
|
-webkit-animation: spin 0.6s ease infinite;
|
||||||
|
animation: spin 0.6s ease infinite;
|
||||||
|
-webkit-transform-origin: center;
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@-webkit-keyframes spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0);
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(359deg);
|
||||||
|
transform: rotate(359deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
-webkit-transform: rotate(0);
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
-webkit-transform: rotate(359deg);
|
||||||
|
transform: rotate(359deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 640px) {
|
@media only screen and (max-width: 640px) {
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 0.2rem;
|
width: 0.2rem;
|
||||||
@ -533,11 +661,59 @@
|
|||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
}
|
}
|
||||||
|
.hide-on-mobile {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
.article-body {
|
.article-body {
|
||||||
min-width: calc(100% - 2em) !important;
|
min-width: calc(100% - 2em) !important;
|
||||||
}
|
}
|
||||||
|
#context_menu, .floating-btn {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
margin: 2rem;
|
||||||
|
background: #222;
|
||||||
|
position: fixed;
|
||||||
|
-webkit-box-shadow: 0.2rem 0.4rem 0.6rem rgba(0, 0, 0, 0.24), -0.1rem -0.2rem 0.4rem rgba(0, 0, 0, 0.16);
|
||||||
|
box-shadow: 0.2rem 0.4rem 0.6rem rgba(0, 0, 0, 0.24), -0.1rem -0.2rem 0.4rem rgba(0, 0, 0, 0.16);
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
#context_menu button, .floating-btn button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#context_menu button svg, .floating-btn button svg {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--primary-color);
|
||||||
|
}
|
||||||
|
.floating-btn {
|
||||||
|
background: #282828;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
border-radius: 5rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.floating-btn button svg {
|
||||||
|
stroke-width: 0.2rem;
|
||||||
|
}
|
||||||
|
#context_menu {
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: column;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#context_menu button svg {
|
||||||
|
stroke-width: 0.2rem;
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
#context_menu button:nth-of-type(1) svg {
|
||||||
|
-webkit-transform: rotate(45deg);
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
#article_container {
|
#article_container {
|
||||||
padding: 1rem;
|
padding: 0.5rem 0.5rem 6rem 0.5rem;
|
||||||
|
}
|
||||||
|
#navbar {
|
||||||
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
.navigation-arrows {
|
.navigation-arrows {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -560,6 +736,9 @@
|
|||||||
.article-body {
|
.article-body {
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
}
|
}
|
||||||
|
.hide-on-medium {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*# sourceMappingURL=main.css.map */</style>
|
/*# sourceMappingURL=main.css.map */</style>
|
||||||
</head>
|
</head>
|
||||||
@ -596,34 +775,41 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<body onload="onLoadStartUp()">
|
<body onload="onLoadStartUp()">
|
||||||
<section class="popup-container hide">
|
<div id="admindiv"></div>
|
||||||
<div id="article_creation_modal" class="popup">
|
<div id="context_menu" class="hide">
|
||||||
<h3>Create a new article</h3>
|
<button onclick="cloudArticleApp.reset_export_list()">
|
||||||
<input type="text" id="article_name" placeholder="Article name">
|
<svg viewBox="0 0 24 24">
|
||||||
|
<line x1="12" y1="0" x2="12" y2="24"/>
|
||||||
<input type="number" id="section_nums" placeholder="Number of sections">
|
<line x1="0" y1="12" x2="24" y2="12"/>
|
||||||
|
|
||||||
<button onclick="hidePopup('article_creation_modal')">Cancel</button>
|
|
||||||
<button id="reset_data_btn">Create</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<div class="popup-container hide">
|
|
||||||
<div id="edit_article" class="popup">
|
|
||||||
<header>
|
|
||||||
<h3>Edit section names</h3>
|
|
||||||
<button onclick="cloudArticleApp.update_section_names()">
|
|
||||||
<svg viewBox="0 0 45.91 32.62">
|
|
||||||
<polyline points="0.71,17.21 14.71,31.21 45.21,0.71 "/>
|
|
||||||
</svg>
|
</svg>
|
||||||
Done</button>
|
Clear Selection</button>
|
||||||
</header>
|
<button onclick="cloudArticleApp.export_as_file()">
|
||||||
<div id="edit_section_container"></div>
|
<svg viewBox="0 0 28.44 24.47">
|
||||||
|
<g>
|
||||||
|
<path d="M27.19,6.72C14.18,6.6,4.87,12.2,0.47,24.3"/>
|
||||||
|
<polyline points="21.37,0.35 27.73,6.72 21.37,13.08"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
Export as file</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="floating-btn">
|
||||||
|
<button onclick="cloudArticleApp.retrieveLatestContent()">
|
||||||
|
<svg viewBox="0 0 38 40.05">
|
||||||
|
<title>Refresh content</title>
|
||||||
|
<path d="M37,21.05c0,9.94-8.06,18-18,18s-18-8.06-18-18s8.06-18,18-18c5.89,0,11.11,2.82,14.4,7.19"/>
|
||||||
|
<polygon points="22.63,10.96 22.81,8.96 32.63,9.86 32.81,0 34.81,0.04 34.59,12.05 "/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button class="admin-options hide-completely" onclick="showPopup('article_creation_modal')">
|
||||||
|
<svg viewBox="0 0 24 24">
|
||||||
|
<title>Create new article</title>
|
||||||
|
<line x1="12" y1="0" x2="12" y2="24"/>
|
||||||
|
<line x1="0" y1="12" x2="24" y2="12"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav id="navbar">
|
<nav id="navbar">
|
||||||
<svg id="icon" viewBox="0 0 99.555 117.877">
|
<svg id="icon" viewBox="0 0 99.555 117.877" title="Content collaboration logo">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.first-orb{fill:#00FA9A;}
|
.first-orb{fill:#00FA9A;}
|
||||||
.second-orb{fill:#00EDBF;}
|
.second-orb{fill:#00EDBF;}
|
||||||
@ -635,13 +821,58 @@
|
|||||||
<circle class="third-orb" cx="68" cy="86" r="32"/>
|
<circle class="third-orb" cx="68" cy="86" r="32"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<span><h5>RanchiMall</h5>CONTENT COLLABORATION</span>
|
<span><h5>RanchiMall</h5>CONTENT COLLABORATION</span><div class="spacer"></div>
|
||||||
<button onclick="showPopup('article_creation_modal')">
|
<button id="refresh_btn" title="Refresh the content" class="hide-on-mobile" onclick="cloudArticleApp.retrieveLatestContent()">
|
||||||
|
<svg viewBox="0 0 38 40.05">
|
||||||
|
<path d="M37,21.05c0,9.94-8.06,18-18,18s-18-8.06-18-18s8.06-18,18-18c5.89,0,11.11,2.82,14.4,7.19"/>
|
||||||
|
<polygon points="22.63,10.96 22.81,8.96 32.63,9.86 32.81,0 34.81,0.04 34.59,12.05 "/>
|
||||||
|
</svg>
|
||||||
|
Refresh</button>
|
||||||
|
<button id="clear_export" title="Clear article selection" class="export-options hide-completely no-fill hide-on-mobile" onclick="cloudArticleApp.reset_export_list()">
|
||||||
<svg viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24">
|
||||||
<line x1="12" y1="0" x2="12" y2="24"/>
|
<line x1="12" y1="0" x2="12" y2="24"/>
|
||||||
<line x1="0" y1="12" x2="24" y2="12"/>
|
<line x1="0" y1="12" x2="24" y2="12"/>
|
||||||
</svg>
|
</svg>
|
||||||
Article</button>
|
Clear Selection</button>
|
||||||
|
<button class="export-options no-fill hide-completely hide-on-mobile" title="Export selected articles as html file" onclick="cloudArticleApp.export_as_file()">
|
||||||
|
<svg viewBox="0 0 28.44 24.47">
|
||||||
|
<g>
|
||||||
|
<path d="M27.19,6.72C14.18,6.6,4.87,12.2,0.47,24.3"/>
|
||||||
|
<polyline points="21.37,0.35 27.73,6.72 21.37,13.08"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
Export as file
|
||||||
|
</button>
|
||||||
|
<div class="dropdown hide-on-mobile admin-options hide-completely" title="dropdown menu option for sub-admins">
|
||||||
|
<button class="dropbtn _5rem-stroke">
|
||||||
|
<svg viewBox="0 0 72 55">
|
||||||
|
<line x1="0" y1="0.5" x2="63" y2="0.5"/>
|
||||||
|
<line x1="0" y1="27.5" x2="45" y2="27.5"/>
|
||||||
|
<line x1="0" y1="54.5" x2="72" y2="54.5"/>
|
||||||
|
</svg>
|
||||||
|
Options</button>
|
||||||
|
<div class="dropdown-content">
|
||||||
|
<button onclick="showPopup('article_creation_modal')" title="Create new article">
|
||||||
|
<svg viewBox="0 0 24 24">
|
||||||
|
<line x1="12" y1="0" x2="12" y2="24"/>
|
||||||
|
<line x1="0" y1="12" x2="24" y2="12"/>
|
||||||
|
</svg>
|
||||||
|
New Article
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="logout_btn" title="Logout button" class="_5rem-stroke" onclick="cloudArticleApp.logout()">
|
||||||
|
<svg viewBox="0 0 73.21 73">
|
||||||
|
<g>
|
||||||
|
<path d="M27.71,18.5"/>
|
||||||
|
<polyline points="27.71,18.5 27.71,0.5 72.71,0.5 72.71,72.5 27.71,72.5 27.71,54.5"/>
|
||||||
|
<g>
|
||||||
|
<line x1="41.85" y1="36.6" x2="0.71" y2="36.6"/>
|
||||||
|
<polyline points="16.14,21.17 0.71,36.6 16.14,52.03"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
Logout</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div id="loader_container" class="hide">
|
<div id="loader_container" class="hide">
|
||||||
@ -653,6 +884,7 @@
|
|||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<h4 id="show_log_events"></h4>
|
<h4 id="show_log_events"></h4>
|
||||||
|
<button onclick="cloudArticleApp.logout()">Clear All Data</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section id="article_container">
|
<section id="article_container">
|
||||||
@ -660,6 +892,7 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
// function required for popups or modals to appear
|
// function required for popups or modals to appear
|
||||||
function showPopup(popup) {
|
function showPopup(popup) {
|
||||||
let thisPopup = document.getElementById(popup);
|
let thisPopup = document.getElementById(popup);
|
||||||
@ -685,7 +918,7 @@
|
|||||||
container.children[1].classList.remove('hide')
|
container.children[1].classList.remove('hide')
|
||||||
},{
|
},{
|
||||||
root: container,
|
root: container,
|
||||||
threshold: 1
|
threshold: 0.8
|
||||||
})
|
})
|
||||||
observer.observe(container.children[0].firstElementChild)
|
observer.observe(container.children[0].firstElementChild)
|
||||||
container.children[0].scrollBy({
|
container.children[0].scrollBy({
|
||||||
@ -703,7 +936,7 @@
|
|||||||
container.children[2].classList.remove('hide')
|
container.children[2].classList.remove('hide')
|
||||||
}, {
|
}, {
|
||||||
root: container,
|
root: container,
|
||||||
threshold: 1
|
threshold: 0.8
|
||||||
})
|
})
|
||||||
observer.observe(container.children[0].lastElementChild)
|
observer.observe(container.children[0].lastElementChild)
|
||||||
|
|
||||||
@ -732,6 +965,59 @@
|
|||||||
spinner.firstElementChild.classList.remove('pulse');
|
spinner.firstElementChild.classList.remove('pulse');
|
||||||
spinner.classList.add('hide');
|
spinner.classList.add('hide');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buidAdminUI() {
|
||||||
|
|
||||||
|
if(floGlobals.subAdmins.includes(myFloID)) {
|
||||||
|
let admindivui = `<section class="popup-container hide" id="article_creation_div">
|
||||||
|
<div id="article_creation_modal" class="popup">
|
||||||
|
<h3>Create a new article</h3>
|
||||||
|
<input type="text" id="article_name" placeholder="Article name">
|
||||||
|
|
||||||
|
<input type="number" id="section_nums" placeholder="Number of sections">
|
||||||
|
|
||||||
|
<button onclick="hidePopup('article_creation_modal')">Cancel</button>
|
||||||
|
<button id="reset_data_btn">Create</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<div class="popup-container hide">
|
||||||
|
<div id="edit_article" class="popup">
|
||||||
|
<header>
|
||||||
|
<h3>Edit section names</h3>
|
||||||
|
<button onclick="cloudArticleApp.update_section_names()">
|
||||||
|
<svg viewBox="0 0 45.91 32.62">
|
||||||
|
<polyline points="0.71,17.21 14.71,31.21 45.21,0.71 "/>
|
||||||
|
</svg>
|
||||||
|
Done</button>
|
||||||
|
</header>
|
||||||
|
<div id="edit_section_container"></div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
document.getElementById('admindiv').innerHTML = admindivui;
|
||||||
|
|
||||||
|
const reset_data_btn = document.getElementById('reset_data_btn');
|
||||||
|
reset_data_btn.onclick = function() {
|
||||||
|
cloudArticleApp.resetArticleContent();
|
||||||
|
hidePopup('edit_article')
|
||||||
|
}
|
||||||
|
document.querySelectorAll('.admin-options').forEach((option) => {
|
||||||
|
option.classList.remove('hide-completely');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function buttonVisibility(mode, parent){
|
||||||
|
let button = parent.children[2];
|
||||||
|
if(parent.firstElementChild.innerText ==''){
|
||||||
|
button.classList.add('hide')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(mode === 'show' && button.classList.contains('hide'))
|
||||||
|
button.classList.remove('hide')
|
||||||
|
if(mode === 'hide' && !button.classList.contains('hide'))
|
||||||
|
button.classList.add('hide')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script id="init_lib">
|
<script id="init_lib">
|
||||||
@ -8333,7 +8619,6 @@ Bitcoin.Util = {
|
|||||||
sendDataToSN(data, snfloID){
|
sendDataToSN(data, snfloID){
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
console.log(snfloID)
|
console.log(snfloID)
|
||||||
console.info("five");
|
|
||||||
var websocket = new WebSocket("wss://" + floGlobals.supernodes[snfloID].uri + "/ws");
|
var websocket = new WebSocket("wss://" + floGlobals.supernodes[snfloID].uri + "/ws");
|
||||||
websocket.onmessage = (evt => {
|
websocket.onmessage = (evt => {
|
||||||
if(evt.data == '$+'){
|
if(evt.data == '$+'){
|
||||||
@ -8361,7 +8646,6 @@ Bitcoin.Util = {
|
|||||||
sendData: function (data, floID) {
|
sendData: function (data, floID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.kBucket.determineClosestSupernode(floID).then(closestNode => {
|
this.kBucket.determineClosestSupernode(floID).then(closestNode => {
|
||||||
console.info("four");
|
|
||||||
console.log(closestNode)
|
console.log(closestNode)
|
||||||
this.sendDataToSN(data, closestNode[0])
|
this.sendDataToSN(data, closestNode[0])
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
@ -8982,7 +9266,7 @@ Bitcoin.Util = {
|
|||||||
floGlobals.appObjects[message.object] = message.reset
|
floGlobals.appObjects[message.object] = message.reset
|
||||||
floGlobals.vectorClock[message.object] = vc
|
floGlobals.vectorClock[message.object] = vc
|
||||||
compactIDB.writeData("appObjects", floGlobals.appObjects[message.object], message.object)
|
compactIDB.writeData("appObjects", floGlobals.appObjects[message.object], message.object)
|
||||||
compactIDB.writeData("vectorClocks", vc, message.object)
|
compactIDB.writeData("vectorClock", vc, message.object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
@ -9001,7 +9285,7 @@ Bitcoin.Util = {
|
|||||||
compactIDB.writeData("appObjects",floGlobals.appObjects[message.object], message.object)
|
compactIDB.writeData("appObjects",floGlobals.appObjects[message.object], message.object)
|
||||||
}
|
}
|
||||||
floGlobals.vectorClock[message.object] = vc
|
floGlobals.vectorClock[message.object] = vc
|
||||||
compactIDB.writeData("vectorClocks", vc, message.object)
|
compactIDB.writeData("vectorClock", vc, message.object)
|
||||||
}
|
}
|
||||||
}catch(error){
|
}catch(error){
|
||||||
console.error(error)
|
console.error(error)
|
||||||
@ -9039,7 +9323,6 @@ Bitcoin.Util = {
|
|||||||
type: type,
|
type: type,
|
||||||
comment: options.comment || ""
|
comment: options.comment || ""
|
||||||
}
|
}
|
||||||
console.info("three");
|
|
||||||
console.table(data);
|
console.table(data);
|
||||||
floSupernode.sendData(JSON.stringify(data), data.receiverID)
|
floSupernode.sendData(JSON.stringify(data), data.receiverID)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
@ -9070,7 +9353,6 @@ Bitcoin.Util = {
|
|||||||
//send General Data
|
//send General Data
|
||||||
sendGeneralData: function(message, type, options = {}){
|
sendGeneralData: function(message, type, options = {}){
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
console.info("two");
|
|
||||||
this.sendApplicationData(message, type, options)
|
this.sendApplicationData(message, type, options)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
@ -9168,7 +9450,7 @@ Bitcoin.Util = {
|
|||||||
//for Dapps
|
//for Dapps
|
||||||
subAdmins:{},
|
subAdmins:{},
|
||||||
appObjects:{},
|
appObjects:{},
|
||||||
vectorClocks:{},
|
vectorClock:{},
|
||||||
generalData:{},
|
generalData:{},
|
||||||
generalVC:{}
|
generalVC:{}
|
||||||
}
|
}
|
||||||
@ -9232,7 +9514,7 @@ Bitcoin.Util = {
|
|||||||
|
|
||||||
loadDataFromIDB: function(){
|
loadDataFromIDB: function(){
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
var loadData = ["appObjects", "vectorClocks", "generalData", "generalVC"]
|
var loadData = ["appObjects", "vectorClock", "generalData", "generalVC"]
|
||||||
var promises = []
|
var promises = []
|
||||||
for(var i = 0; i < loadData.length; i++)
|
for(var i = 0; i < loadData.length; i++)
|
||||||
promises[i] = compactIDB.readAllData(loadData[i])
|
promises[i] = compactIDB.readAllData(loadData[i])
|
||||||
@ -9419,7 +9701,8 @@ Bitcoin.Util = {
|
|||||||
floDapps.launchStartUp().then(result => {
|
floDapps.launchStartUp().then(result => {
|
||||||
console.log(result)
|
console.log(result)
|
||||||
showMessage(result)
|
showMessage(result)
|
||||||
showMessage(`Welcome FLO_ID: ${myFloID}`)
|
showMessage(`Welcome ${myFloID}`)
|
||||||
|
buidAdminUI();
|
||||||
cloudArticleApp.retrieveLatestContent();
|
cloudArticleApp.retrieveLatestContent();
|
||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error))
|
||||||
}
|
}
|
||||||
@ -9429,14 +9712,16 @@ Bitcoin.Util = {
|
|||||||
|
|
||||||
const cloudArticleApp = {
|
const cloudArticleApp = {
|
||||||
|
|
||||||
SUBJECT: "BusinessDesign1", // BusinessDesign1 | testArticle9
|
SUBJECT: "testArticle9", // BusinessDesign1 | testArticle9
|
||||||
|
|
||||||
numberOfSections: 5,
|
numberOfSections: 5,
|
||||||
|
|
||||||
CONTENT_TYPE: "BUSINESS_DESIGN", // BUSINESS_DESIGN | typeContentCollab9
|
CONTENT_TYPE: "typeContentCollab9", // BUSINESS_DESIGN | typeContentCollab9
|
||||||
|
|
||||||
todaysContenthashList: [],
|
todaysContenthashList: [],
|
||||||
|
|
||||||
|
export_file_object: {},
|
||||||
|
|
||||||
delay: (t, v) => {
|
delay: (t, v) => {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
setTimeout(resolve.bind(null, v), t);
|
setTimeout(resolve.bind(null, v), t);
|
||||||
@ -9454,8 +9739,6 @@ Bitcoin.Util = {
|
|||||||
const full_data_div = document.getElementById('current_data'),
|
const full_data_div = document.getElementById('current_data'),
|
||||||
articleSubject = floGlobals.appObjects[this.SUBJECT];
|
articleSubject = floGlobals.appObjects[this.SUBJECT];
|
||||||
|
|
||||||
//const new_generalData = floDapps.getNextGeneralData(this.CONTENT_TYPE, floGlobals.vectorClock[this.SUBJECT]);
|
|
||||||
|
|
||||||
const new_generalData = floGlobals.generalData[JSON.stringify({application:floGlobals.application, type:cloudArticleApp.CONTENT_TYPE})]
|
const new_generalData = floGlobals.generalData[JSON.stringify({application:floGlobals.application, type:cloudArticleApp.CONTENT_TYPE})]
|
||||||
|
|
||||||
let new_entries_array = [];
|
let new_entries_array = [];
|
||||||
@ -9487,7 +9770,8 @@ Bitcoin.Util = {
|
|||||||
|
|
||||||
if(typeof secObject.section_details==="object"
|
if(typeof secObject.section_details==="object"
|
||||||
&& secObject.section_details.section_name.length) {
|
&& secObject.section_details.section_name.length) {
|
||||||
article_structure += `<h3 class="gallery-name">${secObject.section_details.section_name}</h3>`;
|
article_structure_id = Crypto.SHA256(secObject.section_details.section_name);
|
||||||
|
article_structure += `<h3 class="gallery-name" id="${article_structure_id}">${secObject.section_details.section_name}</h3>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add non scored new entries from users
|
// Add non scored new entries from users
|
||||||
@ -9513,13 +9797,7 @@ Bitcoin.Util = {
|
|||||||
let vc = article_data.vectorClock || "";
|
let vc = article_data.vectorClock || "";
|
||||||
|
|
||||||
if(Number(article_data.score)>0) {
|
if(Number(article_data.score)>0) {
|
||||||
// const new_content_object = {
|
|
||||||
// content: article_data.content,
|
|
||||||
// content_creator: article_data.content_creator,
|
|
||||||
// score: article_data.score,
|
|
||||||
// vectorClock: article_data.vectorClock,
|
|
||||||
// signerPubKey: article_data.signerPubKey
|
|
||||||
// }
|
|
||||||
const new_content_object = {
|
const new_content_object = {
|
||||||
article_name: article_data.article_name,
|
article_name: article_data.article_name,
|
||||||
content: article_data.content,
|
content: article_data.content,
|
||||||
@ -9544,15 +9822,17 @@ Bitcoin.Util = {
|
|||||||
article_structure +=
|
article_structure +=
|
||||||
`<div class="article-body">
|
`<div class="article-body">
|
||||||
<div class="article-header">
|
<div class="article-header">
|
||||||
<h5>${article_data.content_creator}</h5>
|
<h5 title="Article author">${article_data.content_creator}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="content-div" id="${gen_div_id}" data-value="${key}__${secKey}" contenteditable="true" onfocusout="cloudArticleApp.edit_onfocuout(event)">
|
<div class="content-div" id="${gen_div_id}" data-gramm="false" data-value="${key}__${secKey}" contenteditable="true" onkeyup="buttonVisibility('show', this.parentNode)">
|
||||||
${article_data.content.trim()}
|
${article_data.content.trim()}
|
||||||
</div>
|
</div>
|
||||||
<input type="hidden" id="hash_${gen_div_id}" value="${content_hash}">
|
<input type="hidden" id="hash_${gen_div_id}" value="${content_hash}"/>
|
||||||
|
<button class="hide" onclick="cloudArticleApp.edit_onfocuout(this.parentNode)">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
|
<h5 id="exp_${gen_div_id}" title="Add this article as selected" class="select-for-export" onclick="cloudArticleApp.register_content_to_export(event)">Select</h5>
|
||||||
<h5 title="Give score to this article">
|
<h5 title="Give score to this article">
|
||||||
<svg viewBox="0 0 16.55 16" style="enable-background:new 0 0 16.55 16;" xml:space="preserve" fill="${fill}">
|
<svg viewBox="0 0 16.55 16" style="enable-background:new 0 0 16.55 16;" xml:space="preserve" fill="${fill}">
|
||||||
<polygon
|
<polygon
|
||||||
@ -9629,10 +9909,13 @@ Bitcoin.Util = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
retrieveLatestContent: async function(receiverID=floGlobals.adminID, senderIDs=floGlobals.subAdmins) {
|
retrieveLatestContent: async function(receiverID=floGlobals.adminID, senderIDs=floGlobals.subAdmins) {
|
||||||
|
showLoader()
|
||||||
|
showMessage('Loading the latest content')
|
||||||
await floCloudAPI.requestObjectData(this.SUBJECT,{receiverID, senderIDs});
|
await floCloudAPI.requestObjectData(this.SUBJECT,{receiverID, senderIDs});
|
||||||
await floCloudAPI.requestGeneralData(this.CONTENT_TYPE);
|
await floCloudAPI.requestGeneralData(this.CONTENT_TYPE);
|
||||||
document.getElementById('current_data').innerHTML = '';
|
document.getElementById('current_data').innerHTML = '';
|
||||||
cloudArticleApp.showFullContentOfArticle(floGlobals.appObjects[cloudArticleApp.SUBJECT]);
|
cloudArticleApp.showFullContentOfArticle(floGlobals.appObjects[cloudArticleApp.SUBJECT]);
|
||||||
|
hideLoader()
|
||||||
},
|
},
|
||||||
|
|
||||||
createNewArticle: function(article_name, div='', number_of_sections=cloudArticleApp.numberOfSections) {
|
createNewArticle: function(article_name, div='', number_of_sections=cloudArticleApp.numberOfSections) {
|
||||||
@ -9722,7 +10005,7 @@ Bitcoin.Util = {
|
|||||||
let iterNum = Number(iterNumber)+1;
|
let iterNum = Number(iterNumber)+1;
|
||||||
|
|
||||||
// Convert line breaks into br
|
// Convert line breaks into br
|
||||||
newcontent = newcontent.replace(/\n/g, '<br>').trim();
|
newcontent = newcontent.replace(/\n/g, '<br>').trim(); //.replace(/\r\n|\r|\n/g,"</br>")
|
||||||
|
|
||||||
const contentSHA256Hash = Crypto.SHA256(newcontent);
|
const contentSHA256Hash = Crypto.SHA256(newcontent);
|
||||||
|
|
||||||
@ -9765,8 +10048,6 @@ Bitcoin.Util = {
|
|||||||
}
|
}
|
||||||
general_data_obj.sign = floCrypto.signData(JSON.stringify(general_data_obj), myPrivKey);
|
general_data_obj.sign = floCrypto.signData(JSON.stringify(general_data_obj), myPrivKey);
|
||||||
|
|
||||||
console.info("one");
|
|
||||||
|
|
||||||
floCloudAPI.sendGeneralData(general_data_obj,this.CONTENT_TYPE,{receiverID:floGlobals.adminID, senderIDs:[myFloID]});
|
floCloudAPI.sendGeneralData(general_data_obj,this.CONTENT_TYPE,{receiverID:floGlobals.adminID, senderIDs:[myFloID]});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9778,9 +10059,9 @@ Bitcoin.Util = {
|
|||||||
return e.target || e.srcElement;
|
return e.target || e.srcElement;
|
||||||
},
|
},
|
||||||
|
|
||||||
edit_onfocuout: function(event) {
|
edit_onfocuout: function(parent) {
|
||||||
if(floGlobals.subAdmins.includes(myFloID)) return;
|
if(floGlobals.subAdmins.includes(myFloID)) return;
|
||||||
let target = this.getEventTarget(event);
|
let target = parent.firstElementChild;
|
||||||
const updated_content = target.innerText.trim();
|
const updated_content = target.innerText.trim();
|
||||||
const updated_content_hash = Crypto.SHA256(updated_content);
|
const updated_content_hash = Crypto.SHA256(updated_content);
|
||||||
let editable_div = document.getElementsByClassName('content_div');
|
let editable_div = document.getElementsByClassName('content_div');
|
||||||
@ -9792,6 +10073,7 @@ Bitcoin.Util = {
|
|||||||
if(separate_data.length!==2) return;
|
if(separate_data.length!==2) return;
|
||||||
|
|
||||||
cloudArticleApp.addArticleContent(separate_data[0].trim(), separate_data[1].trim(), updated_content, myFloID);
|
cloudArticleApp.addArticleContent(separate_data[0].trim(), separate_data[1].trim(), updated_content, myFloID);
|
||||||
|
buttonVisibility('hide', parent)
|
||||||
},
|
},
|
||||||
|
|
||||||
upgrade_article: function(event) {
|
upgrade_article: function(event) {
|
||||||
@ -9815,20 +10097,116 @@ Bitcoin.Util = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
register_content_to_export: function(event) {
|
||||||
|
let target = cloudArticleApp.getEventTarget(event),
|
||||||
|
article_id = target.id.substring(4),
|
||||||
|
parent_heading_id = target.closest('.gallery-container').previousElementSibling.id,
|
||||||
|
options = document.getElementById('context_menu'),
|
||||||
|
top = target.getBoundingClientRect().top,
|
||||||
|
left = target.getBoundingClientRect().left;
|
||||||
|
|
||||||
|
if(typeof cloudArticleApp.export_file_object[parent_heading_id]!=="object") {
|
||||||
|
this.register_heading_to_export(parent_heading_id);
|
||||||
|
}
|
||||||
|
if(JSON.stringify(cloudArticleApp.export_file_object[parent_heading_id].contents).search(article_id)>=0) return;
|
||||||
|
const rank = Number(Object.keys(cloudArticleApp.export_file_object[parent_heading_id].contents))+1;
|
||||||
|
cloudArticleApp.export_file_object[parent_heading_id].contents[rank] = {
|
||||||
|
article_id: article_id,
|
||||||
|
rank: rank
|
||||||
|
}
|
||||||
|
console.log(cloudArticleApp.export_file_object)
|
||||||
|
target.classList.add("snippet-selected");
|
||||||
|
target.textContent= 'Selected';
|
||||||
|
options.classList.remove('hide')
|
||||||
|
let y = document.addEventListener("touchend", function(event) {
|
||||||
|
if (event.target.closest('#context_menu') || event.target.closest('.select-for-export')) return;
|
||||||
|
options.classList.add('hide')
|
||||||
|
document.removeEventListener('click', y);
|
||||||
|
});
|
||||||
|
if(window.innerWidth > 640){
|
||||||
|
document.querySelectorAll('.export-options').forEach((option) => {
|
||||||
|
option.classList.remove('hide-completely')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(top > window.innerHeight - 100)
|
||||||
|
options.setAttribute('style', `transform: translate(${left}px, ${top-160}px)`)
|
||||||
|
else
|
||||||
|
options.setAttribute('style', `transform: translate(${left}px, ${top}px)`)
|
||||||
|
},
|
||||||
|
|
||||||
|
register_heading_to_export: function(heading_id="") {
|
||||||
|
if(heading_id.length<1 || typeof cloudArticleApp.export_file_object[heading_id]==="object") return;
|
||||||
|
|
||||||
|
cloudArticleApp.export_file_object[heading_id] = {
|
||||||
|
title: document.getElementById(heading_id).innerText,
|
||||||
|
rank: Object.keys(cloudArticleApp.export_file_object).length+1,
|
||||||
|
contents: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
export_as_file: function(e) {
|
||||||
|
const headings = Object.values(cloudArticleApp.export_file_object).sort((a,b)=>a.rank<b.rank);
|
||||||
|
|
||||||
|
let t = ``;
|
||||||
|
|
||||||
|
for(textContent of headings) {
|
||||||
|
let snippets = Object.values(textContent.contents).sort((c,d)=>c.rank<d.rank);
|
||||||
|
t += `<h4>${textContent.title}</h4>`;
|
||||||
|
for(snips of snippets) {
|
||||||
|
if(typeof snips!=="object") continue;
|
||||||
|
t += '<p>' +document.getElementById(snips.article_id).innerText+'</p>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let file_name = "content_collaboration"+new Date().getTime();
|
||||||
|
|
||||||
|
this.downloadInnerHtml(file_name, t, 'text/html');
|
||||||
|
document.getElementById('context_menu').classList.add('hide')
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// https://stackoverflow.com/a/22085875/5348972
|
||||||
|
downloadInnerHtml: function(filename, elHtml, mimeType) {
|
||||||
|
if (navigator.msSaveBlob) { // IE 10+
|
||||||
|
navigator.msSaveBlob(new Blob([elHtml], { type: mimeType + ';charset=utf-8;' }), filename);
|
||||||
|
} else {
|
||||||
|
var link = document.createElement('a');
|
||||||
|
mimeType = mimeType || 'text/plain';
|
||||||
|
|
||||||
|
link.setAttribute('download', filename);
|
||||||
|
link.setAttribute('href', 'data:' + mimeType + ';charset=utf-8,' + encodeURIComponent(elHtml));
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
cloudArticleApp.export_file_object = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
reset_export_list: function() {
|
||||||
|
cloudArticleApp.export_file_object = {};
|
||||||
|
document.querySelectorAll('.snippet-selected').forEach((cl) =>{
|
||||||
|
cl.textContent= 'Select';
|
||||||
|
cl.classList.remove("snippet-selected");
|
||||||
|
})
|
||||||
|
document.getElementById('context_menu').classList.add('hide')
|
||||||
|
document.querySelectorAll('.export-options').forEach((option) => {
|
||||||
|
option.classList.add('hide-completely')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
logout: function() {
|
||||||
|
if(confirm("Do you want to logout?")){
|
||||||
|
floDapps.clearCredentials()
|
||||||
|
compactIDB.deleteDB().then((message) => {
|
||||||
|
console.log(message)
|
||||||
|
onLoadStartUp()
|
||||||
|
alert('You have logged out successfully.')
|
||||||
|
}).catch((error) => {
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
|
||||||
(function() {
|
|
||||||
const reset_data_btn = document.getElementById('reset_data_btn');
|
|
||||||
reset_data_btn.onclick = function() {
|
|
||||||
cloudArticleApp.resetArticleContent();
|
|
||||||
hidePopup('edit_article')
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue
Block a user