Skip to content

Commit 98f4f1f

Browse files
committed
- UI updates for preview plugin
- Bugfix: Launching second instance when 'open with...' option is selected
1 parent 9991440 commit 98f4f1f

4 files changed

Lines changed: 122 additions & 53 deletions

File tree

linux_clean_install.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Script to quickly fresh-install note-manager
2+
3+
# 1- Remove existing installation if exists
4+
# 2- Delete 'out' folder
5+
# 3- Run 'npm make' to create new artifact
6+
# 4- Install the newly created artifact
7+
# 5- Launch the app
8+
(sudo apt remove note-manager || true) && (rm -rf out || true) && npm run make && sudo apt install ./out/make/deb/x64/note-manager_1.0.0_amd64.deb && note-manager

src/index.css

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,31 @@ body, html {
6363

6464
width: 40vw;
6565

66-
resize: horizontal;
67-
overflow: auto;
66+
resize: both;
6867

6968
border-left: 1px solid;
69+
70+
display: flex;
71+
flex-direction: column;
72+
73+
justify-content: flex-start;
74+
align-items: center;
7075
}
7176

7277
#toolWindowHeader {
78+
width: 100%;
7379
display: flex;
7480
justify-content: space-between;
7581
border-bottom: 1px solid;
7682
}
7783

84+
#toolWindowContent {
85+
padding: 5px;
86+
width: 100%;
87+
max-height: 100%;
88+
box-sizing: border-box;
89+
}
90+
7891
#toolWindowTitle {
7992
display: flex;
8093
justify-content: space-between;
@@ -89,11 +102,6 @@ body, html {
89102
align-items: center;
90103
}
91104

92-
#toolWindowContent {
93-
padding: 5px;
94-
width: 100%;
95-
}
96-
97105
.editorToolWrapper {
98106
width: 100%;
99107
height: min-content;

src/main.ts

Lines changed: 96 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import initLoggingEventHandlers from "./ipc/LoggingEventHandlers";
44
import {EventType} from "./enums";
55
import {attachTitlebarToWindow, setupTitlebar} from "custom-electron-titlebar/main";
66
import * as Environment from "./utils/EnvironmentUtils";
7-
import {fileToTab, readEditorState} from "./utils/EditorUtils";
7+
import {fileToTab, openInWindow, readEditorState} from "./utils/EditorUtils";
88
import initIpcMainListeners from "./ipc/IpcMainListener";
99
import {initApplicationMenu, loadThemeToWindow, refreshTitlebar} from "./utils/ElectronUtils";
1010
import {EditorState} from "./domain/EditorState";
1111
import {SupportedLanguages} from './domain/SupportedLanguage';
12+
import {hash} from "./utils/TextUtils";
13+
import {isFileExists} from "./utils/FileUtils";
14+
1215

1316
setupTitlebar();
1417

@@ -32,8 +35,10 @@ process.on('unhandledRejection', (reason: any) => {
3235
logError(reason);
3336
});
3437

38+
let mainWindow: BrowserWindow;
39+
3540
const createWindow = () => {
36-
const mainWindow = new BrowserWindow({
41+
mainWindow = new BrowserWindow({
3742
width: 1440,
3843
height: 860,
3944
titleBarStyle: "hidden",
@@ -71,33 +76,9 @@ const createWindow = () => {
7176
loadThemeToWindow(mainWindow);
7277
refreshTitlebar();
7378

74-
const fileArg = getFileArgument();
75-
const activeTabId = crypto.randomUUID();
76-
let initialState: EditorState = {
77-
tabs: [{
78-
id: activeTabId,
79-
name: "New Document.txt",
80-
displayName: "New Document.txt",
81-
content: "",
82-
language: SupportedLanguages.text,
83-
}],
84-
activeTabId: activeTabId
85-
}
86-
87-
const persistentState = readEditorState();
79+
const state = await getEditorState();
8880

89-
if (persistentState) { // restore the state
90-
initialState = persistentState;
91-
}
92-
93-
if (fileArg && !initialState.tabs.map(t => t.file).includes(fileArg)) {
94-
const tab = await fileToTab(fileArg);
95-
96-
initialState.tabs.push(tab);
97-
initialState.activeTabId = tab.id;
98-
}
99-
100-
mainWindow.webContents.send(EventType.INIT_WITH_STATE, initialState);
81+
mainWindow.webContents.send(EventType.INIT_WITH_STATE, state);
10182
});
10283

10384
mainWindow.on(EventType.CLOSE_WINDOW, (event) => {
@@ -107,22 +88,84 @@ const createWindow = () => {
10788
})
10889
};
10990

110-
// This method will be called when Electron has finished
111-
// initialization and is ready to create browser windows.
112-
// Some APIs can only be used after this event occurs.
113-
app.whenReady().then(() => {
114-
Environment.loadPreferences(); // load user preferences
91+
async function getEditorState() {
92+
const fileArg = getFileArgument();
93+
94+
const tempTabId = crypto.randomUUID();
95+
let initialState: EditorState = {
96+
tabs: [{
97+
id: tempTabId,
98+
name: "New Document.txt",
99+
displayName: "New Document.txt",
100+
content: "",
101+
hash: await hash(""),
102+
language: SupportedLanguages.text,
103+
}],
104+
activeTabId: tempTabId
105+
}
106+
107+
const persistentState = readEditorState();
108+
109+
if (persistentState) { // restore the state
110+
initialState = persistentState;
111+
}
112+
113+
if (fileArg && !initialState.tabs.map(t => t.file).includes(fileArg)) {
114+
const tab = await fileToTab(fileArg);
115+
116+
initialState.tabs.push(tab);
117+
initialState.activeTabId = tab.id;
118+
}
119+
120+
return initialState;
121+
}
122+
123+
if (!app.requestSingleInstanceLock()) {
124+
app.quit(); // Quit if another instance is already running
125+
} else {
126+
app.on('second-instance', (_, argv) => {
127+
// When a second instance is launched
128+
if (mainWindow) {
129+
// Focus the existing window
130+
if (mainWindow.isMinimized()) mainWindow.restore();
131+
mainWindow.focus();
132+
133+
// Pass the file argument (e.g., argv[2] on Windows, argv[1] on macOS)
134+
const fileArg = getFileArgument(argv);
135+
if (fileArg) {
136+
openInWindow(mainWindow, fileArg);
137+
}
138+
}
139+
});
140+
141+
// This method will be called when Electron has finished
142+
// initialization and is ready to create browser windows.
143+
// Some APIs can only be used after this event occurs.
144+
app.whenReady().then(() => {
145+
Environment.loadPreferences(); // load user preferences
146+
147+
const arg = getFileArgument(); // open with...
115148

116-
createWindow();
149+
if(arg && mainWindow) {
150+
const targetWindow = mainWindow;
117151

118-
// On OS X it's common to re-create a window in the app when the
119-
// dock icon is clicked and there are no other windows open.
120-
app.on('activate', () => {
121-
if (BrowserWindow.getAllWindows().length === 0) {
152+
openInWindow(targetWindow, arg);
153+
154+
targetWindow.moveTop();
155+
targetWindow.focus();
156+
} else {
122157
createWindow();
123158
}
159+
160+
// On OS X it's common to re-create a window in the app when the
161+
// dock icon is clicked and there are no other windows open.
162+
app.on('activate', () => {
163+
if (BrowserWindow.getAllWindows().length === 0) {
164+
createWindow();
165+
}
166+
});
124167
});
125-
});
168+
}
126169

127170
// Quit when all windows are closed, except on macOS. There, it's common
128171
// for applications and their menu bar to stay active until the user quits
@@ -133,12 +176,22 @@ app.on('window-all-closed', () => {
133176
}
134177
});
135178

136-
function getFileArgument() {
137-
if (app.isPackaged && process.argv.length > 1) { // 'open with ...' option
138-
const file = process.argv[1];
179+
function getFileArgument(args?: string[]) {
180+
let result;
139181

140-
if (file && file !== "." && file !== "./") return file;
182+
const processArguments = args || process.argv;
183+
184+
if (app.isPackaged && processArguments?.length > 1) { // 'open with ...' option
185+
processArguments?.forEach((arg, idx) => {
186+
if(idx === 0) return; // pass the first argument, it is the working directory
187+
188+
if(arg && arg !== "." && arg !== "./") {
189+
if(isFileExists(arg)) result = arg;
190+
}
191+
});
141192
}
193+
194+
return result;
142195
}
143196

144197
initLoggingEventHandlers();

src/react/components/editor/plugins/PreviewPlugin.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default class PreviewPlugin implements EditorPlugin {
3939
},
4040
getToolbarWindowContent: () => {
4141
return `
42-
<div>
42+
<div style="width: 100%; height: 100%;">
4343
<style>
4444
* {
4545
font-size: 14px;
@@ -79,9 +79,9 @@ export default class PreviewPlugin implements EditorPlugin {
7979
8080
#previewContent {
8181
width: 100%;
82-
height: 100%;
82+
height: 80%;
8383
max-width: 100%;
84-
max-height: 100%;
84+
max-height: 80%;
8585
background-color: white;
8686
color: black;
8787
padding: 5px;

0 commit comments

Comments
 (0)