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