aboutsummaryrefslogtreecommitdiffstats
path: root/web_src/js/features/repo-common.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web_src/js/features/repo-common.ts')
-rw-r--r--web_src/js/features/repo-common.ts83
1 files changed, 83 insertions, 0 deletions
diff --git a/web_src/js/features/repo-common.ts b/web_src/js/features/repo-common.ts
new file mode 100644
index 0000000000..ac63ef2145
--- /dev/null
+++ b/web_src/js/features/repo-common.ts
@@ -0,0 +1,83 @@
+import $ from 'jquery';
+import {hideElem, queryElems, showElem} from '../utils/dom.ts';
+import {POST} from '../modules/fetch.ts';
+import {showErrorToast} from '../modules/toast.ts';
+import {sleep} from '../utils.ts';
+
+async function onDownloadArchive(e) {
+ e.preventDefault();
+ // there are many places using the "archive-link", eg: the dropdown on the repo code page, the release list
+ const el = e.target.closest('a.archive-link[href]');
+ const targetLoading = el.closest('.ui.dropdown') ?? el;
+ targetLoading.classList.add('is-loading', 'loading-icon-2px');
+ try {
+ for (let tryCount = 0; ;tryCount++) {
+ const response = await POST(el.href);
+ if (!response.ok) throw new Error(`Invalid server response: ${response.status}`);
+
+ const data = await response.json();
+ if (data.complete) break;
+ await sleep(Math.min((tryCount + 1) * 750, 2000));
+ }
+ window.location.href = el.href; // the archive is ready, start real downloading
+ } catch (e) {
+ console.error(e);
+ showErrorToast(`Failed to download the archive: ${e}`, {duration: 2500});
+ } finally {
+ targetLoading.classList.remove('is-loading', 'loading-icon-2px');
+ }
+}
+
+export function initRepoArchiveLinks() {
+ queryElems('a.archive-link[href]', (el) => el.addEventListener('click', onDownloadArchive));
+}
+
+export function initRepoCloneLink() {
+ const $repoCloneSsh = $('#repo-clone-ssh');
+ const $repoCloneHttps = $('#repo-clone-https');
+ const $inputLink = $('#repo-clone-url');
+
+ if ((!$repoCloneSsh.length && !$repoCloneHttps.length) || !$inputLink.length) {
+ return;
+ }
+
+ $repoCloneSsh.on('click', () => {
+ localStorage.setItem('repo-clone-protocol', 'ssh');
+ window.updateCloneStates();
+ });
+ $repoCloneHttps.on('click', () => {
+ localStorage.setItem('repo-clone-protocol', 'https');
+ window.updateCloneStates();
+ });
+
+ $inputLink.on('focus', () => {
+ $inputLink.trigger('select');
+ });
+}
+
+export function initRepoCommonBranchOrTagDropdown(selector) {
+ $(selector).each(function () {
+ const $dropdown = $(this);
+ $dropdown.find('.reference.column').on('click', function () {
+ hideElem($dropdown.find('.scrolling.reference-list-menu'));
+ showElem($($(this).data('target')));
+ return false;
+ });
+ });
+}
+
+export function initRepoCommonFilterSearchDropdown(selector) {
+ const $dropdown = $(selector);
+ if (!$dropdown.length) return;
+
+ $dropdown.dropdown({
+ fullTextSearch: 'exact',
+ selectOnKeydown: false,
+ onChange(_text, _value, $choice) {
+ if ($choice[0].getAttribute('data-url')) {
+ window.location.href = $choice[0].getAttribute('data-url');
+ }
+ },
+ message: {noResults: $dropdown[0].getAttribute('data-no-results')},
+ });
+}