Files
mue/src/features/navbar/components/Notes.jsx
Alex Sparkes 4cf5269cdc Dev (#1134)
* feat: add professional three-branch release workflow automation (#1129)

- Add version-bump workflow for semantic versioning across all files
- Add beta-release workflow for automated pre-release testing
- Add production-release workflow with manual approval gates
- Add hotfix-release workflow for emergency patches
- Create comprehensive CONTRIBUTING.md with workflow guide
- Create detailed RELEASE_PROCESS.md for maintainers
- Add PR template with release checklists
- Update CODEOWNERS to protect workflow files
- Update README with contribution links
- Remove /docs from .gitignore to allow documentation

This implements a dev  beta  main branching strategy with:
- Automated version management across 6 files
- Changelog generation from conventional commits
- GitHub Releases with build artifacts
- Environment-based approvals for production
- Back-merge support for hotfixes

* feat: new default quotes experience, improve added page

* Fix/beta workflow version check (#1131)

* fix(workflows): prevent beta release for non-beta versions

* fix(workflows): address copilot PR review feedback

- Support iterative beta versions (7.6.0-beta.1 -> 7.6.0-beta.2)
- Remove tag trigger from beta workflow to prevent premature releases
- Fix tag format in docs/summaries to include 'v' prefix
- Clarify deployment approval wording

* feat: replace mui with new style

* feat: improve time formatting in Clock component with padded digits

* fix: change Checkbox component from label to div for better semantics

* fix: change Switch component from label to div for better semantics

* feat: add smooth animation to reset functionality in Slider component

* feat: enhance accessibility and styling for form components including Checkbox, Dropdown, Radio, Slider, and Text

* feat: enhance WeatherOptions component with improved layout and auto location reset functionality

* feat: update Slider and Dropdown components with improved layout and z-index adjustments

* feat: add reset functionality to Dropdown component with toast notification

* feat: update Dropdown component styles for improved layout and structure

* feat: update languageSettings component with increased padding for better spacing

* feat: bump version to 7.6.0 across all manifests and documentation

---------

Signed-off-by: Alex Sparkes <alexsparkes@gmail.com>
Co-authored-by: David Ralph <me@davidcralph.co.uk>
2026-01-25 20:58:57 +00:00

150 lines
4.4 KiB
JavaScript

import variables from 'config/variables';
import { memo, useState, useEffect } from 'react';
import { useT } from 'contexts';
import { MdContentCopy, MdAssignment, MdPushPin, MdDownload } from 'react-icons/md';
import { useFloating, shift } from '@floating-ui/react-dom';
import { toast } from 'react-toastify';
import { Tooltip } from 'components/Elements';
import { Textarea } from 'components/Form/Settings';
import { saveFile } from 'utils/saveFile';
import EventBus from 'utils/eventbus';
const Notes = ({ notesRef, floatRef, position, xPosition, yPosition }) => {
const t = useT();
const [notes, setNotes] = useState(localStorage.getItem('notes') || '');
const [showNotes, setShowNotes] = useState(localStorage.getItem('notesPinned') === 'true');
const [zoomFontSize, setZoomFontSize] = useState('1.2rem');
useEffect(() => {
const handleRefresh = (data) => {
if (data === 'navbar') {
setZoomFontSize(Number(((localStorage.getItem('zoomNavbar') || 100) / 100) * 1.2) + 'rem');
}
};
setZoomFontSize(Number(((localStorage.getItem('zoomNavbar') || 100) / 100) * 1.2) + 'rem');
EventBus.on('refresh', handleRefresh);
return () => {
EventBus.off('refresh');
};
}, []);
const handleSetNotes = (e) => {
localStorage.setItem('notes', e.target.value);
setNotes(e.target.value);
};
const handleShowNotes = () => {
setShowNotes(true);
};
const handleHideNotes = () => {
setShowNotes(localStorage.getItem('notesPinned') === 'true');
};
const handlePin = () => {
variables.stats.postEvent('feature', 'Notes pin');
const notesPinned = localStorage.getItem('notesPinned') === 'true';
localStorage.setItem('notesPinned', !notesPinned);
setShowNotes(!notesPinned);
};
const handleCopy = () => {
variables.stats.postEvent('feature', 'Notes copied');
navigator.clipboard.writeText(notes);
toast(t('toasts.notes'));
};
const handleDownload = () => {
if (!notes || notes === '') {
return;
}
variables.stats.postEvent('feature', 'Notes download');
saveFile(notes, 'mue-notes.txt', 'text/plain');
};
return (
<div className="notes" onMouseLeave={handleHideNotes} onFocus={handleShowNotes}>
<button
className="navbarButton"
onMouseEnter={handleShowNotes}
onFocus={handleShowNotes}
onBlur={handleHideNotes}
ref={notesRef}
style={{ fontSize: zoomFontSize }}
aria-label={t('widgets.navbar.notes.title')}
>
<MdAssignment className="topicons" />
</button>
{showNotes && (
<span
className="notesContainer"
ref={floatRef}
style={{
position: position,
top: yPosition ?? '44',
left: xPosition ?? '',
}}
>
<div className="flexNotes">
<div className="topBarNotes" style={{ display: 'flex' }}>
<MdAssignment />
<span>{t('widgets.navbar.notes.title')}</span>
</div>
<div className="notes-buttons">
<Tooltip title={t('widgets.navbar.todo.pin')}>
<button onClick={handlePin}>
<MdPushPin />
</button>
</Tooltip>
<Tooltip title={t('widgets.quote.copy')}>
<button onClick={handleCopy} disabled={notes === ''}>
<MdContentCopy />
</button>
</Tooltip>
<Tooltip title={t('widgets.background.download')}>
<button onClick={handleDownload} disabled={notes === ''}>
<MdDownload />
</button>
</Tooltip>
</div>
<Textarea
placeholder={t('widgets.navbar.notes.placeholder')}
value={notes}
onChange={handleSetNotes}
minRows={5}
/>
</div>
</span>
)}
</div>
);
};
function NotesWrapper() {
const [reference, setReference] = useState(null);
const { x, y, refs, strategy } = useFloating({
placement: 'bottom',
middleware: [shift()],
elements: { reference },
});
return (
<Notes
notesRef={setReference}
floatRef={refs.setFloating}
position={strategy}
xPosition={x}
yPosition={y}
/>
);
}
const MemoizedNotesWrapper = memo(NotesWrapper);
export { MemoizedNotesWrapper as default, MemoizedNotesWrapper as Notes };