From 06ea2a6aa71373582343d82c996c2aec5a1d3c2b Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Tue, 11 Mar 2025 04:13:32 +0300 Subject: [PATCH 1/9] fix(suggestions list): refactor suggestions sorting backlog and in progress suggestions should be printed first then print the completed suggestions --- widget/js/pages/home/index.js | 17 ++++------------- widget/js/state.js | 2 +- widget/js/widget.controller.js | 31 +++++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/widget/js/pages/home/index.js b/widget/js/pages/home/index.js index 6547e40..7965e3d 100644 --- a/widget/js/pages/home/index.js +++ b/widget/js/pages/home/index.js @@ -68,7 +68,7 @@ const homePage = { suggestionTitle.innerHTML = suggestion.title; suggestionBodyText.innerHTML = suggestion.suggestion; widgetPagesShared.validateSuggestionImage(suggestionBodyText); - suggestionVotesCount.innerHTML = `${Object.keys(suggestion.upVotedBy).length}`; + suggestionVotesCount.innerHTML = `${Object.keys(suggestion.upVotedBy).length}`; if (!state.settings.enableComments) { suggestionCommentContainer.classList.add('hidden'); @@ -223,20 +223,11 @@ const homePage = { }); if (suggestions.length < state.pageSize) { - if (state.currentStatusSearch === SUGGESTION_STATUS.COMPLETED) { + if (state.isAllNotCompletedSuggestionFetched) { state.isAllSuggestionFetched = true; if (!state.suggestionsList.length) this.printEmptyState(); - } else if (state.currentStatusSearch === SUGGESTION_STATUS.INPROGRESS) { - state.currentStatusSearch = SUGGESTION_STATUS.COMPLETED; - state.page = 0; - - widgetController.getSuggestions().then((suggestions) => { - this.handleSuggestionPage(suggestions) - }).catch((err) => { - console.error(err); - }); } else { - state.currentStatusSearch = SUGGESTION_STATUS.INPROGRESS; + state.isAllNotCompletedSuggestionFetched = true; state.page = 0; widgetController.getSuggestions().then((suggestions) => { @@ -251,7 +242,7 @@ const homePage = { init() { this.initSelectors(); - widgetController.getSuggestions().then((suggestions) => { + widgetController.getFirstSuggestionsPage().then((suggestions) => { setTimeout(() => { this.destroySkeleton(); diff --git a/widget/js/state.js b/widget/js/state.js index d5de98c..4a16d0c 100644 --- a/widget/js/state.js +++ b/widget/js/state.js @@ -51,9 +51,9 @@ const state = { settings: new Setting(), page: 0, pageSize: 50, - currentStatusSearch: SUGGESTION_STATUS.BACKLOG, fetching: false, isAllSuggestionFetched: false, + isAllNotCompletedSuggestionFetched: false, validUserImages: {}, suggestionsList: [], updatedUsersData: [], diff --git a/widget/js/widget.controller.js b/widget/js/widget.controller.js index 4fb2dcb..4c24806 100644 --- a/widget/js/widget.controller.js +++ b/widget/js/widget.controller.js @@ -53,15 +53,17 @@ const widgetController = { getSuggestions() { return new Promise((resolve) => { - const { page, pageSize, settings, currentStatusSearch } = state; + const { page, pageSize, settings, isAllNotCompletedSuggestionFetched } = state; const searchOptions = { page, pageSize }; let $match = { "_buildfire.index.string1": { $exists: false } }, $sort = {}; - if (currentStatusSearch === SUGGESTION_STATUS.COMPLETED) { + if (isAllNotCompletedSuggestionFetched) { + // hide completed immediately if (settings.hideCompletedItems === 0) return resolve([]); + // hide completed after a certain period if (settings.hideCompletedItems > 0) { const startDate = new Date(); startDate.setDate(startDate.getDate() - settings.hideCompletedItems); @@ -71,10 +73,14 @@ const widgetController = { { modifiedOn: { $gte: startDate } } ]; } else { - $match.status = { $eq: currentStatusSearch }; + // never hide the completed items + $match.status = { $eq: SUGGESTION_STATUS.COMPLETED }; } } else { - $match.status = { $eq: currentStatusSearch }; + $match['$or'] = [ + { status: SUGGESTION_STATUS.BACKLOG }, + { status: SUGGESTION_STATUS.INPROGRESS }, + ]; } switch (settings.defaultItemSorting) { @@ -124,6 +130,23 @@ const widgetController = { }); }, + getFirstSuggestionsPage() { + return new Promise((resolve, reject) => { + this.getSuggestions().then((suggestions) => { + if (suggestions.length >= 10) { + resolve(suggestions); + } else { + state.isAllNotCompletedSuggestionFetched = true; + state.page = 0; + + this.getSuggestions().then(() => { + resolve(state.suggestionsList); + }); + } + }) + }) + }, + getSuggestionById(suggestionId) { return new Promise((resolve, reject) => { Suggestions.getById(suggestionId).then((suggestion) => { From f6a1050c49aecc4b953a33b17b90350de7435b49 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Tue, 11 Mar 2025 04:25:56 +0300 Subject: [PATCH 2/9] feat(suggestions list): refactor suggestion vote icons revert suggestion icon to use the old arrow up --- widget/index.html | 12 ++++++------ widget/js/pages/home/index.js | 7 ++++++- widget/js/pages/suggestion/index.js | 7 ++++++- widget/js/pages/widgetPagesShared.js | 8 ++++---- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/widget/index.html b/widget/index.html index 8a7baad..9fb7262 100755 --- a/widget/index.html +++ b/widget/index.html @@ -93,11 +93,11 @@

- +

@@ -129,11 +129,11 @@

- +

diff --git a/widget/js/pages/home/index.js b/widget/js/pages/home/index.js index 7965e3d..0236b17 100644 --- a/widget/js/pages/home/index.js +++ b/widget/js/pages/home/index.js @@ -68,7 +68,7 @@ const homePage = { suggestionTitle.innerHTML = suggestion.title; suggestionBodyText.innerHTML = suggestion.suggestion; widgetPagesShared.validateSuggestionImage(suggestionBodyText); - suggestionVotesCount.innerHTML = `${Object.keys(suggestion.upVotedBy).length}`; + let suggestionVotesCountClasses = 'margin--0'; if (!state.settings.enableComments) { suggestionCommentContainer.classList.add('hidden'); @@ -76,11 +76,16 @@ const homePage = { if (authManager.currentUser && suggestion.upVotedBy && suggestion.upVotedBy[authManager.currentUser.userId]) { upvote_icon.className = 'padding-zero margin--zero iconsTheme material-icons'; + suggestionVotesCountClasses += ' iconsTheme' + } else { + suggestionVotesCountClasses += ' bodyTextTheme' } if (suggestion.status === SUGGESTION_STATUS.COMPLETED) { upvote_icon.classList.add('disabled'); } + suggestionVotesCount.innerHTML = `${Object.keys(suggestion.upVotedBy).length}`; + suggestionCommentContainer.onclick = () => widgetPagesShared.navigateToSuggestionComments(suggestion); upvote_icon.onclick = () => widgetPagesShared.voteToSuggestion(suggestion); suggestionStatus.onclick = () => widgetPagesShared.updateSuggestionStatus(suggestion); diff --git a/widget/js/pages/suggestion/index.js b/widget/js/pages/suggestion/index.js index d2360fc..0b0f821 100644 --- a/widget/js/pages/suggestion/index.js +++ b/widget/js/pages/suggestion/index.js @@ -50,7 +50,7 @@ const suggestionDetailsPage = { suggestionTitle.innerHTML = state.activeSuggestion.title; suggestionBodyText.innerHTML = state.activeSuggestion.suggestion; widgetPagesShared.validateSuggestionImage(suggestionBodyText); - suggestionVotesCount.innerHTML = `${Object.keys(state.activeSuggestion.upVotedBy).length}`; + let suggestionVotesCountClasses = 'margin--0'; if (!state.settings.enableComments) { suggestionCommentContainer.classList.add('hidden'); @@ -58,11 +58,16 @@ const suggestionDetailsPage = { if (authManager.currentUser && state.activeSuggestion.upVotedBy && state.activeSuggestion.upVotedBy[authManager.currentUser.userId]) { upvote_icon.className = 'padding-zero margin--zero iconsTheme material-icons'; + suggestionVotesCountClasses += ' iconsTheme' + } else { + suggestionVotesCountClasses += ' bodyTextTheme' } if (state.activeSuggestion.status === SUGGESTION_STATUS.COMPLETED) { upvote_icon.classList.add('disabled'); } + suggestionVotesCount.innerHTML = `${Object.keys(state.activeSuggestion.upVotedBy).length}`; + suggestionCommentContainer.onclick = () => widgetPagesShared.navigateToSuggestionComments(state.activeSuggestion); upvote_icon.onclick = () => widgetPagesShared.voteToSuggestion(state.activeSuggestion); suggestionStatus.onclick = () => widgetPagesShared.updateSuggestionStatus(state.activeSuggestion); diff --git a/widget/js/pages/widgetPagesShared.js b/widget/js/pages/widgetPagesShared.js index 3c9e6a0..af7ebb2 100644 --- a/widget/js/pages/widgetPagesShared.js +++ b/widget/js/pages/widgetPagesShared.js @@ -256,11 +256,11 @@ const widgetPagesShared = { }).then((isConfirmed) => { if (isConfirmed) { widgetController.handleSuggestionUnVote(suggestion).then((updatedSuggestion) => { - if (upvote_icon) upvote_icon.className = 'padding-zero margin--zero iconsTheme material-icons-outlined'; - if (suggestionVotesCount) suggestionVotesCount.innerHTML = `${Object.keys(updatedSuggestion.upVotedBy).length}`; + if (upvote_icon) upvote_icon.className = 'padding-zero margin--zero bodyTextTheme material-icons'; + if (suggestionVotesCount) suggestionVotesCount.innerHTML = `${Object.keys(updatedSuggestion.upVotedBy).length}`; - if (detailsVoteIcon) detailsVoteIcon.className = 'padding-zero margin--zero iconsTheme material-icons-outlined'; - if (detailsVotesCount) detailsVotesCount.innerHTML = `${Object.keys(updatedSuggestion.upVotedBy).length}`; + if (detailsVoteIcon) detailsVoteIcon.className = 'padding-zero margin--zero bodyTextTheme material-icons'; + if (detailsVotesCount) detailsVotesCount.innerHTML = `${Object.keys(updatedSuggestion.upVotedBy).length}`; }).catch((err) => { console.error(err); if (upvote_icon) upvote_icon.classList.remove('disabled'); From 6c6c1bcc8a2e1589fc702aa5bac5787de1695543 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 01:00:39 +0300 Subject: [PATCH 3/9] fix backward settings tag issue --- widget/js/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/js/app.js b/widget/js/app.js index a123c21..68b9cbf 100644 --- a/widget/js/app.js +++ b/widget/js/app.js @@ -15,7 +15,7 @@ const hasPermission = (permissionType) => { const permissionTags = state.settings.permissions[permissionType].tags; for (let i = 0; i < permissionTags.length; i++) { - if (userTags.some((_tag) => _tag.tagName === permissionTags[i].tagName)) { + if (userTags.some((_tag) => (_tag.tagName === permissionTags[i].tagName || _tag.tagName === permissionTags[i].value))) { userPermitted = true; break; } From b3eb60ba118dee534879671111362c19c3288e9e Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 01:22:22 +0300 Subject: [PATCH 4/9] save last updated settings info --- control/content/index.html | 1 + control/content/js/index.js | 4 +++- control/settings/index.html | 1 + control/settings/js/index.js | 4 +++- widget/global/js/repositories/Settings.js | 2 ++ 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/control/content/index.html b/control/content/index.html index dbf30c8..0afbf86 100755 --- a/control/content/index.html +++ b/control/content/index.html @@ -18,6 +18,7 @@ + diff --git a/control/content/js/index.js b/control/content/js/index.js index 0407755..38e7435 100644 --- a/control/content/js/index.js +++ b/control/content/js/index.js @@ -38,5 +38,7 @@ const contentPage = { }; window.onload = () => { - contentPage.init(); + authManager.enforceLogin().then(() => { + contentPage.init(); + }); }; diff --git a/control/settings/index.html b/control/settings/index.html index 7a38332..da36507 100644 --- a/control/settings/index.html +++ b/control/settings/index.html @@ -18,6 +18,7 @@ + diff --git a/control/settings/js/index.js b/control/settings/js/index.js index f178eb4..460f511 100644 --- a/control/settings/js/index.js +++ b/control/settings/js/index.js @@ -385,5 +385,7 @@ const settingsPage = { }; window.onload = () => { - settingsPage.init(); + authManager.enforceLogin().then(() => { + settingsPage.init(); + }); }; diff --git a/widget/global/js/repositories/Settings.js b/widget/global/js/repositories/Settings.js index 8f79720..0854fa2 100644 --- a/widget/global/js/repositories/Settings.js +++ b/widget/global/js/repositories/Settings.js @@ -17,6 +17,8 @@ class Settings { static save(settings) { return new Promise((resolve, reject) => { + settings.lastUpdatedOn = new Date(); + settings.lastUpdatedBy = authManager.currentUser.userId; buildfire.datastore.save(new Setting(settings), this.TAG, (err, res) => { if (err) { reject(err); From 9c58c2c6a7df963a239448ca595ea70bb302f470 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 01:35:28 +0300 Subject: [PATCH 5/9] set settings created by if not exists --- control/content/js/content.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control/content/js/content.controller.js b/control/content/js/content.controller.js index 6da8734..af091b4 100644 --- a/control/content/js/content.controller.js +++ b/control/content/js/content.controller.js @@ -10,7 +10,7 @@ const contentController = { Settings.get().then((result) => { if (!result || !Object.keys(result).length) { Analytics.init(); // init analytics only for the first time of installing the plugin - Settings.save(new Setting({ navigateToCwByDefault: true })).then((settings) => { + Settings.save(new Setting({ navigateToCwByDefault: true, createdBy: authManager.currentUser.userId })).then((settings) => { state.settings = new Setting(); resolve(); }).catch((err) => { // don't blok the ui, just print the error and resolve From 008e43fca5817d5b00e1acc9c7ce02f3aaa2f164 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 01:42:39 +0300 Subject: [PATCH 6/9] include tagName property in backward compatible instances --- control/settings/js/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/control/settings/js/index.js b/control/settings/js/index.js index 460f511..9f6daf7 100644 --- a/control/settings/js/index.js +++ b/control/settings/js/index.js @@ -226,7 +226,8 @@ const settingsPage = { })); this.updateDeepSettingValue(`${settingKey}.tags`, updatedTags); }; - tagsInput.set(settingValue.tags); + const tags = settingValue.tags.map(tag => ({...tag, tagName: tag.tagName ? tag.tagName : tag.value})); + tagsInput.set(tags); }, initDropdown(options) { From c0600b2e526bf5674eb736a90bea00c334592fba Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 01:46:22 +0300 Subject: [PATCH 7/9] include last updated on for the user credits --- widget/global/js/repositories/UserCredits.js | 1 + widget/js/widget.controller.js | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/widget/global/js/repositories/UserCredits.js b/widget/global/js/repositories/UserCredits.js index b59b9a0..419fa83 100644 --- a/widget/global/js/repositories/UserCredits.js +++ b/widget/global/js/repositories/UserCredits.js @@ -18,6 +18,7 @@ class UserCredits { if (!results || !results.length) { const data = new UserCredit({ userId, + createdBy: userId, }).toJSON(); this.insert(data).then((res) => { res.data.id = res.id; diff --git a/widget/js/widget.controller.js b/widget/js/widget.controller.js index 4c24806..47b27fe 100644 --- a/widget/js/widget.controller.js +++ b/widget/js/widget.controller.js @@ -244,6 +244,8 @@ const widgetController = { const payload = { $set: { credits: encryptedCredits, + lastUpdatedBy: authManager.currentUser._id, + lastUpdatedOn: new Date(), }, }; return UserCredits.update(authManager.currentUser._id, payload).then((updatedCredits) => { @@ -265,14 +267,15 @@ const widgetController = { const encryptedCredits = widgetUtils.encryptCredit(state.settings.inAppPurchase.votesPerPurchase, ENUMS.SECRET_KEY); const payload = { $set: { - createdBy: authManager.currentUser._id, + lastUpdatedBy: authManager.currentUser._id, + lastUpdatedOn: new Date(), credits: encryptedCredits, firstTimePurchase: true, }, }; UserCredits.update(authManager.currentUser._id, payload).then((updatedCredits) => { state.userCredits = { - createdBy: authManager.currentUser._id, + lastUpdatedBy: authManager.currentUser._id, credits: encryptedCredits, firstTimePurchase: true, }; From be107b14a2bb56842a92ccf001f902147bf340d9 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 03:11:29 +0300 Subject: [PATCH 8/9] refactor chat icon color --- widget/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/widget/index.html b/widget/index.html index 9fb7262..cab5898 100755 --- a/widget/index.html +++ b/widget/index.html @@ -101,8 +101,8 @@

- - + +
@@ -137,8 +137,8 @@

- - + + From 512d82d26fe71c6d7cfdf3ab1ff1b988470909c7 Mon Sep 17 00:00:00 2001 From: alaa smadi Date: Wed, 12 Mar 2025 03:12:58 +0300 Subject: [PATCH 9/9] refactor fetching state variable --- widget/js/pages/home/index.js | 4 ++-- widget/js/state.js | 2 +- widget/js/widget.controller.js | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/widget/js/pages/home/index.js b/widget/js/pages/home/index.js index 0236b17..9754f9f 100644 --- a/widget/js/pages/home/index.js +++ b/widget/js/pages/home/index.js @@ -228,11 +228,11 @@ const homePage = { }); if (suggestions.length < state.pageSize) { - if (state.isAllNotCompletedSuggestionFetched) { + if (state.startFetchingCompleted) { state.isAllSuggestionFetched = true; if (!state.suggestionsList.length) this.printEmptyState(); } else { - state.isAllNotCompletedSuggestionFetched = true; + state.startFetchingCompleted = true; state.page = 0; widgetController.getSuggestions().then((suggestions) => { diff --git a/widget/js/state.js b/widget/js/state.js index 4a16d0c..9306b23 100644 --- a/widget/js/state.js +++ b/widget/js/state.js @@ -53,7 +53,7 @@ const state = { pageSize: 50, fetching: false, isAllSuggestionFetched: false, - isAllNotCompletedSuggestionFetched: false, + startFetchingCompleted: false, validUserImages: {}, suggestionsList: [], updatedUsersData: [], diff --git a/widget/js/widget.controller.js b/widget/js/widget.controller.js index 47b27fe..b7b65d2 100644 --- a/widget/js/widget.controller.js +++ b/widget/js/widget.controller.js @@ -53,13 +53,13 @@ const widgetController = { getSuggestions() { return new Promise((resolve) => { - const { page, pageSize, settings, isAllNotCompletedSuggestionFetched } = state; + const { page, pageSize, settings, startFetchingCompleted } = state; const searchOptions = { page, pageSize }; let $match = { "_buildfire.index.string1": { $exists: false } }, $sort = {}; - if (isAllNotCompletedSuggestionFetched) { + if (startFetchingCompleted) { // hide completed immediately if (settings.hideCompletedItems === 0) return resolve([]); @@ -136,7 +136,7 @@ const widgetController = { if (suggestions.length >= 10) { resolve(suggestions); } else { - state.isAllNotCompletedSuggestionFetched = true; + state.startFetchingCompleted = true; state.page = 0; this.getSuggestions().then(() => {