UI Behaviour updates

1. Added new notification popup
2. Removed unnecessarily showing reload dialouge
3. Added default section titles when creating articles
This commit is contained in:
Vivek Teega 2020-09-26 12:10:22 +05:30
parent 27770a8ed7
commit 50b33ff153
2 changed files with 3337 additions and 69 deletions

3229
components.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -35,12 +35,13 @@
} }
body { body {
--primary-color: #00fa9a; --accent-color: #00fa9a;
--light-shade: #222; --light-shade: #222;
--background: #111; --background-color: #111;
--text: 238, 238, 238; --foreground-color: 32,32,32;
--text-color: 238, 238, 238;
font-size: 16px; font-size: 16px;
background: var(--background); background: var(--background-color);
} }
* { * {
@ -92,7 +93,7 @@
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
background: transparent; background: transparent;
color: var(--primary-color); color: var(--accent-color);
padding: 0.6rem 1rem; padding: 0.6rem 1rem;
border: none; border: none;
-webkit-transition: background 0.3s ease; -webkit-transition: background 0.3s ease;
@ -125,12 +126,12 @@
button[disabled] { button[disabled] {
opacity: 0.5 !important; opacity: 0.5 !important;
cursor: default; cursor: default;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
} }
textarea { textarea {
background: var(--light-shade); background: var(--light-shade);
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
padding: 1.5rem; padding: 1.5rem;
max-width: 100%; max-width: 100%;
font-size: 1rem; font-size: 1rem;
@ -148,7 +149,7 @@
border-radius: 0.2rem; border-radius: 0.2rem;
margin: 1rem 0; margin: 1rem 0;
background: #181818; background: #181818;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
font-size: 1rem !important; font-size: 1rem !important;
} }
@ -181,7 +182,7 @@
margin: 1rem; margin: 1rem;
font-size: 1rem; font-size: 1rem;
font-weight: 500; font-weight: 500;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
} }
#confirmation div { #confirmation div {
@ -198,7 +199,7 @@
height: 1rem; height: 1rem;
width: 1rem; width: 1rem;
fill: none; fill: none;
stroke: var(--primary-color); stroke: var(--accent-color);
stroke-width: 6; stroke-width: 6;
overflow: visible; overflow: visible;
stroke-linecap: round; stroke-linecap: round;
@ -300,13 +301,13 @@
transition: transform 0.3s, -webkit-transform 0.3s; transition: transform 0.3s, -webkit-transform 0.3s;
-webkit-box-shadow: 0 2rem 2rem rgba(0, 0, 0, 0.24); -webkit-box-shadow: 0 2rem 2rem rgba(0, 0, 0, 0.24);
box-shadow: 0 2rem 2rem rgba(0, 0, 0, 0.24); box-shadow: 0 2rem 2rem rgba(0, 0, 0, 0.24);
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
overflow-y: auto; overflow-y: auto;
max-height: 100%; max-height: 100vh;
} }
.solid-background { .solid-background {
background: var(--background); background: var(--background-color);
} }
#context_menu { #context_menu {
@ -329,8 +330,8 @@
} }
.section-title h2 { .section-title h2 {
color: var(--background); color: var(--background-color);
background: var(--primary-color); background: var(--accent-color);
padding: 0.5rem; padding: 0.5rem;
margin: 0; margin: 0;
} }
@ -339,7 +340,7 @@
padding: 0.2rem 0; padding: 0.2rem 0;
margin: 1rem 0; margin: 1rem 0;
font-size: 1.2rem; font-size: 1.2rem;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
font-weight: 500; font-weight: 500;
line-height: 1.5; line-height: 1.5;
} }
@ -398,7 +399,7 @@
.heading>.icon:first-of-type { .heading>.icon:first-of-type {
margin-right: 1rem; margin-right: 1rem;
cursor: pointer; cursor: pointer;
stroke: rgba(var(--text), 1); stroke: rgba(var(--text-color), 1);
} }
.gallery-container { .gallery-container {
@ -457,7 +458,7 @@
scroll-snap-align: start; scroll-snap-align: start;
min-width: 30%; min-width: 30%;
background-color: #222; background-color: #222;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
margin: 0 1rem 1rem 0; margin: 0 1rem 1rem 0;
border-radius: 0.2rem; border-radius: 0.2rem;
} }
@ -524,7 +525,7 @@
-webkit-box-align: center; -webkit-box-align: center;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
color: var(--primary-color); color: var(--accent-color);
cursor: pointer; cursor: pointer;
} }
@ -533,11 +534,11 @@
} }
.article-body .card-footer h5:nth-of-type(2):hover svg { .article-body .card-footer h5:nth-of-type(2):hover svg {
fill: var(--primary-color); fill: var(--accent-color);
} }
.article-body .card-footer h5 svg { .article-body .card-footer h5 svg {
stroke: var(--primary-color); stroke: var(--accent-color);
width: 1.2rem; width: 1.2rem;
margin-right: 0.5rem; margin-right: 0.5rem;
} }
@ -562,7 +563,7 @@
} }
.snippet-selected { .snippet-selected {
outline: 1px solid var(--primary-color); outline: 1px solid var(--accent-color);
} }
.no-transformations { .no-transformations {
@ -571,17 +572,17 @@
} }
:-webkit-any-link { :-webkit-any-link {
color: var(--primary-color); color: var(--accent-color);
text-decoration: none; text-decoration: none;
} }
:-moz-any-link { :-moz-any-link {
color: var(--primary-color); color: var(--accent-color);
text-decoration: none; text-decoration: none;
} }
:any-link { :any-link {
color: var(--primary-color); color: var(--accent-color);
text-decoration: none; text-decoration: none;
} }
@ -601,7 +602,7 @@
} }
#sign_in .icon { #sign_in .icon {
stroke: rgba(var(--text), 1); stroke: rgba(var(--text-color), 1);
} }
#sign_in h2 { #sign_in h2 {
@ -612,13 +613,13 @@
#sign_in p:first-of-type { #sign_in p:first-of-type {
margin-bottom: 4rem; margin-bottom: 4rem;
z-index: 3; z-index: 3;
color: rgba(var(--text), 0.8); color: rgba(var(--text-color), 0.8);
} }
#sign_in .back-btn { #sign_in .back-btn {
margin-bottom: 1rem; margin-bottom: 1rem;
padding-left: 0; padding-left: 0;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
} }
#sign_in div:first-of-type { #sign_in div:first-of-type {
@ -652,16 +653,16 @@
flex-direction: column; flex-direction: column;
margin: 0.5rem; margin: 0.5rem;
width: 8rem; width: 8rem;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
background: rgba(var(--foreground), 1); background: rgba(var(--foreground), 1);
} }
#sign_in div:first-of-type button:hover { #sign_in div:first-of-type button:hover {
color: var(--primary-color); color: var(--accent-color);
} }
#sign_in div:first-of-type button:hover .icon { #sign_in div:first-of-type button:hover .icon {
stroke: var(--primary-color); stroke: var(--accent-color);
} }
#sign_in #priv_key_sign_in { #sign_in #priv_key_sign_in {
@ -692,7 +693,7 @@
#sign_in #priv_key_sign_in button { #sign_in #priv_key_sign_in button {
margin: 1rem 0 2rem 0; margin: 1rem 0 2rem 0;
width: 100%; width: 100%;
background: rgba(var(--text), 0.1); background: rgba(var(--text-color), 0.1);
-webkit-box-pack: center; -webkit-box-pack: center;
-ms-flex-pack: center; -ms-flex-pack: center;
justify-content: center; justify-content: center;
@ -711,7 +712,7 @@
-webkit-box-align: center; -webkit-box-align: center;
-ms-flex-align: center; -ms-flex-align: center;
align-items: center; align-items: center;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
background: #222; background: #222;
padding: 1rem; padding: 1rem;
z-index: 2; z-index: 2;
@ -751,7 +752,7 @@
height: 100vh; height: 100vh;
width: 100vw; width: 100vw;
top: 0; top: 0;
background: var(--background); background: var(--background-color);
-webkit-transition: opacity 0.6s ease; -webkit-transition: opacity 0.6s ease;
transition: opacity 0.6s ease; transition: opacity 0.6s ease;
display: -ms-grid; display: -ms-grid;
@ -773,7 +774,7 @@
#loader_container h4 { #loader_container h4 {
font-weight: normal; font-weight: normal;
color: rgba(var(--text), 1); color: rgba(var(--text-color), 1);
} }
#loader_container button { #loader_container button {
@ -874,6 +875,16 @@
outline: none; outline: none;
} }
#article_list_div {
width: 36rem;
height: 80vh;
}
#article_list_div sm-select{
margin-top: 1.5rem;
}
@media screen and (min-width: 640px) { @media screen and (min-width: 640px) {
#sign_in { #sign_in {
width: 24rem; width: 24rem;
@ -1017,9 +1028,13 @@
/*# sourceMappingURL=main.css.map */ /*# sourceMappingURL=main.css.map */
</style> </style>
<script src="components.js"></script>
</head> </head>
<body onload="onLoadStartUp()"> <body onload="onLoadStartUp()">
<sm-notifications id="sm-notifications"></sm-notifications>
<div class="popup-container hide"> <div class="popup-container hide">
<div id="confirmation" class="popup"> <div id="confirmation" class="popup">
<p></p> <p></p>
@ -1097,7 +1112,7 @@
Export as file</button> Export as file</button>
</div> </div>
<div class="floating-btn"> <div class="floating-btn">
<button onclick="cloudArticleApp.retrieveLatestContent()"> <button onclick="cloudArticleApp.retrieveLatestContent(true)">
<svg class="icon" viewBox="0 0 64 64"> <svg class="icon" viewBox="0 0 64 64">
<title>refresh</title> <title>refresh</title>
<path d="M60.94,43.13A30.87,30.87,0,1,1,59,17.93" /> <path d="M60.94,43.13A30.87,30.87,0,1,1,59,17.93" />
@ -1146,7 +1161,7 @@
</span> </span>
<div class="spacer"></div> <div class="spacer"></div>
<button id="refresh_btn" title="Refresh the content" class="hide-on-mobile" <button id="refresh_btn" title="Refresh the content" class="hide-on-mobile"
onclick="cloudArticleApp.retrieveLatestContent()"> onclick="cloudArticleApp.retrieveLatestContent(true)">
<svg class="icon" viewBox="0 0 64 64"> <svg class="icon" viewBox="0 0 64 64">
<title>refresh</title> <title>refresh</title>
<path d="M60.94,43.13A30.87,30.87,0,1,1,59,17.93" /> <path d="M60.94,43.13A30.87,30.87,0,1,1,59,17.93" />
@ -1457,6 +1472,8 @@
} }
} }
function showLoader() { function showLoader() {
console.trace('show loader trace')
debugger
let spinner = document.getElementById('loader_container'); let spinner = document.getElementById('loader_container');
spinner.firstElementChild.classList.add('pulse'); spinner.firstElementChild.classList.add('pulse');
spinner.classList.remove('hide'); spinner.classList.remove('hide');
@ -1472,15 +1489,15 @@
let article_list = ``; let article_list = ``;
let articles = floGlobals.appObjects["ContentCollaboration"]["ArticleLists"] let articles = floGlobals.appObjects["ContentCollaboration"]["ArticleLists"]
for (let a in articles) for (let a in articles)
article_list += `<option value="${a}">${articles[a]}</option>`; article_list += `<sm-option value="${a}">${articles[a]}</sm-option>`;
let userdivui = `<section class="popup-container hide"> let userdivui = `<section class="popup-container hide">
<div id="article_list_div" class="popup"> <div id="article_list_div" class="popup">
<h3>Select an Article</h3> <h3>Select an Article</h3>
<select id="article_list"> <sm-select id="article_list">
${article_list} ${article_list}
</select> </sm-select>
<button id="clear_local_default">Cancel</button> <button id="clear_local_default">Cancel</button>
<button id="select_article_btn">View</button> <button id="select_article_btn">View</button>
@ -1499,7 +1516,7 @@
document.getElementById('select_article_btn').onclick = function () { document.getElementById('select_article_btn').onclick = function () {
let article_id = document.getElementById("article_list").value; let article_id = document.getElementById("article_list").value;
cloudArticleApp.setLocalDefault(article_id); cloudArticleApp.setLocalDefault(article_id);
cloudArticleApp.retrieveLatestContent(); cloudArticleApp.retrieveLatestContent(true);
hidePopup() hidePopup()
} }
@ -9559,6 +9576,7 @@
//Request data from supernode //Request data from supernode
requestData: function (request, floID) { requestData: function (request, floID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
debugger
this.kBucket.determineClosestSupernode(floID).then(closestNode => { this.kBucket.determineClosestSupernode(floID).then(closestNode => {
this.requestDataFromSN(request, closestNode[0]) this.requestDataFromSN(request, closestNode[0])
.then(result => resolve(result)) .then(result => resolve(result))
@ -10296,6 +10314,7 @@
//request an object data from supernode cloud //request an object data from supernode cloud
requestObjectData: function (objectName, options = {}) { requestObjectData: function (objectName, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
debugger
var request = { var request = {
receiverID: options.receiverID || floGlobals.adminID, receiverID: options.receiverID || floGlobals.adminID,
senderIDs: (options.senderIDs === false) ? false : options.senderIDs || senderIDs: (options.senderIDs === false) ? false : options.senderIDs ||
@ -10754,7 +10773,7 @@
console.log(`Welcome FLO_ID: ${myFloID}`) console.log(`Welcome FLO_ID: ${myFloID}`)
//App functions.... //App functions....
cloudArticleApp.refreshMasterObject().then(result => { cloudArticleApp.refreshMasterObject().then(result => {
cloudArticleApp.retrieveLatestContent(); cloudArticleApp.retrieveLatestContent(true);
buildAdminUI(); buildAdminUI();
}).catch(error => console.error(error)) }).catch(error => console.error(error))
}).catch(error => console.error(error)) }).catch(error => console.error(error))
@ -11003,6 +11022,10 @@
const Topic = Object.keys(floGlobals.appObjects[this.SUBJECT])[0]; const Topic = Object.keys(floGlobals.appObjects[this.SUBJECT])[0];
sec_items.forEach((y, i) => { sec_items.forEach((y, i) => {
i++; i++;
if(y.value.length < 1){
alert('Section name cannot be empty. Please fill them up')
throw new Error('Section name cannot be empty. Please fill them up')
}
floGlobals.appObjects[this.SUBJECT][Topic].data[`section${i}`].section_details.section_name = y.value; floGlobals.appObjects[this.SUBJECT][Topic].data[`section${i}`].section_details.section_name = y.value;
}); });
@ -11016,14 +11039,19 @@
hidePopup() hidePopup()
}, },
retrieveLatestContent: async function (receiverID = floGlobals.adminID, senderIDs = floGlobals.subAdmins) { retrieveLatestContent: async function (loader=false, receiverID = floGlobals.adminID, senderIDs = floGlobals.subAdmins) {
showLoader() console.trace('Inside retrieveLatestContent')
showMessage('Loading the latest content') if(loader == true){
showLoader()
showMessage('Loading the latest content')
}
await floCloudAPI.requestObjectData(this.SUBJECT, { receiverID, senderIDs }); await floCloudAPI.requestObjectData(this.SUBJECT, { receiverID, senderIDs });
await floCloudAPI.requestGeneralData(this.SUBJECT); await floCloudAPI.requestGeneralData(this.SUBJECT);
document.getElementById('current_data').innerHTML = ''; document.getElementById('current_data').innerHTML = '';
cloudArticleApp.showFullContentOfArticle(floGlobals.appObjects[cloudArticleApp.SUBJECT]); cloudArticleApp.showFullContentOfArticle(floGlobals.appObjects[cloudArticleApp.SUBJECT]);
hideLoader() if(loader == true){
hideLoader()
}
}, },
createNewArticle: async function () { createNewArticle: async function () {
@ -11055,7 +11083,7 @@
section_iters: {}, section_iters: {},
}; };
new_article[article_name].data[`section${i}`]["section_details"] = { new_article[article_name].data[`section${i}`]["section_details"] = {
section_name: "" section_name: `Section ${j+1}`
}; };
new_article[article_name].data[`section${i}`]["section_iters"]["iteration0"] = { new_article[article_name].data[`section${i}`]["section_iters"]["iteration0"] = {
content: "", content: "",
@ -11094,7 +11122,7 @@
this.setLocalDefault(article_id) this.setLocalDefault(article_id)
await this.retrieveLatestContent(); await this.retrieveLatestContent(true);
}, },
addSections: async function (sections) { addSections: async function (sections) {
@ -11141,7 +11169,10 @@
addArticleContent: async function (article_name = "", section = "", newcontent = "", content_creator = "", score = 0, vectorClock = "") { addArticleContent: async function (article_name = "", section = "", newcontent = "", content_creator = "", score = 0, vectorClock = "") {
let notifications = document.getElementById("sm-notifications");
await this.retrieveLatestContent(); await this.retrieveLatestContent();
//let full_data = JSON.parse(JSON.stringify(floGlobals.appObjects[this.SUBJECT])); //let full_data = JSON.parse(JSON.stringify(floGlobals.appObjects[this.SUBJECT]));
let article = floGlobals.appObjects[this.SUBJECT][article_name]; let article = floGlobals.appObjects[this.SUBJECT][article_name];
@ -11168,12 +11199,14 @@
const contentSHA256Hash = Crypto.SHA256(newcontent); const contentSHA256Hash = Crypto.SHA256(newcontent);
// Reject if this hash is already present in db if(floGlobals.subAdmins.includes(floGlobals.myFloID)){
if (JSON.stringify(article).includes(contentSHA256Hash)) return false; // Reject if this hash is already present in db
if (JSON.stringify(article).includes(contentSHA256Hash)) return false;
// Reject if duplicate content is being submitted && which is not yet registered in floGlobals.appObjects[this.SUBJECT] // Reject if duplicate content is being submitted && which is not yet registered in floGlobals.appObjects[this.SUBJECT]
if (cloudArticleApp.todaysContenthashList.includes(contentSHA256Hash)) return false; if (cloudArticleApp.todaysContenthashList.includes(contentSHA256Hash)) return false;
cloudArticleApp.todaysContenthashList.push(contentSHA256Hash); cloudArticleApp.todaysContenthashList.push(contentSHA256Hash);
}
const new_content_object = { const new_content_object = {
article_name: article_name, article_name: article_name,
@ -11190,7 +11223,9 @@
article.data[section]["section_iters"][`iteration${iterNum}`] = new_content_object; article.data[section]["section_iters"][`iteration${iterNum}`] = new_content_object;
showMessage(`Adding new iteration to article ${article_name}`); //showMessage(`Adding new iteration to article ${article_name}`);
// todo - add updating score notification
notifications.push('Updating score')
if (floGlobals.subAdmins.includes(myFloID)) { if (floGlobals.subAdmins.includes(myFloID)) {
floCloudAPI.updateObjectData(this.SUBJECT); floCloudAPI.updateObjectData(this.SUBJECT);
@ -11210,7 +11245,8 @@
floCloudAPI.sendGeneralData(general_data_obj, this.SUBJECT); floCloudAPI.sendGeneralData(general_data_obj, this.SUBJECT);
} }
this.retrieveLatestContent(); await this.retrieveLatestContent();
// todo - Add updated score notification
}, },
getEventTarget: function (e) { getEventTarget: function (e) {
@ -11237,20 +11273,23 @@
}, },
upgrade_article: function (event) { upgrade_article: function (event) {
let new_score = prompt("Enter Score: ", 0); if(floGlobals.subAdmins.includes(myFloID)){
new_score = Number(new_score);
if (typeof new_score !== "number" || new_score <= 0) return; let new_score = prompt("Enter Score: ", 0);
let target = cloudArticleApp.getEventTarget(event); new_score = Number(new_score);
let article_vc = target.id.substr(6); if (typeof new_score !== "number" || new_score <= 0) return;
let contents = floGlobals.appObjects[this.SUBJECT]; let target = cloudArticleApp.getEventTarget(event);
for (title of Object.keys(contents)) { let article_vc = target.id.substr(6);
for (sections of Object.keys(contents[title].data)) { let contents = floGlobals.appObjects[this.SUBJECT];
for (iters of Object.values(contents[title].data[sections].section_iters)) { for (title of Object.keys(contents)) {
if (typeof iters.vectorClock === "string" for (sections of Object.keys(contents[title].data)) {
&& iters.vectorClock == article_vc) { for (iters of Object.values(contents[title].data[sections].section_iters)) {
cloudArticleApp.addArticleContent(title, sections, iters.content, if (typeof iters.vectorClock === "string"
iters.content_creator, new_score, article_vc); && iters.vectorClock == article_vc) {
break; cloudArticleApp.addArticleContent(title, sections, iters.content,
iters.content_creator, new_score, article_vc);
break;
}
} }
} }
} }