Skip to content

Commit 6bc7592

Browse files
committed
Add stop loading, tab restore, and omnibox improvements
Introduces a stop loading button to the navigation bar, allowing users to halt page loads. Implements tab restore functionality to reopen recently closed tabs via context menu or Ctrl+Shift+T. Enhances the omnibox and search overlay with local bookmark/history suggestions, improved favicon handling, and better search engine icon display. Updates font loading to use woff2 subsets, refines event handling for search engine changes, and optimizes webpack configs for caching and performance.
1 parent bed0a9d commit 6bc7592

File tree

25 files changed

+719
-74
lines changed

25 files changed

+719
-74
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "syra",
3-
"version": "1.4.0",
3+
"version": "2.0.0",
44
"description": "A beautiful fast custom Electron web browser built with react, styled components, typescript and electron.",
55
"author": "Revalex Technologies <revalextechnologies@gmail.com>",
66
"main": "build/main.bundle.js",

src/interfaces/types/types-electron.d.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ interface ElectronAPI {
4343

4444
getSearchSuggestions: (query: string) => Promise<string[]>;
4545

46+
getHistory: () => Promise<any[]>;
47+
getBookmarks: () => Promise<any[]>;
48+
addBookmark: (payload: {
49+
title: string;
50+
url: string;
51+
folder?: string;
52+
favicon?: string;
53+
}) => Promise<any>;
54+
updateBookmark: (
55+
id: number,
56+
updates: { title?: string; url?: string; folder?: string; favicon?: string },
57+
) => Promise<any>;
58+
removeBookmark: (id: number) => Promise<any>;
59+
removeBookmarkByUrl: (url: string) => Promise<any>;
60+
isBookmarked: (url: string) => Promise<boolean>;
61+
onBookmarksUpdated: (cb: (bookmarks: any[]) => void) => () => void;
62+
showBookmarkContextMenu: (payload: any) => void;
63+
4664
getTheme: () => Promise<'light' | 'dark' | 'system'>;
4765
setTheme: (theme: 'light' | 'dark' | 'system') => void;
4866

@@ -104,7 +122,9 @@ interface ElectronAPI {
104122

105123
showTabContextMenu: (args: { id: number; menuItems?: any }) => void;
106124

107-
getNavigationState: (id: number) => Promise<{ canGoBack: boolean; canGoForward: boolean }>;
125+
getNavigationState: (
126+
id: number,
127+
) => Promise<{ canGoBack: boolean; canGoForward: boolean; isLoading: boolean }>;
108128
}
109129

110130
declare global {

src/main/content-manager.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ export class contentManager {
111111
this.reload(id);
112112
});
113113

114+
ipcMain.on('stop-loading', (event, id: number) => {
115+
if (!isEventForThisWindow(event)) return;
116+
this.stopLoading(id);
117+
});
118+
114119
ipcMain.on('toggle-tab-audio', (event, id: number) => {
115120
if (!isEventForThisWindow(event)) return;
116121
const view = this.views.get(id);
@@ -247,6 +252,22 @@ export class contentManager {
247252
}
248253
}
249254

255+
public stopLoading(id: number) {
256+
const view = this.views.get(id);
257+
if (view && typeof (view as any).stopLoading === 'function') {
258+
try {
259+
(view as any).stopLoading();
260+
} catch {}
261+
} else if (view) {
262+
try {
263+
const wc = view.getWebContents?.();
264+
if (wc && typeof (wc as any).stop === 'function') {
265+
(wc as any).stop();
266+
}
267+
} catch {}
268+
}
269+
}
270+
250271
public getCurrentViewId(): number | null {
251272
return this.currentViewId;
252273
}

src/main/content.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,14 @@ export class CreateChildView {
677677
}
678678
}
679679

680+
public stopLoading() {
681+
if (!this.isDestroyed) {
682+
try {
683+
this.view.webContents.stop();
684+
} catch {}
685+
}
686+
}
687+
680688
public updateBounds() {
681689
if (this.isDestroyed) return;
682690
if (!this.parentWindow || this.parentWindow.isDestroyed()) return;

src/main/dialogs/search.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ export class SearchOmniboxController {
6161
} catch {}
6262
}
6363

64+
public send(channel: string, ...args: any[]) {
65+
try {
66+
if (this.view && !this.view.webContents.isDestroyed()) {
67+
this.view.webContents.send(channel, ...args);
68+
}
69+
} catch {}
70+
}
71+
6472
private ensureView() {
6573
if (this.view && !this.view.webContents.isDestroyed()) return;
6674
this.view = new WebContentsView({

src/main/index.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ export function getDownloadsList(): DownloadInfo[] {
10121012
export const contentManagers = new Map<number, contentManager>();
10131013

10141014
const findControllers = new Map<number, any>();
1015+
const searchControllers = new Map<number, SearchOmniboxController>();
10151016

10161017
app.whenReady().then(() => {
10171018
try {
@@ -1170,6 +1171,14 @@ export function setupWindowIntegration(
11701171
findControllers.set(win.id, findDialog);
11711172
const dlg = new DialogService(win);
11721173
const searchDialog = new SearchOmniboxController(win);
1174+
try {
1175+
searchControllers.set(win.id, searchDialog);
1176+
win.on('closed', () => {
1177+
try {
1178+
searchControllers.delete(win.id);
1179+
} catch {}
1180+
});
1181+
} catch {}
11731182

11741183
dlg.register('quickmenu', qm as any);
11751184
dlg.register('downloads', downloadsDialog as any);
@@ -1296,27 +1305,36 @@ ipcMain.on('reload', (event, id: number) => {
12961305
const cm = getContentManagerFor(win);
12971306
cm?.reload(id);
12981307
});
1308+
1309+
ipcMain.on('stop-loading', (event, id: number) => {
1310+
const win = BrowserWindow.fromWebContents(event.sender);
1311+
if (!win) return;
1312+
1313+
const cm: any = getContentManagerFor(win);
1314+
cm?.stopLoading?.(id);
1315+
});
12991316
ipcMain.handle('get-navigation-state', async (event, id: number) => {
13001317
const win = BrowserWindow.fromWebContents(event.sender);
13011318
if (!win) {
1302-
return { canGoBack: false, canGoForward: false };
1319+
return { canGoBack: false, canGoForward: false, isLoading: false };
13031320
}
13041321

13051322
const cm = getContentManagerFor(win);
13061323
if (!cm) {
1307-
return { canGoBack: false, canGoForward: false };
1324+
return { canGoBack: false, canGoForward: false, isLoading: false };
13081325
}
13091326

13101327
const view = cm['views']?.get(id);
13111328
if (!view) {
1312-
return { canGoBack: false, canGoForward: false };
1329+
return { canGoBack: false, canGoForward: false, isLoading: false };
13131330
}
13141331

13151332
const wc: any = __getWC(view);
13161333
const nav = wc && wc.navigationHistory;
13171334
return {
13181335
canGoBack: nav && typeof nav.canGoBack === 'function' ? !!nav.canGoBack() : false,
13191336
canGoForward: nav && typeof nav.canGoForward === 'function' ? !!nav.canGoForward() : false,
1337+
isLoading: wc && typeof wc.isLoading === 'function' ? !!wc.isLoading() : false,
13201338
};
13211339
});
13221340
ipcMain.on('get-current-url-sync', (event) => {
@@ -1480,9 +1498,17 @@ safeHandle('is-bookmarked', async (_event: Electron.IpcMainInvokeEvent, url: str
14801498
ipcMain.on('set-default-search-engine', (event: Electron.IpcMainEvent, engine: string) => {
14811499
if (typeof engine === 'string' && engine.trim().length > 0) {
14821500
setDefaultSearchEngine(engine);
1501+
const current = getDefaultSearchEngine();
14831502
BrowserWindow.getAllWindows().forEach((w) => {
1484-
__getWC(w).send('search-engine-changed', getDefaultSearchEngine());
1503+
__getWC(w).send('search-engine-changed', current);
14851504
});
1505+
try {
1506+
searchControllers.forEach((ctrl) => {
1507+
try {
1508+
ctrl.send('search-engine-changed', current);
1509+
} catch {}
1510+
});
1511+
} catch {}
14861512
}
14871513
});
14881514

src/main/useragent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function platformToken(): string {
77
}
88

99
export function getChromiumVersion(): string {
10-
return process.versions.chrome || '120.0.0.0';
10+
return process.versions.chrome || '144.0.0.0';
1111
}
1212

1313
export function buildUserAgent(): string {

src/preloads/window-preload.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ contextBridge.exposeInMainWorld('electron', {
3939
'go-back',
4040
'go-forward',
4141
'reload',
42+
'stop-loading',
4243
'create-web-contents-view',
4344
'select-web-contents-view',
4445
'close-web-contents-view',

src/renderer/constants/fonts.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { createGlobalStyle } from 'styled-components';
2-
import RobotoVar from '@/renderer/resources/fonts/Roboto/Roboto-VariableFont_wdth,wght.ttf';
3-
import RobotoVarItalic from '@/renderer/resources/fonts/Roboto/Roboto-Italic-VariableFont_wdth,wght.ttf';
2+
import RobotoVar from '@/renderer/resources/fonts/Roboto/Roboto-VariableFont_wdth,wght.subset.woff2';
3+
import RobotoVarItalic from '@/renderer/resources/fonts/Roboto/Roboto-Italic-VariableFont_wdth,wght.subset.woff2';
44

55
export const GlobalFonts = createGlobalStyle`
66
@font-face {
77
font-family: 'Roboto';
8-
src: url(${RobotoVar}) format('truetype');
8+
src: url(${RobotoVar}) format('woff2');
99
font-style: normal;
1010
font-weight: 100 900;
1111
font-display: swap;
1212
}
13-
@font-face { font-family: 'Roboto'; src: url(${RobotoVarItalic}) format('truetype'); font-style: italic; font-weight: 100 900; font-display: swap; }
13+
@font-face { font-family: 'Roboto'; src: url(${RobotoVarItalic}) format('woff2'); font-style: italic; font-weight: 100 900; font-display: swap; }
1414
:root, body { font-family: 'Roboto', system-ui, -apple-system, 'Segoe UI', 'Noto Sans', 'Helvetica Neue', Arial, 'Apple Color Emoji', 'Segoe UI Emoji', sans-serif; }
1515
`;
Binary file not shown.

0 commit comments

Comments
 (0)