refactor(app): Sticky-Note durch Widget-System ersetzen
Migration alter Sticky-Daten in das neue Widget-System, Notes.init() statt initStickyNote(), Toolbar-Position in Settings, JSON-Export/Import um Notes erweitert, Onboarding-Text aktualisiert.
This commit is contained in:
+45
-2
@@ -16,7 +16,8 @@ async function init() {
|
|||||||
bindGlobalEvents();
|
bindGlobalEvents();
|
||||||
bindSettingsEvents();
|
bindSettingsEvents();
|
||||||
initSearch();
|
initSearch();
|
||||||
initStickyNote();
|
await migrateSticky();
|
||||||
|
await Notes.init();
|
||||||
initDataButtons();
|
initDataButtons();
|
||||||
Store.checkQuota();
|
Store.checkQuota();
|
||||||
|
|
||||||
@@ -30,6 +31,46 @@ async function init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- STICKY NOTE MIGRATION ----
|
||||||
|
async function migrateSticky() {
|
||||||
|
const stickyText = await Store.get('stickyNote');
|
||||||
|
const stickyPos = await Store.get('stickyPos');
|
||||||
|
const existingWidgets = await Store.get('widgetStates');
|
||||||
|
|
||||||
|
// Nur migrieren wenn alte Daten vorhanden UND noch keine Widgets existieren
|
||||||
|
if (!stickyText && !stickyPos) return;
|
||||||
|
if (existingWidgets && Array.isArray(existingWidgets.notes) && existingWidgets.notes.length > 0) return;
|
||||||
|
|
||||||
|
const noteData = {
|
||||||
|
id: 'note_' + uid(),
|
||||||
|
title: (stickyText || '').split('\n')[0].trim().slice(0, 20) || 'Note',
|
||||||
|
content: stickyText || '',
|
||||||
|
template: 'text',
|
||||||
|
x: stickyPos ? stickyPos.x : 120,
|
||||||
|
y: stickyPos ? stickyPos.y : 80,
|
||||||
|
width: 280,
|
||||||
|
height: 220,
|
||||||
|
open: true,
|
||||||
|
checkedItems: [],
|
||||||
|
checklistItems: []
|
||||||
|
};
|
||||||
|
|
||||||
|
await Store.set('widgetStates', { notes: [noteData] });
|
||||||
|
|
||||||
|
// Alte Keys aufraeumen
|
||||||
|
try {
|
||||||
|
if (typeof chrome !== 'undefined' && chrome.storage) {
|
||||||
|
chrome.storage.local.remove(['stickyNote', 'stickyPos', 'stickyVisible']);
|
||||||
|
} else {
|
||||||
|
localStorage.removeItem('stickyNote');
|
||||||
|
localStorage.removeItem('stickyPos');
|
||||||
|
localStorage.removeItem('stickyVisible');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Sticky-Migration: Alte Keys konnten nicht entfernt werden', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- BACKUP REMINDER ----
|
// ---- BACKUP REMINDER ----
|
||||||
const BACKUP_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000; // 7 Tage
|
const BACKUP_INTERVAL_MS = 7 * 24 * 60 * 60 * 1000; // 7 Tage
|
||||||
|
|
||||||
@@ -55,7 +96,9 @@ async function checkBackupReminder() {
|
|||||||
|
|
||||||
if (doBackup) {
|
if (doBackup) {
|
||||||
// JSON-Export auslösen (gleiche Logik wie btnExportJSON)
|
// JSON-Export auslösen (gleiche Logik wie btnExportJSON)
|
||||||
const data = { version: '1.5.2', exported: new Date().toISOString(), boards, settings };
|
const widgetData = await Store.get('widgetStates');
|
||||||
|
const notesData = (widgetData && Array.isArray(widgetData.notes)) ? widgetData.notes : [];
|
||||||
|
const data = { version: '1.6.0', exported: new Date().toISOString(), boards, settings, notes: notesData };
|
||||||
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
|||||||
+34
-4
@@ -9,9 +9,16 @@ function initDataButtons() {
|
|||||||
const jsonInput = document.getElementById('jsonImportInput');
|
const jsonInput = document.getElementById('jsonImportInput');
|
||||||
if (!btnExport || !btnImport) return;
|
if (!btnExport || !btnImport) return;
|
||||||
|
|
||||||
// Export
|
// Export (inkl. Notes)
|
||||||
btnExport.addEventListener('click', () => {
|
btnExport.addEventListener('click', async () => {
|
||||||
const data = { version: '1.5.2', exported: new Date().toISOString(), boards, settings };
|
const widgetData = await Store.get('widgetStates');
|
||||||
|
const data = {
|
||||||
|
version: '1.6.0',
|
||||||
|
exported: new Date().toISOString(),
|
||||||
|
boards,
|
||||||
|
settings,
|
||||||
|
notes: widgetData && Array.isArray(widgetData.notes) ? widgetData.notes : []
|
||||||
|
};
|
||||||
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
@@ -50,8 +57,31 @@ function initDataButtons() {
|
|||||||
boards = [...boards, ...validBoards];
|
boards = [...boards, ...validBoards];
|
||||||
await saveBoards();
|
await saveBoards();
|
||||||
renderBoards();
|
renderBoards();
|
||||||
|
|
||||||
|
// Notes importieren (falls vorhanden)
|
||||||
|
let notesImported = 0;
|
||||||
|
if (Array.isArray(data.notes) && data.notes.length > 0) {
|
||||||
|
const existingWidgets = await Store.get('widgetStates');
|
||||||
|
const existingNotes = (existingWidgets && Array.isArray(existingWidgets.notes)) ? existingWidgets.notes : [];
|
||||||
|
const importNotes = data.notes.filter(n => {
|
||||||
|
if (!n || !n.id || !n.template) return false;
|
||||||
|
n.checklistItems = Array.isArray(n.checklistItems) ? n.checklistItems : [];
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
// Limit beachten
|
||||||
|
const spaceLeft = Notes.MAX_NOTES - existingNotes.length;
|
||||||
|
const toImport = importNotes.slice(0, spaceLeft);
|
||||||
|
if (toImport.length > 0) {
|
||||||
|
const merged = [...existingNotes, ...toImport];
|
||||||
|
await Store.set('widgetStates', { notes: merged });
|
||||||
|
Notes._notes = merged;
|
||||||
|
notesImported = toImport.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const noteMsg = notesImported > 0 ? ` + ${notesImported} Note(s)` : '';
|
||||||
await HellionDialog.alert(
|
await HellionDialog.alert(
|
||||||
`${validBoards.length} Board(s) erfolgreich importiert.`,
|
`${validBoards.length} Board(s)${noteMsg} erfolgreich importiert.`,
|
||||||
{ type: 'success', title: 'Import erfolgreich' }
|
{ type: 'success', title: 'Import erfolgreich' }
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ const Onboarding = {
|
|||||||
title: 'Weitere Features',
|
title: 'Weitere Features',
|
||||||
features: [
|
features: [
|
||||||
'Suchleiste mit Google, DuckDuckGo oder Bing',
|
'Suchleiste mit Google, DuckDuckGo oder Bing',
|
||||||
'Sticky Notes f\u00FCr schnelle Notizen',
|
'Widget-Toolbar rechts \u2014 Notes und Checklisten erstellen',
|
||||||
|
'Notebook-Sidebar \u00FCber den \u201ENote\u201C Button oder die Toolbar',
|
||||||
'Funktioniert komplett offline \u2014 alles lokal gespeichert'
|
'Funktioniert komplett offline \u2014 alles lokal gespeichert'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
+18
-2
@@ -25,7 +25,7 @@ function closeThemeModal() {
|
|||||||
|
|
||||||
// ---- ACCORDION ----
|
// ---- ACCORDION ----
|
||||||
function initAccordion() {
|
function initAccordion() {
|
||||||
const defaultOpen = new Set(['appearance', 'behavior', 'data', 'help']);
|
const defaultOpen = new Set(['appearance', 'behavior', 'widgets', 'data', 'help']);
|
||||||
const sections = document.querySelectorAll('.settings-section[data-section]');
|
const sections = document.querySelectorAll('.settings-section[data-section]');
|
||||||
|
|
||||||
sections.forEach(section => {
|
sections.forEach(section => {
|
||||||
@@ -71,6 +71,11 @@ function applySettings() {
|
|||||||
const showSearchEl = document.getElementById('settingShowSearch');
|
const showSearchEl = document.getElementById('settingShowSearch');
|
||||||
if (showSearchEl) showSearchEl.checked = settings.showSearch;
|
if (showSearchEl) showSearchEl.checked = settings.showSearch;
|
||||||
|
|
||||||
|
// Toolbar-Position
|
||||||
|
document.body.classList.toggle('toolbar-left', settings.toolbarPos === 'left');
|
||||||
|
const toolbarPosEl = document.getElementById('settingToolbarPos');
|
||||||
|
if (toolbarPosEl) toolbarPosEl.value = settings.toolbarPos || 'right';
|
||||||
|
|
||||||
applyTheme(settings.theme || 'nebula', !!settings.bgUrl);
|
applyTheme(settings.theme || 'nebula', !!settings.bgUrl);
|
||||||
|
|
||||||
if (settings.bgUrl) {
|
if (settings.bgUrl) {
|
||||||
@@ -172,6 +177,17 @@ function bindSettingsEvents() {
|
|||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Toolbar-Position Setting
|
||||||
|
const toolbarPosEl = document.getElementById('settingToolbarPos');
|
||||||
|
if (toolbarPosEl) {
|
||||||
|
toolbarPosEl.value = settings.toolbarPos || 'right';
|
||||||
|
toolbarPosEl.addEventListener('change', async (e) => {
|
||||||
|
settings.toolbarPos = e.target.value;
|
||||||
|
document.body.classList.toggle('toolbar-left', e.target.value === 'left');
|
||||||
|
await saveSettings();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Onboarding wiederholen
|
// Onboarding wiederholen
|
||||||
document.getElementById('btnRestartOnboarding').addEventListener('click', () => {
|
document.getElementById('btnRestartOnboarding').addEventListener('click', () => {
|
||||||
closeSettings();
|
closeSettings();
|
||||||
@@ -188,7 +204,7 @@ function bindSettingsEvents() {
|
|||||||
boards = [];
|
boards = [];
|
||||||
settings = { compact: false, shortenTitles: false, newTab: true, showDesc: false,
|
settings = { compact: false, shortenTitles: false, newTab: true, showDesc: false,
|
||||||
hideExtra: false, visibleCount: 10, bgUrl: '', theme: 'nebula',
|
hideExtra: false, visibleCount: 10, bgUrl: '', theme: 'nebula',
|
||||||
showSearch: true, searchEngine: 'google' };
|
showSearch: true, searchEngine: 'google', toolbarPos: 'right' };
|
||||||
await saveBoards();
|
await saveBoards();
|
||||||
await saveSettings();
|
await saveSettings();
|
||||||
applySettings();
|
applySettings();
|
||||||
|
|||||||
+2
-1
@@ -15,7 +15,8 @@ let settings = {
|
|||||||
bgUrl: '',
|
bgUrl: '',
|
||||||
theme: 'nebula',
|
theme: 'nebula',
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
searchEngine: 'google'
|
searchEngine: 'google',
|
||||||
|
toolbarPos: 'right'
|
||||||
};
|
};
|
||||||
|
|
||||||
function uid() {
|
function uid() {
|
||||||
|
|||||||
Reference in New Issue
Block a user