Merge dev into main (v0.63.1)
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 29s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 29s
This commit is contained in:
commit
9b02d7cfa1
5 files changed
+45
-8
No files matched your search
+7
-1
@@ -6,6 +6,11 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.63.1] - 2026-11-02
|
||||
|
||||
### Fixed
|
||||
- Notizen am Desktop: Die Knopfleiste an einem Punkt (Fokus, Auslagern, Löschen …) erscheint nur noch, während sich die Maus über dem Punkt bewegt, und verschwindet etwa eine Sekunde später. Eine ruhende Maus, auch beim Tippen, lässt sie nicht mehr über dem Text stehen. Auf der Leiste selbst bleibt sie sichtbar.
|
||||
|
||||
## [0.63.0] - 2026-11-02
|
||||
|
||||
### Added
|
||||
@@ -902,7 +907,8 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V
|
||||
- Geteilte Listen (Einkaufs-, Pack- und Checklisten) mit `#Kategorie`-Gruppierung, Mengenangaben und Echtzeit-Abhaken.
|
||||
- Benutzer-, Gruppen- und Admin-Verwaltung (Ersteinrichtungs-Assistent, Einladungscodes, Profilbilder, persönliche API-Keys & Webhook-Ingest `/api/v1/webhooks/ingest`, JSON-Datenexport) sowie CSS-Theme-Engine mit 4 Themes (`Dark`, `Light`, `High Contrast`, `Soft`) und PWA-Unterstützung.
|
||||
|
||||
[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.63.0...dev
|
||||
[Unreleased]: https://git.dsit.me/sandrodach/MindSift/compare/v0.63.1...dev
|
||||
[0.63.1]: https://git.dsit.me/sandrodach/MindSift/compare/v0.63.0...v0.63.1
|
||||
[0.63.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.62.0...v0.63.0
|
||||
[0.62.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.61.0...v0.62.0
|
||||
[0.61.0]: https://git.dsit.me/sandrodach/MindSift/compare/v0.60.0...v0.61.0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[](#)
|
||||
[](#-schnellstart)
|
||||
[](#-deine-daten-gehören-dir)
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
|
||||
**MindSift** ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server.
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mindsift-frontend",
|
||||
"version": "0.63.0",
|
||||
"version": "0.63.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mindsift-frontend",
|
||||
"version": "0.63.0",
|
||||
"version": "0.63.1",
|
||||
"license": "AGPL-3.0-only",
|
||||
"dependencies": {
|
||||
"@fontsource-variable/inter": "5.3.0",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "mindsift-frontend",
|
||||
"private": true,
|
||||
"version": "0.63.0",
|
||||
"version": "0.63.1",
|
||||
"license": "AGPL-3.0-only",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -67,6 +67,9 @@ function slashRank(c: SlashCommand, q: string): number {
|
||||
return 4;
|
||||
}
|
||||
|
||||
// How long the action bubble stays after the last mouse move over a bullet
|
||||
const BUBBLE_IDLE_MS = 1000;
|
||||
|
||||
const SLASH_COMMANDS: SlashCommand[] = [
|
||||
{ type: 'todo', label: '/todo', desc: 'Aufgabe mit Checkbox', icon: <ListTodo className="w-3.5 h-3.5" /> },
|
||||
{ type: 'numbered', label: '/number', desc: 'Nummerierte Liste (1., a., i.)', icon: <ListOrdered className="w-3.5 h-3.5" />, aliases: ['nummer', 'liste', 'ol'] },
|
||||
@@ -209,6 +212,28 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
||||
const [showLinkModal, setShowLinkModal] = useState<boolean>(false);
|
||||
const [showTodoMenu, setShowTodoMenu] = useState<boolean>(false);
|
||||
|
||||
// Action bubble with a real pointer: shown only while the mouse moves over the row (until a moment after
|
||||
// the last move), while it rests on the bubble or a menu of it is open; a resting mouse must not leave it
|
||||
// over the text. Touch devices keep showing it at the focused bullet.
|
||||
const hasHover = useMemo(() => typeof window !== 'undefined' && !!window.matchMedia?.('(hover: hover)').matches, []);
|
||||
const [pointerMoving, setPointerMoving] = useState(false);
|
||||
const [pointerOnBubble, setPointerOnBubble] = useState(false);
|
||||
const pointerIdleTimerRef = useRef<number | null>(null);
|
||||
const handleRowMouseMove = () => {
|
||||
if (!hasHover) return;
|
||||
setPointerMoving(true);
|
||||
if (pointerIdleTimerRef.current !== null) window.clearTimeout(pointerIdleTimerRef.current);
|
||||
pointerIdleTimerRef.current = window.setTimeout(() => setPointerMoving(false), BUBBLE_IDLE_MS);
|
||||
};
|
||||
const handleRowMouseLeave = () => {
|
||||
if (pointerIdleTimerRef.current !== null) window.clearTimeout(pointerIdleTimerRef.current);
|
||||
pointerIdleTimerRef.current = null;
|
||||
setPointerMoving(false);
|
||||
};
|
||||
useEffect(() => () => {
|
||||
if (pointerIdleTimerRef.current !== null) window.clearTimeout(pointerIdleTimerRef.current);
|
||||
}, []);
|
||||
|
||||
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
const debounceTimerRef = useRef<number | null>(null);
|
||||
const latestBlockRef = useRef<DocumentBlock>(block);
|
||||
@@ -1087,9 +1112,13 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
||||
const isEmpty = (!localContent || localContent.trim() === '') && !hasChildren;
|
||||
|
||||
|
||||
const showBubble = hasHover ? pointerMoving || pointerOnBubble || showTodoMenu : activeFocus;
|
||||
|
||||
return (
|
||||
<div
|
||||
data-outline-block={block.id}
|
||||
onMouseMove={handleRowMouseMove}
|
||||
onMouseLeave={handleRowMouseLeave}
|
||||
className={`group relative flex items-start gap-1 py-1 px-0.5 sm:px-1.5 rounded-card transition-all duration-300 ${
|
||||
inRangeSelection ? 'bg-accent/15' : ''
|
||||
} ${
|
||||
@@ -1595,11 +1624,13 @@ export const OutlinerBlock: React.FC<OutlinerBlockProps> = ({
|
||||
|
||||
{/* Floating Actions Overlay Bubble (Zoom, Auslagern, Löschen, TODO-Menü, Text-Umwandlung) */}
|
||||
<div
|
||||
onMouseEnter={() => setPointerOnBubble(true)}
|
||||
onMouseLeave={() => setPointerOnBubble(false)}
|
||||
className={`absolute right-1 sm:right-2 top-0.5 sm:top-1 z-20 bg-panel/90 backdrop-blur-sm border border-border shadow-xs rounded-pill px-1 sm:px-1.5 py-0.5 flex items-center gap-0.5 sm:gap-1 transition-opacity ${
|
||||
activeFocus
|
||||
showBubble
|
||||
? 'opacity-100 pointer-events-auto'
|
||||
: // Hover only with a real pointer: a tap on a phone would make the invisible buttons clickable
|
||||
'opacity-0 [@media(hover:hover)]:group-hover:opacity-100 focus-within:opacity-100 pointer-events-none [@media(hover:hover)]:group-hover:pointer-events-auto focus-within:pointer-events-auto'
|
||||
: // Hidden buttons must not take clicks; keyboard focus inside still shows it
|
||||
'opacity-0 pointer-events-none focus-within:opacity-100 focus-within:pointer-events-auto'
|
||||
}`}
|
||||
>
|
||||
{/* Convert back to bullet for headings, callouts, dividers, code and numbered items */}
|
||||
|
||||
Reference in new issue
Block a user