Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions web_src/js/components/DiffFileTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import {toggleElem} from '../utils/dom.ts';
import {diffTreeStore} from '../modules/diff-file.ts';
import {setFileFolding} from '../features/file-fold.ts';
import {onMounted, onUnmounted} from 'vue';
import {getLocalStorageSetting, setLocalStorageSetting} from '../modules/storage.ts';

const LOCAL_STORAGE_KEY = 'diff_file_tree_visible';

const store = diffTreeStore();

onMounted(() => {
// Default to true if unset
store.fileTreeIsVisible = localStorage.getItem(LOCAL_STORAGE_KEY) !== 'false';
store.fileTreeIsVisible = getLocalStorageSetting(LOCAL_STORAGE_KEY) !== 'false';
document.querySelector('.diff-toggle-file-tree-button')!.addEventListener('click', toggleVisibility);

hashChangeListener();
Expand Down Expand Up @@ -43,7 +44,7 @@ function toggleVisibility() {

function updateVisibility(visible: boolean) {
store.fileTreeIsVisible = visible;
localStorage.setItem(LOCAL_STORAGE_KEY, store.fileTreeIsVisible.toString());
setLocalStorageSetting(LOCAL_STORAGE_KEY, store.fileTreeIsVisible.toString());
updateState(store.fileTreeIsVisible);
}

Expand Down
5 changes: 3 additions & 2 deletions web_src/js/components/RepoActionView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {renderAnsi} from '../render/ansi.ts';
import {POST, DELETE} from '../modules/fetch.ts';
import type {IntervalId} from '../types.ts';
import {toggleFullScreen} from '../utils.ts';
import {getLocalStorageSetting, setLocalStorageSetting} from '../modules/storage.ts';

// see "models/actions/status.go", if it needs to be used somewhere else, move it to a shared file like "types/actions.ts"
type RunStatus = 'unknown' | 'waiting' | 'running' | 'success' | 'failure' | 'cancelled' | 'skipped' | 'blocked';
Expand Down Expand Up @@ -73,7 +74,7 @@ type LocaleStorageOptions = {

function getLocaleStorageOptions(): LocaleStorageOptions {
try {
const optsJson = localStorage.getItem('actions-view-options');
const optsJson = getLocalStorageSetting('actions-view-options');
if (optsJson) return JSON.parse(optsJson);
} catch {}
// if no options in localStorage, or failed to parse, return default options
Expand Down Expand Up @@ -224,7 +225,7 @@ export default defineComponent({
methods: {
saveLocaleStorageOptions() {
const opts: LocaleStorageOptions = {autoScroll: this.optionAlwaysAutoScroll, expandRunning: this.optionAlwaysExpandRunning};
localStorage.setItem('actions-view-options', JSON.stringify(opts));
setLocalStorageSetting('actions-view-options', JSON.stringify(opts));
},

// get the job step logs container ('.job-step-logs')
Expand Down
7 changes: 4 additions & 3 deletions web_src/js/features/citation.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {getCurrentLocale} from '../utils.ts';
import {fomanticQuery} from '../modules/fomantic/base.ts';
import {getLocalStorageSetting, setLocalStorageSetting} from '../modules/storage.ts';

const {pageData} = window.config;

Expand Down Expand Up @@ -38,7 +39,7 @@ export async function initCitationFileCopyContent() {
if ((!citationCopyApa && !citationCopyBibtex) || !inputContent) return;

const updateUi = () => {
const isBibtex = (localStorage.getItem('citation-copy-format') || defaultCitationFormat) === 'bibtex';
const isBibtex = (getLocalStorageSetting('citation-copy-format') || defaultCitationFormat) === 'bibtex';
const copyContent = (isBibtex ? citationCopyBibtex : citationCopyApa).getAttribute('data-text')!;
inputContent.value = copyContent;
citationCopyBibtex.classList.toggle('primary', isBibtex);
Expand All @@ -55,12 +56,12 @@ export async function initCitationFileCopyContent() {
updateUi();

citationCopyApa.addEventListener('click', () => {
localStorage.setItem('citation-copy-format', 'apa');
setLocalStorageSetting('citation-copy-format', 'apa');
updateUi();
});

citationCopyBibtex.addEventListener('click', () => {
localStorage.setItem('citation-copy-format', 'bibtex');
setLocalStorageSetting('citation-copy-format', 'bibtex');
updateUi();
});

Expand Down
33 changes: 27 additions & 6 deletions web_src/js/features/comp/ComboMarkdownEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {DropzoneCustomEventReloadFiles, initDropzone} from '../dropzone.ts';
import {createTippy} from '../../modules/tippy.ts';
import {fomanticQuery} from '../../modules/fomantic/base.ts';
import type EasyMDE from 'easymde';
import {addLocalStorageChangeListener, getLocalStorageSetting, setLocalStorageSetting} from '../../modules/storage.ts';

/**
* validate if the given textarea is non-empty.
Expand All @@ -47,6 +48,21 @@ export function validateTextareaNonEmpty(textarea: HTMLTextAreaElement) {
return true;
}

/** Returns whether the user currently has the monospace font setting enabled */
function isMonospaceEnabled() {
return getLocalStorageSetting('markdown-editor-monospace') === 'true';
}

/** Apply font to the provided or all textareas on the page and optionally save on localStorage */
function applyMonospace(enabled: boolean, {textarea, save}: {textarea?: HTMLTextAreaElement, save?: boolean}) {
for (const el of textarea ? [textarea] : document.querySelectorAll('.markdown-text-editor')) {
el.classList.toggle('tw-font-mono', enabled);
}
if (save) {
setLocalStorageSetting('markdown-editor-monospace', String(enabled));
}
}

type Heights = {
minHeight?: string,
height?: string,
Expand Down Expand Up @@ -141,20 +157,25 @@ export class ComboMarkdownEditor {
}

const monospaceButton = this.container.querySelector('.markdown-switch-monospace')!;
const monospaceEnabled = localStorage?.getItem('markdown-editor-monospace') === 'true';
const monospaceEnabled = isMonospaceEnabled();
applyMonospace(monospaceEnabled, {textarea: this.textarea, save: false});
const monospaceText = monospaceButton.getAttribute(monospaceEnabled ? 'data-disable-text' : 'data-enable-text')!;
monospaceButton.setAttribute('data-tooltip-content', monospaceText);
monospaceButton.setAttribute('aria-checked', String(monospaceEnabled));
monospaceButton.addEventListener('click', (e) => {
e.preventDefault();
const enabled = localStorage?.getItem('markdown-editor-monospace') !== 'true';
localStorage.setItem('markdown-editor-monospace', String(enabled));
this.textarea.classList.toggle('tw-font-mono', enabled);
const enabled = !isMonospaceEnabled();
applyMonospace(enabled, {save: true});
const text = monospaceButton.getAttribute(enabled ? 'data-disable-text' : 'data-enable-text')!;
monospaceButton.setAttribute('data-tooltip-content', text);
monospaceButton.setAttribute('aria-checked', String(enabled));
});

// apply setting when it was changed in another tab
addLocalStorageChangeListener('markdown-editor-monospace', () => {
applyMonospace(isMonospaceEnabled(), {save: false});
});

if (this.supportEasyMDE) {
const easymdeButton = this.container.querySelector('.markdown-switch-easymde')!;
easymdeButton.addEventListener('click', async (e) => {
Expand Down Expand Up @@ -403,10 +424,10 @@ export class ComboMarkdownEditor {
}

get userPreferredEditor(): string {
return window.localStorage.getItem(`markdown-editor-${this.previewMode ?? 'default'}`) || '';
return getLocalStorageSetting(`markdown-editor-${this.previewMode ?? 'default'}`) || '';
}
set userPreferredEditor(s: string) {
window.localStorage.setItem(`markdown-editor-${this.previewMode ?? 'default'}`, s);
setLocalStorageSetting(`markdown-editor-${this.previewMode ?? 'default'}`, s);
}
}

Expand Down
9 changes: 5 additions & 4 deletions web_src/js/features/repo-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import RepoActivityTopAuthors from '../components/RepoActivityTopAuthors.vue';
import {createApp} from 'vue';
import {toOriginUrl} from '../utils/url.ts';
import {createTippy} from '../modules/tippy.ts';
import {getLocalStorageSetting, setLocalStorageSetting} from '../modules/storage.ts';

async function onDownloadArchive(e: Event) {
e.preventDefault();
Expand Down Expand Up @@ -57,7 +58,7 @@ function initCloneSchemeUrlSelection(parent: Element) {
const tabSsh = parent.querySelector('.repo-clone-ssh');
const tabTea = parent.querySelector('.repo-clone-tea');
const updateClonePanelUi = function() {
let scheme = localStorage.getItem('repo-clone-protocol')!;
let scheme = getLocalStorageSetting('repo-clone-protocol')!;
if (!['https', 'ssh', 'tea'].includes(scheme)) {
scheme = 'https';
}
Expand Down Expand Up @@ -114,15 +115,15 @@ function initCloneSchemeUrlSelection(parent: Element) {
updateClonePanelUi();
// tabSsh or tabHttps might not both exist, eg: guest view, or one is disabled by the server
tabHttps?.addEventListener('click', () => {
localStorage.setItem('repo-clone-protocol', 'https');
setLocalStorageSetting('repo-clone-protocol', 'https');
updateClonePanelUi();
});
tabSsh?.addEventListener('click', () => {
localStorage.setItem('repo-clone-protocol', 'ssh');
setLocalStorageSetting('repo-clone-protocol', 'ssh');
updateClonePanelUi();
});
tabTea?.addEventListener('click', () => {
localStorage.setItem('repo-clone-protocol', 'tea');
setLocalStorageSetting('repo-clone-protocol', 'tea');
updateClonePanelUi();
});
elCloneUrlInput.addEventListener('focus', () => {
Expand Down
18 changes: 18 additions & 0 deletions web_src/js/modules/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** Get a setting from localStorage */
export function getLocalStorageSetting(key: string) {
return localStorage?.getItem(key);
}

/** Set a setting in localStorage */
export function setLocalStorageSetting(key: string, value: string) {
return localStorage?.setItem(key, value);
}

/** Add a listener to the 'storage' event for given setting key. This event only fires in non-current tabs. */
export function addLocalStorageChangeListener(key: string, listener: (e: StorageEvent) => void) {
window.addEventListener('storage', (e: StorageEvent) => {
if (e.storageArea === localStorage && e.key === key) {
listener(e);
}
});
}