Skip to content
Merged
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
4 changes: 2 additions & 2 deletions desktop-app/neutralino.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/neutralinojs/neutralinojs/main/schemas/neutralino.config.schema.json",
"applicationId": "js.neutralino.sample",
"applicationId": "com.markdownviewer.desktop",
"version": "1.0.0",
"defaultMode": "window",
"port": 0,
Expand All @@ -13,7 +13,7 @@
"enabled": true,
"writeToLogFile": true
},
"nativeAllowList": ["app.*", "os.*", "filesystem.readFile", "debug.log"],
"nativeAllowList": ["app.*", "os.*", "filesystem.*", "debug.log"],
"globalVariables": {},
"modes": {
"window": {
Expand Down
2 changes: 1 addition & 1 deletion desktop-app/prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ html = html.replace(/href="assets\//g, 'href="/assets/');
html = html.replace(/href="styles\.css"/g, 'href="/styles.css"');
/** Replace root script.js tag with neutralino.js + main.js + script.js under /js/ */
html = html.replace(
/<script src="script\.js"><\/script>/,
/<script\s+src="script\.js"\s*><\/script>/i,
'<script src="/js/neutralino.js"></script>\n <script src="/js/main.js"></script>\n <script src="/js/script.js"></script>',
);

Expand Down
47 changes: 46 additions & 1 deletion desktop-app/resources/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,51 @@ <h3 class="modal-section-title">Open-source credits</h3>
</div>
</div>

<!-- Share Modal -->
<div id="share-modal" class="reset-modal-overlay modal-overlay" role="dialog" aria-modal="true" aria-labelledby="share-modal-title" aria-hidden="true" style="display:none;">
<div class="reset-modal-box reset-modal-box--wide modal-box">
<div class="modal-header">
<p id="share-modal-title" class="reset-modal-message">Share Document</p>
<button type="button" class="modal-close-btn" id="share-modal-close-icon" aria-label="Close share dialog">
<i class="bi bi-x-lg"></i>
</button>
</div>
<div class="modal-body">
<p class="share-modal-description">Choose how recipients can interact with this document.</p>
<div class="share-mode-cards">
<label class="share-mode-card" id="share-card-view" for="share-mode-view">
<input type="radio" id="share-mode-view" name="share-mode" value="view" checked />
<span class="share-card-icon"><i class="bi bi-eye"></i></span>
<span class="share-card-body">
<span class="share-card-title">View only</span>
<span class="share-card-desc">Opens in preview mode. The editor is hidden.</span>
</span>
<span class="share-card-check"><i class="bi bi-check-lg"></i></span>
</label>
<label class="share-mode-card" id="share-card-edit" for="share-mode-edit">
<input type="radio" id="share-mode-edit" name="share-mode" value="edit" />
<span class="share-card-icon"><i class="bi bi-pencil-square"></i></span>
<span class="share-card-body">
<span class="share-card-title">Edit</span>
<span class="share-card-desc">Opens in split editor + preview mode.</span>
</span>
<span class="share-card-check"><i class="bi bi-check-lg"></i></span>
</label>
</div>
<div class="share-url-row">
<input type="text" id="share-url-input" class="rename-modal-input share-url-input" readonly placeholder="Generating link…" aria-label="Share URL" />
<button class="reset-modal-btn share-copy-btn" id="share-copy-btn" title="Copy link">
<i class="bi bi-clipboard"></i>
</button>
</div>
<p class="share-modal-notice"><i class="bi bi-info-circle"></i> The entire document is encoded in the URL. No data is sent to any server.</p>
</div>
<div class="reset-modal-actions">
<button class="reset-modal-btn reset-modal-cancel" id="share-modal-close">Close</button>
</div>
</div>
</div>

<!-- Rename Modal -->
<div id="rename-modal" class="reset-modal-overlay" role="dialog" aria-modal="true" aria-labelledby="rename-modal-title" style="display:none;">
<div class="reset-modal-box reset-modal-box--wide">
Expand Down Expand Up @@ -722,4 +767,4 @@ <h3 class="modal-section-title">Open-source credits</h3>
<script src="/js/main.js"></script>
<script src="/js/script.js"></script>
</body>
</html>
</html>
51 changes: 28 additions & 23 deletions desktop-app/resources/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ function openTutorial() {
*/
function setTray() {
// Tray menu is only available in window mode
if (NL_MODE != "window") {
if (typeof NL_MODE === "undefined" || NL_MODE != "window") {
console.log("INFO: Tray menu is only available in the window mode.");
return;
}

// Define tray menu items
let tray = {
icon: "/resources/icons/trayIcon.png",
icon: "/resources/assets/icon.jpg",
menuItems: [
{ id: "VERSION", text: "Get version" },
{ id: "SEP", text: "-" },
Expand All @@ -54,7 +54,11 @@ function setTray() {
};

// Set the tray menu
Neutralino.os.setTray(tray);
try {
Neutralino.os.setTray(tray);
} catch (e) {
console.warn("Failed to set system tray:", e);
}
}

/*
Expand Down Expand Up @@ -85,39 +89,40 @@ function onWindowClose() {
Neutralino.app.exit();
}

// Initialize Neutralino
Neutralino.init();
// Initialize Neutralino if in native environment
if (typeof Neutralino !== 'undefined') {
Neutralino.init();

// Register event listeners
Neutralino.events.on("trayMenuItemClicked", onTrayMenuItemClicked);
Neutralino.events.on("windowClose", onWindowClose);
// Register event listeners
Neutralino.events.on("trayMenuItemClicked", onTrayMenuItemClicked);
Neutralino.events.on("windowClose", onWindowClose);

// Conditional initialization: Set up system tray if not running on macOS
if (NL_OS != "Darwin") {
// TODO: Fix https://github.com/neutralinojs/neutralinojs/issues/615
setTray();
// Conditional initialization: Set up system tray if not running on macOS
if (typeof NL_OS !== 'undefined' && NL_OS != "Darwin") {
// TODO: Fix https://github.com/neutralinojs/neutralinojs/issues/615
setTray();
}
}

// Open file passed as command-line argument (e.g. when double-clicking a .md file)
(async function loadInitialFile() {
if (typeof Neutralino === 'undefined' || typeof NL_ARGS === 'undefined') return;
const args = Array.isArray(NL_ARGS) ? NL_ARGS : (() => { try { return JSON.parse(NL_ARGS); } catch(e) { return []; } })();
const filePath = args.find(a => typeof a === 'string' && /\.(md|markdown)$/i.test(a));
if (!filePath) return;

try {
const content = await Neutralino.filesystem.readFile(filePath);
const fileName = filePath.split(/[/\\]/).pop().replace(/\.(md|markdown)$/i, '');

window.NL_INITIAL_FILE_CONTENT = {
name: fileName,
content: content
};

function applyContent() {
const editor = document.getElementById('markdown-editor');
if (!editor) return;
editor.value = content;
editor.dispatchEvent(new Event('input'));
}

if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', applyContent);
} else {
setTimeout(applyContent, 0);
// Callback hook in case script.js loaded first
if (window.NL_IMPORT_EXTERNAL_FILE) {
window.NL_IMPORT_EXTERNAL_FILE(content, fileName);
}
} catch (e) {
console.warn('Could not open initial file:', e);
Expand Down
Loading
Loading