From 5428fa031d22ebcc62e31ff180a15aa2d56df55f Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Fri, 10 Feb 2023 14:54:34 +0800 Subject: [PATCH 01/32] Separate data of table from its UI handling --- website/src/queries-logic.js | 113 +++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 51 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index b31d487e..9fb2db63 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -2,6 +2,7 @@ const { Octokit } = require("@octokit/rest"); const { throttling } = require("@octokit/plugin-throttling"); /* Variables that should be cleared for every new query (defaults are set in "clear_old_data"). */ +let TABLE_DATA = []; let REPO_DATE; let TOTAL_FORKS; let RATE_LIMIT_EXCEEDED; @@ -13,7 +14,8 @@ let ONGOING_REQUESTS_COUNTER = 0; function clear_old_data() { clearHeader(); clearMsg(); - clearTable(); + TABLE_DATA = []; // clear the table data + clearTable(); // clear the table DOM setApiCallsLabel(0); hideExportCsvBtn(); REPO_DATE = new Date(); @@ -135,8 +137,10 @@ function allRequestsAreDone() { function decrementCounters() { ONGOING_REQUESTS_COUNTER--; if (allRequestsAreDone()) { + if (tableIsEmpty(getTableBody())) { + setMsg(UF_MSG_EMPTY_FILTER); + } clearNonErrorMsg(); - sortTable(); enableQueryFields(); displayCsvExportBtn(); } @@ -164,41 +168,26 @@ function send(requestPromise, successFn, failureFn) { () => decrementCounters()); } -/** Fills the first part of a row. */ -function build_fork_element_html(table_body, combined_name, num_stars, num_forks) { - const NEW_ROW = $('', {id: extract_username_from_fork(combined_name), class: "useful_forks_repo"}); - table_body.append( - NEW_ROW.append( - $('').html(getRepoCol(combined_name, false)).attr("value", combined_name), - $('').html(UF_TABLE_SEPARATOR + getStarCol(num_stars)).attr("value", num_stars), - $('').html(UF_TABLE_SEPARATOR + getForkCol(num_forks)).attr("value", num_forks) - ) - ); - return NEW_ROW; -} - -/** Add bold to the date text if the date is earlier than the queried repo. */ -function compareDates(date, html) { - return REPO_DATE <= new Date(date) ? `${html}` : html; -} - -/** Prepares, appends, and updates a table row. */ -function add_fork_elements(forkdata_array, user, repo, parentDefaultBranch) { - if (isEmpty(forkdata_array)) +/** Updates table data, then calls function to update the table. */ +function update_table_data(responseData, user, repo, parentDefaultBranch) { + if (isEmpty(responseData)) { return; + } - if (!RATE_LIMIT_EXCEEDED) // because some times gets called after some other msgs are displayed + if (!RATE_LIMIT_EXCEEDED) {// because some times gets called after some other msgs are displayed clearNonErrorMsg(); + } - let table_body = getTableBody(); - for (const currFork of forkdata_array) { - - /* Basic data (name/stars/forks). */ - const NEW_ROW = build_fork_element_html(table_body, currFork.full_name, currFork.stargazers_count, currFork.forks_count); - + for (const currFork of responseData) { if (RATE_LIMIT_EXCEEDED) // we can skip everything below because they are only requests continue; + let datum = { + 'name': currFork.full_name, + 'stars': currFork.stargazers_count, + 'forks': currFork.forks_count, + }; + /* Commits diff data (ahead/behind). */ const requestPromise = () => octokit.repos.compareCommits({ owner: user, @@ -207,27 +196,18 @@ function add_fork_elements(forkdata_array, user, repo, parentDefaultBranch) { head: `${extract_username_from_fork(currFork.full_name)}:${currFork.default_branch}` }); const onSuccess = (responseHeaders, responseData) => { - if (responseData.total_commits <= AHEAD_COMMITS_FILTER) { - NEW_ROW.remove(); - if (tableIsEmpty(table_body)) { - setMsg(UF_MSG_EMPTY_FILTER); - } - } else { - /* Appending the commit badges to the new row. */ - const ahead_url = responseData.html_url; - const behind_url = getBehindUrl(ahead_url); - const pushed_at = getOnlyDate(currFork.pushed_at); - const date_txt = compareDates(pushed_at, getDateCol(pushed_at)); - NEW_ROW.append( - $('').html(UF_TABLE_SEPARATOR), - $('', {class: "uf_badge"}).html(ahead_badge(responseData.ahead_by, ahead_url)).attr("value", responseData.ahead_by), - $('').html(UF_TABLE_SEPARATOR), - $('', {class: "uf_badge"}).html(behind_badge(responseData.behind_by, behind_url)).attr("value", responseData.behind_by), - $('').html(UF_TABLE_SEPARATOR + date_txt).attr("value", pushed_at) - ); + if (responseData.total_commits > AHEAD_COMMITS_FILTER) { + datum['ahead_by'] = responseData.ahead_by; + datum['ahead_url'] = responseData.html_url; + datum['behind_by'] = responseData.behind_by; + datum['behind_url'] = getBehindUrl(responseData.html_url); + datum['pushed_at'] = getOnlyDate(currFork.pushed_at); + TABLE_DATA.push(datum); + + update_table(TABLE_DATA); } }; - const onFailure = () => NEW_ROW.remove(); + const onFailure = () => { }; // do nothing send(requestPromise, onSuccess, onFailure); /* Forks of forks. */ @@ -237,6 +217,38 @@ function add_fork_elements(forkdata_array, user, repo, parentDefaultBranch) { } } +/** + * Rewrites the table with the specified data. + * @param {Array} data - Array of objects with the following keys: name, stars, forks, ahead_by, ahead_url, behind_by, behind_url, pushed_at + */ +function update_table(data) { + clearTable(); + let table_body = getTableBody(); + for (const currFork of data) { + const { name, stars, forks, ahead_by, ahead_url, behind_by, behind_url, pushed_at } = currFork; + const date_txt = compareDates(pushed_at, getDateCol(pushed_at)); + + const NEW_ROW = $('', { id: extract_username_from_fork(name), class: "useful_forks_repo" }); + NEW_ROW.append( + $('').html(getRepoCol(name, false)).attr("value", name), + $('').html(UF_TABLE_SEPARATOR + getStarCol(stars)).attr("value", stars), + $('').html(UF_TABLE_SEPARATOR + getForkCol(forks)).attr("value", forks), + $('').html(UF_TABLE_SEPARATOR), + $('', { class: "uf_badge" }).html(ahead_badge(ahead_by, ahead_url)).attr("value", ahead_by), + $('').html(UF_TABLE_SEPARATOR), + $('', { class: "uf_badge" }).html(behind_badge(behind_by, behind_url)).attr("value", behind_by), + $('').html(UF_TABLE_SEPARATOR + date_txt).attr("value", pushed_at) + ); + table_body.append(NEW_ROW); + } + sortTable(); +} + +/** Add bold to the date text if the date is earlier than the queried repo. */ +function compareDates(date, html) { + return REPO_DATE <= new Date(date) ? `${html}` : html; +} + /** Paginated (index starts at 1) recursive forks scan. */ function request_fork_page(page_number, user, repo, defaultBranch) { if (RATE_LIMIT_EXCEEDED) @@ -266,8 +278,7 @@ function request_fork_page(page_number, user, repo, defaultBranch) { } } - /* Populate the table. */ - add_fork_elements(responseData, user, repo, defaultBranch); + update_table_data(responseData, user, repo, defaultBranch); }; const onFailure = () => displayConditionalErrorMsg(); send(requestPromise, onSuccess, onFailure); From 1089205ffb1e151830fb93b3dc923d8c3657b67a Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Fri, 10 Feb 2023 18:18:34 +0800 Subject: [PATCH 02/32] Add GitHub-style filter for columns There are 2 types of filter: `number` and `date`. Tyey both support the following operators: `>`, `<`, `>=`, `<=`, `=`. The format of date should be `yyyy-mm-dd`, like `2022-01-01`. number: `stars`, `forks`, `ahead`, `behind`. date: `pushed` eg: `stars:>0 pushed:>2022-01-01` --- website/index.html | 4 ++ website/src/queries-init.js | 8 ++++ website/src/queries-logic.js | 86 ++++++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/website/index.html b/website/index.html index d9d9637f..8c138fdb 100644 --- a/website/index.html +++ b/website/index.html @@ -230,6 +230,10 @@ Find useful forks

+
+
+ +
diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 60d08ae0..32221945 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -1,6 +1,7 @@ const SELF_URL = "https://useful-forks.github.io/"; const JQ_REPO_FIELD = $('#repo'); +const JQ_FILTER_FIELD = $('#filter'); const JQ_SEARCH_BTN = $('#searchBtn'); const JQ_TOTAL_CALLS = $('#totalApiCalls'); @@ -151,6 +152,13 @@ function getQueryOrDefault(defaultVal) { return JQ_REPO_FIELD.val(); } +function getFilterOrDefault(defaultVal) { + if (!JQ_FILTER_FIELD.val()) { + JQ_FILTER_FIELD.val(defaultVal); + } + return JQ_FILTER_FIELD.val(); +} + function setApiCallsLabel(total) { JQ_TOTAL_CALLS.html(total + " calls"); } diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 9fb2db63..b4c32e09 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -169,7 +169,7 @@ function send(requestPromise, successFn, failureFn) { } /** Updates table data, then calls function to update the table. */ -function update_table_data(responseData, user, repo, parentDefaultBranch) { +function update_table_data(responseData, user, repo, parentDefaultBranch, is_useful_fork) { if (isEmpty(responseData)) { return; } @@ -204,7 +204,11 @@ function update_table_data(responseData, user, repo, parentDefaultBranch) { datum['pushed_at'] = getOnlyDate(currFork.pushed_at); TABLE_DATA.push(datum); - update_table(TABLE_DATA); + if (typeof is_useful_fork === 'function') { + update_table(TABLE_DATA.filter(is_useful_fork)); + } else { + update_table(TABLE_DATA); + } } }; const onFailure = () => { }; // do nothing @@ -217,6 +221,17 @@ function update_table_data(responseData, user, repo, parentDefaultBranch) { } } +function update_filter() { + clearNonErrorMsg(); + + let is_useful_fork = getFilterFunction() + if (typeof is_useful_fork === 'function') { + update_table(TABLE_DATA.filter(is_useful_fork)); + } else { + update_table(TABLE_DATA); + } +} + /** * Rewrites the table with the specified data. * @param {Array} data - Array of objects with the following keys: name, stars, forks, ahead_by, ahead_url, behind_by, behind_url, pushed_at @@ -244,6 +259,60 @@ function update_table(data) { sortTable(); } +function getFilterFunction() { + const filter = getFilterOrDefault(); + if (filter === '') { + return; // no filter + } + + const mapTable = { + 'ahead': 'ahead_by', + 'behind': 'behind_by', + 'pushed': 'pushed_at' + }; + + // parse filter string into condition object + const conditionStrList = filter.split(' '); + let conditionObj = {}; + for (const condition of conditionStrList) { + let [attribute, requirement] = condition.split(':'); + const [_, operator, value] = requirement.split(/([<>=]+)/); + if (attribute in mapTable) { + attribute = mapTable[attribute]; + } + conditionObj[attribute] = { operator, value }; + } + // construct filter function 'is_useful_fork' + let is_useful_fork = (datum) => { + for (const [attribute, { operator, value }] of Object.entries(conditionObj)) { + switch (operator) { + case '>': + if (datum[attribute] <= value) + return false; + break; + case '>=': + if (datum[attribute] < value) + return false; + break; + case '<': + if (datum[attribute] >= value) + return false; + break; + case '<=': + if (datum[attribute] > value) + return false; + break; + case '=': + if (datum[attribute] != value) + return false; + break; + } + } + return true; + } + return is_useful_fork; +} + /** Add bold to the date text if the date is earlier than the queried repo. */ function compareDates(date, html) { return REPO_DATE <= new Date(date) ? `${html}` : html; @@ -278,7 +347,12 @@ function request_fork_page(page_number, user, repo, defaultBranch) { } } - update_table_data(responseData, user, repo, defaultBranch); + let is_useful_fork = getFilterFunction() + if (typeof is_useful_fork === 'function') { + update_table_data(responseData, user, repo, defaultBranch, is_useful_fork); + } else { + update_table_data(responseData, user, repo, defaultBranch); + } }; const onFailure = () => displayConditionalErrorMsg(); send(requestPromise, onSuccess, onFailure); @@ -429,3 +503,9 @@ JQ_REPO_FIELD.keyup(event => { if (JQ_REPO_FIELD.val()) { JQ_SEARCH_BTN.click(); } + +JQ_FILTER_FIELD.keyup(event => { + if (event.keyCode === 13) { // 'ENTER' + update_filter(); + } +}); From 62e94c0f7a19c7618137612e85b28a07f1858861 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Mon, 13 Feb 2023 15:56:21 +0800 Subject: [PATCH 03/32] Adjust position of filter box --- website/index.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/website/index.html b/website/index.html index 8c138fdb..3a13771e 100644 --- a/website/index.html +++ b/website/index.html @@ -230,11 +230,10 @@ Find useful forks

-
+
-
From 2318d5f69777938f9a5f86f49d62b384ac4e8a9a Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Mon, 13 Feb 2023 15:57:12 +0800 Subject: [PATCH 04/32] Apply change in filter field automatically --- website/src/queries-logic.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index b4c32e09..0dff30f4 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -505,7 +505,6 @@ if (JQ_REPO_FIELD.val()) { } JQ_FILTER_FIELD.keyup(event => { - if (event.keyCode === 13) { // 'ENTER' - update_filter(); - } + // User updated the filter field, so we need to re-filter the table. + update_filter(); }); From 1967f20b3140d9e1fd4c98e506a329a03a4c9912 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Mon, 13 Feb 2023 16:08:17 +0800 Subject: [PATCH 05/32] Edit the placeholder of filter field --- website/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 3a13771e..05550291 100644 --- a/website/index.html +++ b/website/index.html @@ -232,7 +232,7 @@

- +
From e3fc24a27d4d091017ba5fd41ac1c0720f39ad3d Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Thu, 23 Feb 2023 22:18:43 +0800 Subject: [PATCH 06/32] Fix wrong message display after filtering --- website/src/csv-export.js | 10 +++------- website/src/queries-init.js | 1 - website/src/queries-logic.js | 18 ++++++++++++------ 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/website/src/csv-export.js b/website/src/csv-export.js index 3a0578ae..f4abbc29 100644 --- a/website/src/csv-export.js +++ b/website/src/csv-export.js @@ -11,18 +11,14 @@ function displayCsvExportBtn() { if (!UF_SETTINGS_CSV_DISPLAY) { return; } - if (!tableIsEmpty()) { - JQ_ID_HEADER.append(EXPORT_DIV); - setClickEvent(); - } + JQ_ID_HEADER.append(EXPORT_DIV); + setClickEvent(); } function hideExportCsvBtn() { if (!UF_SETTINGS_CSV_DISPLAY) { return; } - if (!tableIsEmpty()) { - getJqId_$(EXPORT_DIV_ID).remove(); - } + getJqId_$(EXPORT_DIV_ID).remove(); } function setClickEvent() { EXPORT_BTN.on('click', function (event) { diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 32221945..9a1c7455 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -22,7 +22,6 @@ const UF_MSG_API_RATE = "GitHub API rate-limits exceeded. Consider pr // list of messages which should not be cleared when the request ends const UF_PRESERVED_MSGS = [ UF_MSG_NO_FORKS, - UF_MSG_EMPTY_FILTER, UF_MSG_ERROR, UF_MSG_API_RATE ]; diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 0dff30f4..b6c5863f 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -137,11 +137,17 @@ function allRequestsAreDone() { function decrementCounters() { ONGOING_REQUESTS_COUNTER--; if (allRequestsAreDone()) { - if (tableIsEmpty(getTableBody())) { - setMsg(UF_MSG_EMPTY_FILTER); - } - clearNonErrorMsg(); + manageMsgs(); enableQueryFields(); + } +} + +function manageMsgs() { + clearNonErrorMsg(); + if (tableIsEmpty(getTableBody())) { + setMsg(UF_MSG_EMPTY_FILTER); + hideExportCsvBtn(); + } else { displayCsvExportBtn(); } } @@ -222,14 +228,14 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use } function update_filter() { - clearNonErrorMsg(); - let is_useful_fork = getFilterFunction() if (typeof is_useful_fork === 'function') { update_table(TABLE_DATA.filter(is_useful_fork)); } else { update_table(TABLE_DATA); } + + manageMsgs(); } /** From c51abe2e8e523352a4b9c3a40368105d5b2e34cb Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Thu, 23 Feb 2023 22:49:38 +0800 Subject: [PATCH 07/32] Update the way to deal with invalid filter pattern --- website/src/queries-logic.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index b6c5863f..643c7db7 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -282,7 +282,13 @@ function getFilterFunction() { let conditionObj = {}; for (const condition of conditionStrList) { let [attribute, requirement] = condition.split(':'); + if (!attribute || !requirement) { + return; // invalid filter + } const [_, operator, value] = requirement.split(/([<>=]+)/); + if (!operator || !value) { + return; // invalid filter + } if (attribute in mapTable) { attribute = mapTable[attribute]; } From 2a8616dcd6f90b5bd7c8116be09e3ad3a171a324 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Sun, 26 Feb 2023 14:26:43 +0800 Subject: [PATCH 08/32] Fix logic to parse filter pattern --- website/src/queries-logic.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 643c7db7..70534642 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -265,6 +265,11 @@ function update_table(data) { sortTable(); } +/** + * 1. Empty filter means no filter. + * 2. Filter string is a list of conditions separated by spaces. + * 3. If a condition is invalid, it is ignored, and the rest of the conditions are applied. + */ function getFilterFunction() { const filter = getFilterOrDefault(); if (filter === '') { @@ -283,11 +288,11 @@ function getFilterFunction() { for (const condition of conditionStrList) { let [attribute, requirement] = condition.split(':'); if (!attribute || !requirement) { - return; // invalid filter + continue; // invalid condition } const [_, operator, value] = requirement.split(/([<>=]+)/); if (!operator || !value) { - return; // invalid filter + continue; // invalid condition } if (attribute in mapTable) { attribute = mapTable[attribute]; From 120a681aca62adc4f56ededb210a7de3cc7fd946 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Sun, 26 Feb 2023 14:30:53 +0800 Subject: [PATCH 09/32] Replace "Export table as CSV" with "Export table below as CSV" --- website/index.html | 2 +- website/src/csv-export.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/website/index.html b/website/index.html index 05550291..8d0d6b9d 100644 --- a/website/index.html +++ b/website/index.html @@ -195,7 +195,7 @@ Display -

Default is checked. Determines whether to display or not the "Export table as CSV" button when a scan ends.

+

Default is checked. Determines whether to display or not the "Export table below as CSV" button when a scan ends.

diff --git a/website/src/csv-export.js b/website/src/csv-export.js index f4abbc29..08aaeb71 100644 --- a/website/src/csv-export.js +++ b/website/src/csv-export.js @@ -3,7 +3,7 @@ const EXPORT_DIV_BTN = "uf_csv_export_btn"; const EXPORT_BTN = $('', {id: EXPORT_DIV_BTN, class: "button is-dark is-outlined is-small"}) .attr("href", "#") .prepend($('', {src: "assets/csv_dl.svg", class: "mr-2", alt: "csv", width: "26", height: "26"})) - .append("Export table as CSV"); + .append("Export table below as CSV"); const EXPORT_DIV = $('
', {id: EXPORT_DIV_ID, class: "mt-2"}).append(EXPORT_BTN); From 9c446d36883bbf9877f4c30b118cb57e40870d76 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Wed, 1 Mar 2023 20:05:10 +0800 Subject: [PATCH 10/32] Add single-letter aliases for each column --- website/src/queries-logic.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 70534642..1bbab586 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -279,7 +279,12 @@ function getFilterFunction() { const mapTable = { 'ahead': 'ahead_by', 'behind': 'behind_by', - 'pushed': 'pushed_at' + 'pushed': 'pushed_at', + 'a': 'ahead_by', + 'b': 'behind_by', + 'p': 'pushed_at', + 's': 'stars', + 'f': 'forks', }; // parse filter string into condition object From 0ca258675ff93242543c89b21e465825a43bff32 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Sun, 5 Mar 2023 11:50:37 +0800 Subject: [PATCH 11/32] Fix bug of overwriting error msg with empty msg --- website/src/queries-init.js | 5 +++++ website/src/queries-logic.js | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 9a1c7455..766ba24a 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -102,6 +102,11 @@ function setMsg(msg) { .css("border-color", "rgba(0,0,0,0.25)") .css("border-style", "solid"); } + +function isMsgEmpty() { + return JQ_ID_MSG.html() === ""; +} + function clearMsg() { JQ_ID_MSG .empty() diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 1bbab586..bf244096 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -143,9 +143,11 @@ function decrementCounters() { } function manageMsgs() { - clearNonErrorMsg(); + clearNonErrorMsg() if (tableIsEmpty(getTableBody())) { - setMsg(UF_MSG_EMPTY_FILTER); + if (isMsgEmpty()) { + setMsg(UF_MSG_EMPTY_FILTER); + } hideExportCsvBtn(); } else { displayCsvExportBtn(); From c511135137866e62dbf3182510e989a3df762573 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Mon, 6 Mar 2023 15:03:41 +0800 Subject: [PATCH 12/32] Show and hide filter field automatically --- website/index.html | 5 +++-- website/src/queries-init.js | 9 +++++++++ website/src/queries-logic.js | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/website/index.html b/website/index.html index 8d0d6b9d..30e3058e 100644 --- a/website/index.html +++ b/website/index.html @@ -231,8 +231,9 @@

-
- +
diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 766ba24a..80cbe6f0 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -2,6 +2,7 @@ const SELF_URL = "https://useful-forks.github.io/"; const JQ_REPO_FIELD = $('#repo'); const JQ_FILTER_FIELD = $('#filter'); +const JQ_FILTER_CONTAINER = $('#filterContainer'); const JQ_SEARCH_BTN = $('#searchBtn'); const JQ_TOTAL_CALLS = $('#totalApiCalls'); @@ -156,6 +157,14 @@ function getQueryOrDefault(defaultVal) { return JQ_REPO_FIELD.val(); } +function hideFilterContainer() { + JQ_FILTER_CONTAINER.hide(); +} + +function showFilterContainer() { + JQ_FILTER_CONTAINER.show(); +} + function getFilterOrDefault(defaultVal) { if (!JQ_FILTER_FIELD.val()) { JQ_FILTER_FIELD.val(defaultVal); diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index bf244096..bf1fe0bd 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -211,7 +211,8 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use datum['behind_url'] = getBehindUrl(responseData.html_url); datum['pushed_at'] = getOnlyDate(currFork.pushed_at); TABLE_DATA.push(datum); - + if (TABLE_DATA.length > 1) showFilterContainer(); + if (typeof is_useful_fork === 'function') { update_table(TABLE_DATA.filter(is_useful_fork)); } else { @@ -455,6 +456,7 @@ function initiate_search() { setUpOctokitWithLatestToken(); setQueryFieldsAsLoading(); + hideFilterContainer(); setMsg(UF_MSG_SCANNING); const user = queryValues[len - 2]; From 6b2f98001b476021d1b0d33f1ab9e05c14d55dbe Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Tue, 7 Mar 2023 10:25:49 +0800 Subject: [PATCH 13/32] Apply little refactor and formatting --- website/src/queries-logic.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index bf1fe0bd..5987559a 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -143,7 +143,7 @@ function decrementCounters() { } function manageMsgs() { - clearNonErrorMsg() + clearNonErrorMsg(); if (tableIsEmpty(getTableBody())) { if (isMsgEmpty()) { setMsg(UF_MSG_EMPTY_FILTER); @@ -176,6 +176,19 @@ function send(requestPromise, successFn, failureFn) { () => decrementCounters()); } +/** Add bold to the date text if the date is earlier than the queried repo. */ +function compareDates(date, html) { + return REPO_DATE <= new Date(date) ? `${html}` : html; +} + +function update_table_trying_use_filter(is_useful_fork) { + if (typeof is_useful_fork === 'function') { + update_table(TABLE_DATA.filter(is_useful_fork)); + } else { + update_table(TABLE_DATA); + } +} + /** Updates table data, then calls function to update the table. */ function update_table_data(responseData, user, repo, parentDefaultBranch, is_useful_fork) { if (isEmpty(responseData)) { @@ -213,11 +226,7 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use TABLE_DATA.push(datum); if (TABLE_DATA.length > 1) showFilterContainer(); - if (typeof is_useful_fork === 'function') { - update_table(TABLE_DATA.filter(is_useful_fork)); - } else { - update_table(TABLE_DATA); - } + update_table_trying_use_filter(is_useful_fork); } }; const onFailure = () => { }; // do nothing @@ -232,11 +241,7 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use function update_filter() { let is_useful_fork = getFilterFunction() - if (typeof is_useful_fork === 'function') { - update_table(TABLE_DATA.filter(is_useful_fork)); - } else { - update_table(TABLE_DATA); - } + update_table_trying_use_filter(is_useful_fork); manageMsgs(); } @@ -338,11 +343,6 @@ function getFilterFunction() { return is_useful_fork; } -/** Add bold to the date text if the date is earlier than the queried repo. */ -function compareDates(date, html) { - return REPO_DATE <= new Date(date) ? `${html}` : html; -} - /** Paginated (index starts at 1) recursive forks scan. */ function request_fork_page(page_number, user, repo, defaultBranch) { if (RATE_LIMIT_EXCEEDED) From 985843b2eb2f6041aabdaf7bb2c01c3924e45dd9 Mon Sep 17 00:00:00 2001 From: payne911 <38117856+payne911@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:31:22 -0500 Subject: [PATCH 14/32] Fix small formatting issue --- website/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/website/index.html b/website/index.html index 30e3058e..7dca6d22 100644 --- a/website/index.html +++ b/website/index.html @@ -230,11 +230,11 @@ Find useful forks

- - + +
From 26cff66fde6e34cd94ee6a45b5463d4529850d70 Mon Sep 17 00:00:00 2001 From: payne911 <38117856+payne911@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:32:29 -0500 Subject: [PATCH 15/32] Reducing area of "git blame" --- website/src/queries-logic.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 5987559a..ba6ddc7e 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -195,9 +195,8 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use return; } - if (!RATE_LIMIT_EXCEEDED) {// because some times gets called after some other msgs are displayed + if (!RATE_LIMIT_EXCEEDED) // because some times gets called after some other msgs are displayed clearNonErrorMsg(); - } for (const currFork of responseData) { if (RATE_LIMIT_EXCEEDED) // we can skip everything below because they are only requests From 96c7c832773156af8a741ca026ce00bb84837d2a Mon Sep 17 00:00:00 2001 From: payne911 <38117856+payne911@users.noreply.github.com> Date: Wed, 15 Mar 2023 00:12:02 -0400 Subject: [PATCH 16/32] Add some more aliases --- website/src/queries-logic.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index ba6ddc7e..fa5d831b 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -287,6 +287,8 @@ function getFilterFunction() { 'ahead': 'ahead_by', 'behind': 'behind_by', 'pushed': 'pushed_at', + 'date': 'pushed_at', + 'd': 'pushed_at', 'a': 'ahead_by', 'b': 'behind_by', 'p': 'pushed_at', From f7363da2aaba09d59e3d8222832f669877192e2c Mon Sep 17 00:00:00 2001 From: payne911 <38117856+payne911@users.noreply.github.com> Date: Wed, 15 Mar 2023 00:26:35 -0400 Subject: [PATCH 17/32] Tooltip for the search field --- website/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/index.html b/website/index.html index 7dca6d22..119cd027 100644 --- a/website/index.html +++ b/website/index.html @@ -233,7 +233,8 @@
From c296c9bf50b086b4e5a638891c9f8b3b577e959b Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Wed, 15 Mar 2023 13:12:52 +0800 Subject: [PATCH 18/32] Fix incompatibility with progress bar display --- website/src/queries-init.js | 1 - website/src/queries-logic.js | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 80cbe6f0..00721fea 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -113,7 +113,6 @@ function clearMsg() { .empty() .removeClass("box") .css("border-style", ""); - removeProgressBar(); } function clearNonErrorMsg() { const msg = JQ_ID_MSG.html(); diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index fa5d831b..d547f15e 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -14,6 +14,7 @@ let ONGOING_REQUESTS_COUNTER = 0; function clear_old_data() { clearHeader(); clearMsg(); + removeProgressBar(); TABLE_DATA = []; // clear the table data clearTable(); // clear the table DOM setApiCallsLabel(0); @@ -138,6 +139,7 @@ function decrementCounters() { ONGOING_REQUESTS_COUNTER--; if (allRequestsAreDone()) { manageMsgs(); + removeProgressBar(); enableQueryFields(); } } @@ -195,8 +197,10 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use return; } - if (!RATE_LIMIT_EXCEEDED) // because some times gets called after some other msgs are displayed + if (!RATE_LIMIT_EXCEEDED) {// because some times gets called after some other msgs are displayed clearNonErrorMsg(); + removeProgressBar(); + } for (const currFork of responseData) { if (RATE_LIMIT_EXCEEDED) // we can skip everything below because they are only requests From 199c24db15c2d7551cdde2de5b74067c6fd22af0 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Thu, 16 Mar 2023 12:02:38 +0800 Subject: [PATCH 19/32] Separete scaning state msgs from non-error msgs --- website/src/queries-init.js | 13 +++++++++++++ website/src/queries-logic.js | 9 +++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/website/src/queries-init.js b/website/src/queries-init.js index 00721fea..5b977a47 100644 --- a/website/src/queries-init.js +++ b/website/src/queries-init.js @@ -27,6 +27,11 @@ const UF_PRESERVED_MSGS = [ UF_MSG_API_RATE ]; +// messages about the current state of the scan but not about the results +const UF_MSGS_SCAN_STATE = [ + UF_MSG_SCANNING, + UF_MSG_SLOWER +]; const EXAMPLE_LINK_1 = `
payne911/PieMenu`; @@ -119,6 +124,14 @@ function clearNonErrorMsg() { if (!UF_PRESERVED_MSGS.includes(msg)) clearMsg(); } + +function clearNonScanStateMsg() { + const msg = JQ_ID_MSG.html(); + if (!UF_MSGS_SCAN_STATE.includes(msg) && !UF_PRESERVED_MSGS.includes(msg)) { + clearMsg(); + } +} + function setHeader(msg) { JQ_ID_HEADER.html(msg); } diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index d547f15e..542f050b 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -138,14 +138,15 @@ function allRequestsAreDone() { function decrementCounters() { ONGOING_REQUESTS_COUNTER--; if (allRequestsAreDone()) { - manageMsgs(); + clearNonErrorMsg(); removeProgressBar(); + updateBasedOnTable(); enableQueryFields(); } } -function manageMsgs() { - clearNonErrorMsg(); +function updateBasedOnTable() { + clearNonScanStateMsg(); if (tableIsEmpty(getTableBody())) { if (isMsgEmpty()) { setMsg(UF_MSG_EMPTY_FILTER); @@ -246,7 +247,7 @@ function update_filter() { let is_useful_fork = getFilterFunction() update_table_trying_use_filter(is_useful_fork); - manageMsgs(); + updateBasedOnTable(); } /** From dd898a85f0e06ee19473d013da0f2f866411a1a8 Mon Sep 17 00:00:00 2001 From: Ethkuil Date: Fri, 17 Mar 2023 16:42:56 +0800 Subject: [PATCH 20/32] Make the filter function global --- website/src/queries-logic.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 542f050b..2c46b375 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -9,6 +9,8 @@ let RATE_LIMIT_EXCEEDED; let AHEAD_COMMITS_FILTER; let TOTAL_API_CALLS_COUNTER; let ONGOING_REQUESTS_COUNTER = 0; +let IS_USEFUL_FORK; // function that determines if a fork is useful or not + /** Used to reset the state for a brand new query. */ function clear_old_data() { @@ -184,16 +186,16 @@ function compareDates(date, html) { return REPO_DATE <= new Date(date) ? `${html}` : html; } -function update_table_trying_use_filter(is_useful_fork) { - if (typeof is_useful_fork === 'function') { - update_table(TABLE_DATA.filter(is_useful_fork)); +function update_table_trying_use_filter() { + if (typeof IS_USEFUL_FORK === 'function') { + update_table(TABLE_DATA.filter(IS_USEFUL_FORK)); } else { update_table(TABLE_DATA); } } /** Updates table data, then calls function to update the table. */ -function update_table_data(responseData, user, repo, parentDefaultBranch, is_useful_fork) { +function update_table_data(responseData, user, repo, parentDefaultBranch) { if (isEmpty(responseData)) { return; } @@ -230,7 +232,7 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use TABLE_DATA.push(datum); if (TABLE_DATA.length > 1) showFilterContainer(); - update_table_trying_use_filter(is_useful_fork); + update_table_trying_use_filter(); } }; const onFailure = () => { }; // do nothing @@ -244,8 +246,8 @@ function update_table_data(responseData, user, repo, parentDefaultBranch, is_use } function update_filter() { - let is_useful_fork = getFilterFunction() - update_table_trying_use_filter(is_useful_fork); + updateFilterFunction(); + update_table_trying_use_filter(); updateBasedOnTable(); } @@ -282,7 +284,7 @@ function update_table(data) { * 2. Filter string is a list of conditions separated by spaces. * 3. If a condition is invalid, it is ignored, and the rest of the conditions are applied. */ -function getFilterFunction() { +function updateFilterFunction() { const filter = getFilterOrDefault(); if (filter === '') { return; // no filter @@ -318,8 +320,8 @@ function getFilterFunction() { } conditionObj[attribute] = { operator, value }; } - // construct filter function 'is_useful_fork' - let is_useful_fork = (datum) => { + + IS_USEFUL_FORK = (datum) => { for (const [attribute, { operator, value }] of Object.entries(conditionObj)) { switch (operator) { case '>': @@ -346,7 +348,6 @@ function getFilterFunction() { } return true; } - return is_useful_fork; } /** Paginated (index starts at 1) recursive forks scan. */ @@ -378,12 +379,7 @@ function request_fork_page(page_number, user, repo, defaultBranch) { } } - let is_useful_fork = getFilterFunction() - if (typeof is_useful_fork === 'function') { - update_table_data(responseData, user, repo, defaultBranch, is_useful_fork); - } else { - update_table_data(responseData, user, repo, defaultBranch); - } + update_table_data(responseData, user, repo, defaultBranch); }; const onFailure = () => displayConditionalErrorMsg(); send(requestPromise, onSuccess, onFailure); From 86d555a93a1f0996000ba4a2850cadd8fafabd50 Mon Sep 17 00:00:00 2001 From: payne911 <38117856+payne911@users.noreply.github.com> Date: Tue, 21 Mar 2023 23:31:21 -0400 Subject: [PATCH 21/32] style --- website/src/queries-logic.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index 2c46b375..e227ce5e 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -200,7 +200,7 @@ function update_table_data(responseData, user, repo, parentDefaultBranch) { return; } - if (!RATE_LIMIT_EXCEEDED) {// because some times gets called after some other msgs are displayed + if (!RATE_LIMIT_EXCEEDED) { // because some times gets called after some other msgs are displayed clearNonErrorMsg(); removeProgressBar(); } From 229d0ce308dc47795d7323af9b0a128a0ef7f4ec Mon Sep 17 00:00:00 2001 From: payne911 Date: Tue, 21 Mar 2023 23:56:51 -0400 Subject: [PATCH 22/32] Avoid querying a duplicated result (resolve #59) --- website/src/queries-logic.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/website/src/queries-logic.js b/website/src/queries-logic.js index e227ce5e..8ea5a51d 100644 --- a/website/src/queries-logic.js +++ b/website/src/queries-logic.js @@ -194,6 +194,14 @@ function update_table_trying_use_filter() { } } +function is_duplicate_repo(name) { + for (const fork of TABLE_DATA) { + if (fork['name'] === name) + return true; + } + return false; +} + /** Updates table data, then calls function to update the table. */ function update_table_data(responseData, user, repo, parentDefaultBranch) { if (isEmpty(responseData)) { @@ -209,6 +217,9 @@ function update_table_data(responseData, user, repo, parentDefaultBranch) { if (RATE_LIMIT_EXCEEDED) // we can skip everything below because they are only requests continue; + if (is_duplicate_repo(currFork.full_name)) + continue; // abort because repo is already listed + let datum = { 'name': currFork.full_name, 'stars': currFork.stargazers_count, From 909e35a008f819e4dda8e253469ae1828af3ea7f Mon Sep 17 00:00:00 2001 From: payne911 Date: Wed, 22 Mar 2023 00:14:53 -0400 Subject: [PATCH 23/32] Remove the ahead filter from the settings --- website/index.html | 17 ----------------- website/src/queries-logic.js | 4 +--- website/src/settings.js | 20 -------------------- 3 files changed, 1 insertion(+), 40 deletions(-) diff --git a/website/index.html b/website/index.html index 119cd027..d657c18e 100644 --- a/website/index.html +++ b/website/index.html @@ -139,23 +139,6 @@