Compare commits
2 Commits
f41c90c8dc
...
7bac69be6d
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bac69be6d | |||
| 4dfd4d51aa |
@@ -7,6 +7,12 @@
|
|||||||
"core:event:default",
|
"core:event:default",
|
||||||
"core:window:default",
|
"core:window:default",
|
||||||
"core:window:allow-set-title",
|
"core:window:allow-set-title",
|
||||||
|
"core:window:allow-start-dragging",
|
||||||
|
"core:window:allow-minimize",
|
||||||
|
"core:window:allow-maximize",
|
||||||
|
"core:window:allow-unmaximize",
|
||||||
|
"core:window:allow-is-maximized",
|
||||||
|
"core:window:allow-close",
|
||||||
"core:app:default",
|
"core:app:default",
|
||||||
"core:webview:default",
|
"core:webview:default",
|
||||||
"fs:read-all",
|
"fs:read-all",
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
"label": "main",
|
"label": "main",
|
||||||
"title": "Pena — Markdown Viewer",
|
"title": "Pena — Markdown Viewer",
|
||||||
"width": 1280,
|
"width": 1280,
|
||||||
"height": 800
|
"height": 800,
|
||||||
|
"decorations": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
@@ -11,6 +11,15 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div id="titlebar">
|
||||||
|
<span id="titlebar-title">Pena — Markdown Viewer</span>
|
||||||
|
<div class="titlebar-controls">
|
||||||
|
<button id="titlebar-minimize" title="Réduire">─</button>
|
||||||
|
<button id="titlebar-maximize" title="Agrandir">▢</button>
|
||||||
|
<button id="titlebar-close" title="Fermer">✕</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="view-home">
|
<div id="view-home">
|
||||||
<h1 class="home-title">Pena</h1>
|
<h1 class="home-title">Pena</h1>
|
||||||
<div class="home-buttons">
|
<div class="home-buttons">
|
||||||
@@ -30,7 +39,23 @@
|
|||||||
<div id="content" class="content">
|
<div id="content" class="content">
|
||||||
<!-- contenu généré par JS -->
|
<!-- contenu généré par JS -->
|
||||||
</div>
|
</div>
|
||||||
|
<button id="btn-customize-css" class="btn-customize-css">
|
||||||
|
<span class="btn-customize-css__icon">⊕</span>
|
||||||
|
Personnaliser le CSS
|
||||||
|
</button>
|
||||||
<button id="btn-back" class="btn-back">← Accueil</button>
|
<button id="btn-back" class="btn-back">← Accueil</button>
|
||||||
|
|
||||||
|
<div id="css-editor-panel" class="css-editor-panel hidden">
|
||||||
|
<div class="css-editor-panel__header">
|
||||||
|
<span>CSS personnalisé</span>
|
||||||
|
<button id="btn-css-close" class="css-editor-panel__close">✕</button>
|
||||||
|
</div>
|
||||||
|
<textarea id="css-editor" class="css-editor__textarea" placeholder="/* Entrez votre CSS personnalisé ici */ /* Exemple : .content { font-size: 18px; } */"></textarea>
|
||||||
|
<div class="css-editor-panel__footer">
|
||||||
|
<button id="btn-css-reset" class="css-editor-panel__btn css-editor-panel__btn--secondary">Réinitialiser</button>
|
||||||
|
<button id="btn-css-apply" class="css-editor-panel__btn css-editor-panel__btn--primary">Appliquer</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="main.js" type="module"></script>
|
<script src="main.js" type="module"></script>
|
||||||
|
|||||||
+79
-5
@@ -1,6 +1,21 @@
|
|||||||
let currentPath = null;
|
let currentPath = null;
|
||||||
let currentMode = null; // 'file' | 'dir'
|
let currentMode = null; // 'file' | 'dir'
|
||||||
|
|
||||||
|
const titlebarTitle = document.getElementById('titlebar-title');
|
||||||
|
const win = window.__TAURI__.window.getCurrentWindow();
|
||||||
|
|
||||||
|
document.getElementById('titlebar').addEventListener('mousedown', (e) => {
|
||||||
|
if (e.target.closest('.titlebar-controls')) return;
|
||||||
|
if (e.buttons === 1) win.startDragging();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('titlebar-minimize').addEventListener('click', () => win.minimize());
|
||||||
|
document.getElementById('titlebar-maximize').addEventListener('click', async () => {
|
||||||
|
if (await win.isMaximized()) win.unmaximize();
|
||||||
|
else win.maximize();
|
||||||
|
});
|
||||||
|
document.getElementById('titlebar-close').addEventListener('click', () => win.close());
|
||||||
|
|
||||||
const viewHome = document.getElementById('view-home');
|
const viewHome = document.getElementById('view-home');
|
||||||
const viewReader = document.getElementById('view-reader');
|
const viewReader = document.getElementById('view-reader');
|
||||||
const sidebar = document.querySelector('#sidebar');
|
const sidebar = document.querySelector('#sidebar');
|
||||||
@@ -165,9 +180,10 @@ async function loadPage(filePath) {
|
|||||||
|
|
||||||
const basename = filePath.split('/').pop().split('\\').pop();
|
const basename = filePath.split('/').pop().split('\\').pop();
|
||||||
const title = basename.replace(/\.md$/i, '');
|
const title = basename.replace(/\.md$/i, '');
|
||||||
await window.__TAURI__.window.getCurrentWindow().setTitle(title);
|
await win.setTitle(title);
|
||||||
|
titlebarTitle.textContent = title;
|
||||||
|
|
||||||
if (currentMode === 'dir') {
|
if (currentMode === 'dir' || currentMode === 'file') {
|
||||||
sidebar.querySelectorAll('a').forEach(a => {
|
sidebar.querySelectorAll('a').forEach(a => {
|
||||||
a.classList.toggle('active', a.dataset.path === filePath);
|
a.classList.toggle('active', a.dataset.path === filePath);
|
||||||
});
|
});
|
||||||
@@ -191,10 +207,19 @@ async function openPath(path, mode) {
|
|||||||
saveRecent(path, mode);
|
saveRecent(path, mode);
|
||||||
|
|
||||||
if (mode === 'file') {
|
if (mode === 'file') {
|
||||||
sidebar.innerHTML = '';
|
|
||||||
sidebar.classList.add('hidden');
|
|
||||||
content.style.marginLeft = '0';
|
|
||||||
showReader();
|
showReader();
|
||||||
|
const sep = path.includes('\\') ? '\\' : '/';
|
||||||
|
const parentDir = path.split(sep).slice(0, -1).join(sep);
|
||||||
|
try {
|
||||||
|
const files = await window.__TAURI__.core.invoke('list_md_files', { dir: parentDir });
|
||||||
|
sidebar.classList.remove('hidden');
|
||||||
|
content.style.marginLeft = '';
|
||||||
|
renderSidebar(parentDir, files, path);
|
||||||
|
} catch {
|
||||||
|
sidebar.innerHTML = '';
|
||||||
|
sidebar.classList.add('hidden');
|
||||||
|
content.style.marginLeft = '0';
|
||||||
|
}
|
||||||
await loadPage(path);
|
await loadPage(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -243,5 +268,54 @@ document.getElementById('btn-back').addEventListener('click', () => {
|
|||||||
currentPath = null;
|
currentPath = null;
|
||||||
currentMode = null;
|
currentMode = null;
|
||||||
sidebar.innerHTML = '';
|
sidebar.innerHTML = '';
|
||||||
|
win.setTitle('Pena — Markdown Viewer');
|
||||||
|
titlebarTitle.textContent = 'Pena — Markdown Viewer';
|
||||||
showHome();
|
showHome();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── CSS personnalisé ──
|
||||||
|
const CSS_STORAGE_KEY = 'pena_custom_css';
|
||||||
|
|
||||||
|
function applyCustomCss(css) {
|
||||||
|
let styleEl = document.getElementById('pena-custom-style');
|
||||||
|
if (!styleEl) {
|
||||||
|
styleEl = document.createElement('style');
|
||||||
|
styleEl.id = 'pena-custom-style';
|
||||||
|
document.head.appendChild(styleEl);
|
||||||
|
}
|
||||||
|
styleEl.textContent = css;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCustomCss() {
|
||||||
|
return localStorage.getItem(CSS_STORAGE_KEY) ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedCss = loadCustomCss();
|
||||||
|
if (savedCss) applyCustomCss(savedCss);
|
||||||
|
|
||||||
|
const btnCustomizeCss = document.getElementById('btn-customize-css');
|
||||||
|
const cssEditorPanel = document.getElementById('css-editor-panel');
|
||||||
|
const cssEditor = document.getElementById('css-editor');
|
||||||
|
|
||||||
|
cssEditor.value = loadCustomCss();
|
||||||
|
|
||||||
|
btnCustomizeCss.addEventListener('click', () => {
|
||||||
|
cssEditorPanel.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('btn-css-close').addEventListener('click', () => {
|
||||||
|
cssEditorPanel.classList.add('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('btn-css-apply').addEventListener('click', () => {
|
||||||
|
const css = cssEditor.value.trim();
|
||||||
|
applyCustomCss(css);
|
||||||
|
localStorage.setItem(CSS_STORAGE_KEY, css);
|
||||||
|
cssEditorPanel.classList.add('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('btn-css-reset').addEventListener('click', () => {
|
||||||
|
cssEditor.value = '';
|
||||||
|
applyCustomCss('');
|
||||||
|
localStorage.removeItem(CSS_STORAGE_KEY);
|
||||||
|
});
|
||||||
|
|||||||
+187
-6
@@ -11,6 +11,64 @@ body {
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Titlebar ── */
|
||||||
|
#titlebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 36px;
|
||||||
|
background: #1a1b2e;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 200;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#titlebar-title {
|
||||||
|
color: rgba(255,255,255,0.5);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar-controls {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 36px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar-controls button {
|
||||||
|
width: 46px;
|
||||||
|
height: 36px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: rgba(255,255,255,0.45);
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: background 0.15s, color 0.15s;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titlebar-controls button:hover {
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
color: rgba(255,255,255,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#titlebar-close:hover {
|
||||||
|
background: #e81123 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* ── Utility ── */
|
/* ── Utility ── */
|
||||||
.hidden { display: none !important; }
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
@@ -21,6 +79,7 @@ body {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
padding-top: 36px;
|
||||||
background: #1a1b2e;
|
background: #1a1b2e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,10 +196,10 @@ body {
|
|||||||
/* ── Sidebar ── */
|
/* ── Sidebar ── */
|
||||||
.sidebar {
|
.sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 36px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 264px;
|
width: 264px;
|
||||||
height: 100vh;
|
height: calc(100vh - 36px);
|
||||||
background: #1a1b2e;
|
background: #1a1b2e;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -148,7 +207,7 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.sidebar__title-block {
|
.sidebar__title-block {
|
||||||
margin: 48px 24px 8px;
|
margin: 32px 24px 8px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.sidebar__title-block a {
|
.sidebar__title-block a {
|
||||||
@@ -320,7 +379,10 @@ body {
|
|||||||
/* ── Content ── */
|
/* ── Content ── */
|
||||||
.content {
|
.content {
|
||||||
margin-left: 264px;
|
margin-left: 264px;
|
||||||
padding: 48px 72px 96px;
|
padding-top: 84px;
|
||||||
|
padding-right: 72px;
|
||||||
|
padding-bottom: 96px;
|
||||||
|
padding-left: 72px;
|
||||||
max-width: 1080px;
|
max-width: 1080px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -395,12 +457,131 @@ body {
|
|||||||
}
|
}
|
||||||
.content ul li code, .content ol li code { font-weight: 700; }
|
.content ul li code, .content ol li code { font-weight: 700; }
|
||||||
|
|
||||||
|
/* ── Customize CSS button ── */
|
||||||
|
.btn-customize-css {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 60px;
|
||||||
|
left: 12px;
|
||||||
|
width: 240px;
|
||||||
|
z-index: 100;
|
||||||
|
background: transparent;
|
||||||
|
color: rgba(255,255,255,0.7);
|
||||||
|
border: 1px solid rgba(255,255,255,0.15);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
transition: color 0.2s, border-color 0.2s, background 0.2s;
|
||||||
|
}
|
||||||
|
.btn-customize-css:hover {
|
||||||
|
color: #fff;
|
||||||
|
border-color: rgba(255,255,255,0.35);
|
||||||
|
background: rgba(255,255,255,0.06);
|
||||||
|
}
|
||||||
|
.btn-customize-css__icon {
|
||||||
|
font-size: 15px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── CSS editor panel ── */
|
||||||
|
.css-editor-panel {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 120px;
|
||||||
|
left: 12px;
|
||||||
|
width: 240px;
|
||||||
|
background: #12132a;
|
||||||
|
border: 1px solid rgba(255,255,255,0.15);
|
||||||
|
border-radius: 10px;
|
||||||
|
z-index: 101;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
box-shadow: 0 8px 32px rgba(0,0,0,0.5);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.css-editor-panel__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 14px;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.08);
|
||||||
|
color: rgba(255,255,255,0.7);
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
}
|
||||||
|
.css-editor-panel__close {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
color: rgba(255,255,255,0.4);
|
||||||
|
font-size: 13px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: color 0.15s, background 0.15s;
|
||||||
|
}
|
||||||
|
.css-editor-panel__close:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
.css-editor__textarea {
|
||||||
|
width: 100%;
|
||||||
|
height: 180px;
|
||||||
|
background: #0e0f24;
|
||||||
|
border: none;
|
||||||
|
color: rgba(255,255,255,0.8);
|
||||||
|
font-family: 'Roboto Mono', monospace;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 12px;
|
||||||
|
resize: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.css-editor__textarea::placeholder {
|
||||||
|
color: rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
.css-editor-panel__footer {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-top: 1px solid rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
.css-editor-panel__btn {
|
||||||
|
flex: 1;
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.15s;
|
||||||
|
}
|
||||||
|
.css-editor-panel__btn--primary {
|
||||||
|
background: #ff5577;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.css-editor-panel__btn--primary:hover { background: #ff3355; }
|
||||||
|
.css-editor-panel__btn--secondary {
|
||||||
|
background: rgba(255,255,255,0.08);
|
||||||
|
color: rgba(255,255,255,0.7);
|
||||||
|
}
|
||||||
|
.css-editor-panel__btn--secondary:hover { background: rgba(255,255,255,0.14); }
|
||||||
|
|
||||||
/* ── Back button ── */
|
/* ── Back button ── */
|
||||||
.btn-back {
|
.btn-back {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 24px;
|
bottom: 24px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 264px;
|
width: 264px;
|
||||||
|
z-index: 98;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: rgba(255,255,255,0.45);
|
color: rgba(255,255,255,0.45);
|
||||||
border: none;
|
border: none;
|
||||||
@@ -421,8 +602,8 @@ body {
|
|||||||
left: -300px;
|
left: -300px;
|
||||||
transition: left 0.2s cubic-bezier(0.09, 0.46, 0.45, 0.94);
|
transition: left 0.2s cubic-bezier(0.09, 0.46, 0.45, 0.94);
|
||||||
}
|
}
|
||||||
.content { margin-left: 0; padding: 32px 24px 64px; }
|
.content { margin-left: 0; padding: 68px 24px 64px; }
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 540px) {
|
@media screen and (max-width: 540px) {
|
||||||
.content { padding: 24px 16px 48px; }
|
.content { padding: 68px 16px 48px; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user