├── assets ├── icon.ico ├── icon.png ├── icon.icns ├── loading.gif └── background.png ├── .gitignore ├── preload.js ├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ └── codeql-analysis.yml ├── LICENSE ├── README.md ├── package.json ├── forge.config.js └── main.js /assets/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comp-Labs/Google-Docs/HEAD/assets/icon.ico -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comp-Labs/Google-Docs/HEAD/assets/icon.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | package-lock.json 4 | 5 | out/ 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /assets/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comp-Labs/Google-Docs/HEAD/assets/icon.icns -------------------------------------------------------------------------------- /assets/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comp-Labs/Google-Docs/HEAD/assets/loading.gif -------------------------------------------------------------------------------- /assets/background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Comp-Labs/Google-Docs/HEAD/assets/background.png -------------------------------------------------------------------------------- /preload.js: -------------------------------------------------------------------------------- 1 | // All of the Node.js APIs are available in the preload process. 2 | // It has the same sandbox as a Chrome extension. 3 | window.addEventListener("DOMContentLoaded", () => { 4 | const replaceText = (selector, text) => { 5 | const element = document.getElementById(selector); 6 | if (element) element.innerText = text; 7 | }; 8 | 9 | for (const type of ["chrome", "node", "electron"]) { 10 | replaceText(`${type}-version`, process.versions[type]); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Tech Fiddle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Docs 2 | **Google Docs is an Online Word Processor Developed by Google. Better Design and Features compared to Free Office such as OpenOffice, LibreOffice etc. This is an app that contains the full suite of Google Docs, Sheets, and Slides for Windows, macOS, and Linux.** 3 | 4 | ## Features 5 | - Freemium Software - Absolutely Free Software with Premium Features 6 | - Google Docs, Sheets, and Slides included. 7 | - Powerful and filled with features such as Microsoft Office 8 | - Compatible with Linux! (Microsoft Office is not compatible with Linux.) 9 | 10 | ## Caution ⚠️ 11 | Make sure you are connected to the Internet During Editing Documents to avoid any loss of data. Changes made to your document are saved to Google Drive Time-to-Time. So the Bright Part is, you do not Lose Changes! 12 | 13 | ## Download Instructions 📦 14 | [Click Here](https://techfiddle.io/apps/Google-Docs/), then click on the button of your Operating System to download. 15 | 16 | On Windows, instead of manually downloading the setup file, you can install/update it using the [Chocolatey package](https://community.chocolatey.org/packages/unofficial-google-docs-client): 17 | ```powershell 18 | choco install unofficial-google-docs-client 19 | ``` 20 | 21 | ## Final Words ✨ 22 | **Thanks for Using it and we encourage users to use it.** 23 | 24 | ## License 25 | [MIT License](LICENSE.md) 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "google-docs", 3 | "productName": "Google Docs", 4 | "version": "2022.12.1", 5 | "description": "Google Docs is a free universal desktop app containing an office suite.", 6 | "main": "main.js", 7 | "scripts": { 8 | "start": "electron-forge start", 9 | "dist": "electron-builder", 10 | "package": "electron-forge package", 11 | "make": "electron-forge make", 12 | "publish": "electron-forge publish" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/Comp-Labs/Google-Docs" 17 | }, 18 | "keywords": [ 19 | "Google", 20 | "Docs", 21 | "Productivity", 22 | "App" 23 | ], 24 | "author": "Tech Fiddle ", 25 | "license": "MIT", 26 | "devDependencies": { 27 | "@electron-forge/cli": "latest", 28 | "@electron-forge/maker-deb": "latest", 29 | "@electron-forge/maker-dmg": "latest", 30 | "@electron-forge/maker-flatpak": "latest", 31 | "@electron-forge/maker-rpm": "latest", 32 | "@electron-forge/maker-snap": "latest", 33 | "@electron-forge/maker-squirrel": "latest", 34 | "@electron-forge/maker-zip": "latest", 35 | "@electron-forge/publisher-github": "latest", 36 | "@electron-forge/publisher-snapcraft": "latest", 37 | "electron": "^31.1.0" 38 | }, 39 | "dependencies": { 40 | "electron-squirrel-startup": "latest", 41 | "update-electron-app": "latest", 42 | "appdmg": "latest" 43 | }, 44 | "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | 3 | on: 4 | # Trigger the workflow on push or pull request, 5 | # but only for the main branch 6 | # Snapcraft Token Valid till 10 March, 2023 7 | push: 8 | branches: 9 | - main 10 | pull_request: 11 | branches: 12 | - main 13 | 14 | jobs: 15 | build-linux: 16 | name: Linux 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v3 20 | - uses: actions/setup-node@v3 21 | with: 22 | node-version: '22' 23 | - name: Install Snapcraft 24 | uses: samuelmeuli/action-snapcraft@v1.2.0 25 | with: 26 | snapcraft_token: ${{ secrets.SNAPCRAFT_TOKEN }} 27 | - name: Build it 28 | env: 29 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | run: | 31 | npm install 32 | sudo apt install flatpak flatpak-builder elfutils 33 | npm run package && cd "out/Google Docs-linux-x64" && ls 34 | npm run make && npm run publish 35 | - uses: actions/upload-artifact@v3 36 | with: 37 | name: Linux 38 | path: out/make/* 39 | - name: Use Snapcraft 40 | run: | 41 | snapcraft --help 42 | snapcraft upload --release=stable "out/make/Google Docs-linux-x64.snap" 43 | 44 | build-mac: 45 | name: macOS 46 | runs-on: macos-latest 47 | steps: 48 | - uses: actions/checkout@v3 49 | - uses: actions/setup-node@v3 50 | with: 51 | node-version: '22' 52 | - uses: actions/setup-python@v4 53 | with: 54 | python-version: '3.10' 55 | - name: Prepare for app signing and notarization 56 | env: 57 | API_KEY: ${{ secrets.api_key }} 58 | if: ${{ env.API_KEY }} 59 | run: | 60 | echo "CSC_LINK=${{ secrets.mac_cert }}" >> $GITHUB_ENV 61 | echo "CSC_KEY_PASSWORD=${{ secrets.mac_cert_password }}" >> $GITHUB_ENV 62 | echo "APPLE_ID=${{ secrets.apple_id }}" >> $GITHUB_ENV 63 | echo "APPLE_ID_PASSWORD=${{ secrets.apple_id_password }}" >> $GITHUB_ENV 64 | echo "TEAM_ID=${{ secrets.team_id }}" >> $GITHUB_ENV 65 | - name: Build it 66 | env: 67 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 68 | run: | 69 | npm install 70 | npm install appdmg --save-dev 71 | npm run publish 72 | - uses: actions/upload-artifact@v3 73 | with: 74 | name: macOS 75 | path: out/make/* 76 | build-windows: 77 | name: Windows 78 | runs-on: windows-latest 79 | steps: 80 | - uses: actions/checkout@v3 81 | - uses: actions/setup-node@v3 82 | with: 83 | node-version: '22' 84 | - name: Build it 85 | env: 86 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 87 | run: | 88 | npm install 89 | npm run publish 90 | - uses: actions/upload-artifact@v3 91 | with: 92 | name: Windows 93 | path: out/make/squirrel.windows/x64/Google-Docs-Windows.exe 94 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ "main" ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ "main" ] 20 | schedule: 21 | - cron: '28 2 * * 1' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v3 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v2 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | 56 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 57 | # If this step fails, then you should remove it and run the build manually (see below) 58 | - name: Autobuild 59 | uses: github/codeql-action/autobuild@v2 60 | 61 | # ℹ️ Command-line programs to run using the OS shell. 62 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 63 | 64 | # If the Autobuild fails above, remove it and uncomment the following three lines. 65 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 66 | 67 | # - run: | 68 | # echo "Run, Build Application using script" 69 | # ./location_of_script_within_repo/buildscript.sh 70 | 71 | - name: Perform CodeQL Analysis 72 | uses: github/codeql-action/analyze@v2 73 | -------------------------------------------------------------------------------- /forge.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | packagerConfig: { 3 | name: "Google Docs", 4 | arch: 'all', 5 | buildIdentifier: 'prod', 6 | appBundleId: 'io.techfiddle.google-docs', 7 | appCopyright: 'Copyright (c) 2023 Tech Fiddle & Google. All Rights Reserved.', 8 | executableName: "google-docs", 9 | icon: './assets/icon.png', 10 | out: './dist', 11 | platform: [ 12 | 'darwin', 13 | 'win32', 14 | 'linux', 15 | 'mas' 16 | ], 17 | win32metadata: { 18 | CompanyName: 'Tech Fiddle', 19 | FileDescription: 'Google Docs Desktop App', 20 | InternalName: 'Google Docs', 21 | ProductName: 'Google Docs' 22 | }, 23 | appCategoryType: 'public.app-category.productivity', 24 | darwinDarkModeSupport: true, 25 | }, 26 | rebuildConfig: {}, 27 | makers: [ 28 | // { 29 | // name: '@electron-forge/maker-appx', 30 | // config: { 31 | // packageName: 'Google Docs', 32 | // packageDisplayName: 'Google Docs', 33 | // packageDescription: 'Google Docs Desktop App', 34 | // publisher: 'CN=developmentca', 35 | // devCert: './assets/devcert.pfx', 36 | // certPass: 'process.env.certPass' 37 | // } 38 | // }, 39 | { 40 | name: '@electron-forge/maker-squirrel', 41 | config: { 42 | name: "GoogleDocs", 43 | authors: 'Tech Fiddle', 44 | copyright: 'Copyright (c) 2023 Tech Fiddle. All Rights Reserved.', 45 | description: 'Google Docs Desktop App', 46 | // exe: 'Google-Docs-Windows', 47 | setupExe: 'Google-Docs-Windows.exe', 48 | iconUrl: 'https://cdn.jsdelivr.net/gh/Comp-Labs/cdn/img/apps/electron/google-docs.ico', 49 | setupIcon: './assets/icon.ico', 50 | loadingGif: './assets/loading.gif' 51 | }, 52 | }, 53 | { 54 | name: '@electron-forge/maker-zip', 55 | platforms: ['darwin'], 56 | }, 57 | { 58 | name: '@electron-forge/maker-dmg', 59 | config: { 60 | additionalDmgOptions: {}, 61 | name: 'Google Docs', 62 | background: './assets/background.png', 63 | icon: './assets/icon.png' 64 | } 65 | }, 66 | // { 67 | // name: '@electron-forge/maker-pkg', 68 | // config: { 69 | // identity: 'google-docs-signing-key' 70 | // } 71 | // }, 72 | { 73 | name: '@electron-forge/maker-deb', 74 | config: { 75 | options: { 76 | name: 'Google Docs', 77 | genericName: 'Google Docs', 78 | productName: 'Google Docs', 79 | description: 'Google Docs Desktop App', 80 | maintainer: 'Tech Fiddle', 81 | homepage: 'https://techfiddle.io', 82 | icon: './assets/icon.png', 83 | depends: [ 84 | "libgtk-3-0", 85 | "libnss3", 86 | "libxtst6", 87 | "xdg-utils", 88 | "libatspi2.0-0", 89 | "libuuid1" 90 | ], 91 | categories: [ 92 | 'Graphics', 93 | 'Office', 94 | 'Utility' 95 | ] 96 | } 97 | }, 98 | }, 99 | { 100 | name: '@electron-forge/maker-flatpak', 101 | config: { 102 | options: { 103 | productName: 'Google Docs', 104 | id: 'io.techfiddle.google-docs', 105 | genericName: 'Google Docs', 106 | icon: './assets/icon.png', 107 | description: 'Google Docs Desktop App', 108 | modules: [ 109 | "libgtk-3-0", 110 | "libnss3", 111 | "libxtst6", 112 | "xdg-utils", 113 | "libatspi2.0-0", 114 | "libuuid1" 115 | ], 116 | categories: [ 117 | 'Graphics', 118 | 'Office', 119 | 'Utility' 120 | ] 121 | } 122 | } 123 | }, 124 | { 125 | name: '@electron-forge/maker-snap', 126 | config: { 127 | name: 'googledocs', 128 | summary: 'Unofficial Google Docs desktop wrapper', 129 | description: 'Google Docs in a native-like Electron shell with optional offline support.', 130 | grade: 'stable', 131 | confinement: 'strict', 132 | executableName: 'google-docs-linux', 133 | icon: './assets/icon.png', 134 | plugs: [ 135 | 'desktop', 136 | 'desktop-legacy', 137 | 'x11', 138 | 'wayland', 139 | 'unity7', 140 | 'browser-support', 141 | 'network', 142 | 'network-bind', 143 | 'pulseaudio' 144 | ], 145 | categories: ['Office'] 146 | } 147 | }, 148 | ], 149 | publishers: [ 150 | { 151 | name: '@electron-forge/publisher-github', 152 | config: { 153 | draft: true, 154 | authToken: 'GITHUB_TOKEN', 155 | tagPrefix: 'v', 156 | repository: { 157 | owner: 'Comp-Labs', 158 | name: 'Google-Docs' 159 | }, 160 | prerelease: false 161 | } 162 | }, 163 | { 164 | name: '@electron-forge/publisher-snapcraft', 165 | config: { 166 | release: "latest/stable" 167 | } 168 | }, 169 | ] 170 | }; 171 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | if (require('electron-squirrel-startup')) return; 2 | 3 | // Modules to control application life and create native browser window 4 | const { app, BrowserWindow, Menu, session } = require("electron") 5 | const path = require("path") 6 | const { updateElectronApp, UpdateSourceType } = require('update-electron-app') 7 | 8 | function createWindow() { 9 | // Create the browser window. 10 | const mainWindow = new BrowserWindow({ 11 | width: 800, 12 | height: 600, 13 | icon: __dirname + "/assets/icon.ico", 14 | webPreferences: { 15 | preload: path.join(__dirname, "preload.js"), 16 | nodeIntegration: false, 17 | nativeWindowOpen: true, 18 | contextIsolation: false, 19 | sandbox: false, 20 | }, 21 | }); 22 | 23 | mainWindow.webContents.setUserAgent("Chrome"); 24 | // = "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko" 25 | mainWindow.loadURL("https://docs.google.com/document/u/0/?pli=1"); 26 | // Open the DevTools. 27 | // mainWindow.webContents.openDevTools() 28 | } 29 | // Workarounds - #48 30 | app.commandLine.appendSwitch('disable-features', 'ImmersiveIme'); 31 | app.commandLine.appendSwitch('enable-blink-features', 'TextInputIme'); 32 | // This method will be called when Electron has finished 33 | // initialization and is ready to create browser windows. 34 | // Some APIs can only be used after this event occurs. 35 | app.whenReady().then(createWindow); 36 | 37 | app.on("activate", function () { 38 | // On macOS it's common to re-create a window in the app when the 39 | // dock icon is clicked and there are no other windows open. 40 | if (BrowserWindow.getAllWindows().length === 0) createWindow(); 41 | mainWindow.webContents.on('new-window', (event, url) => { 42 | event.preventDefault() 43 | mainWindow.loadURL(url) 44 | }) 45 | }); 46 | 47 | updateElectronApp() 48 | 49 | // Quit when all windows are closed, except on macOS. There, it's common 50 | // for applications and their menu bar to stay active until the user quits 51 | // explicitly with Cmd + Q. 52 | app.on("window-all-closed", function () { 53 | if (process.platform !== "darwin") app.quit(); 54 | }); 55 | 56 | // In this file you can include the rest of your app's specific main process 57 | // code. You can also put them in separate files and require them here. 58 | const isMac = process.platform === "darwin"; 59 | 60 | const template = [ 61 | // { role: 'appMenu' } 62 | ...(isMac 63 | ? [ 64 | { 65 | label: app.name, 66 | submenu: [ 67 | { role: "about" }, 68 | { type: "separator" }, 69 | { role: "services" }, 70 | { type: "separator" }, 71 | { role: "hide" }, 72 | { role: "hideOthers" }, 73 | { role: "unhide" }, 74 | { type: "separator" }, 75 | { role: "quit" }, 76 | ], 77 | }, 78 | ] 79 | : []), 80 | // { role: 'fileMenu' } 81 | { 82 | label: "File", 83 | submenu: [isMac ? { role: "close" } : { role: "quit" }], 84 | }, 85 | // { role: 'editMenu' } 86 | { 87 | label: "Edit", 88 | submenu: [ 89 | { role: "undo" }, 90 | { role: "redo" }, 91 | { type: "separator" }, 92 | { role: "cut" }, 93 | { role: "copy" }, 94 | { role: "paste" }, 95 | ...(isMac 96 | ? [ 97 | { role: "pasteAndMatchStyle" }, 98 | { role: "delete" }, 99 | { role: "selectAll" }, 100 | { type: "separator" }, 101 | { 102 | label: "Speech", 103 | submenu: [{ role: "startSpeaking" }, { role: "stopSpeaking" }], 104 | }, 105 | ] 106 | : [{ role: "delete" }, { type: "separator" }, { role: "selectAll" }]), 107 | ], 108 | }, 109 | // { role: 'viewMenu' } 110 | { 111 | role: 'viewMenu', 112 | label: "View", 113 | submenu: [ 114 | { role: "reload" }, 115 | { role: "forceReload" }, 116 | // { role: "goBack" }, 117 | // { role: "goForward" }, 118 | { role: "toggleDevTools" }, 119 | { type: "separator" }, 120 | { role: "resetZoom" }, 121 | { role: "zoomIn" }, 122 | { role: "zoomOut" }, 123 | { type: "separator" }, 124 | { role: "togglefullscreen" }, 125 | ], 126 | }, 127 | // { role: 'windowMenu' } 128 | { 129 | role: 'windowMenu', 130 | label: "Window", 131 | submenu: [ 132 | { role: "minimize" }, 133 | { role: "zoom" }, 134 | ...(isMac 135 | ? [ 136 | { type: "separator" }, 137 | { role: "front" }, 138 | { type: "separator" }, 139 | { role: "window" }, 140 | ] 141 | : [{ role: "close" }]), 142 | ], 143 | }, 144 | { 145 | role: "help", 146 | submenu: [ 147 | { 148 | label: "Google Docs v2022.12.1", 149 | enabled: false 150 | }, 151 | { 152 | label: "Website", 153 | click: async () => { 154 | const { shell } = require("electron"); 155 | await shell.openExternal("https://techfiddle.io/"); 156 | }, 157 | }, 158 | { 159 | label: "Contact Us", 160 | click: async () => { 161 | const { shell } = require("electron"); 162 | await shell.openExternal("https://techfiddle.io/contact"); 163 | }, 164 | }, 165 | { type: "separator" }, 166 | { 167 | label: "GitHub", 168 | click: async () => { 169 | const { shell } = require("electron"); 170 | await shell.openExternal("https://github.com/Comp-Labs/Google-Docs"); 171 | }, 172 | }, 173 | { 174 | label: "YouTube", 175 | click: async () => { 176 | const { shell } = require("electron"); 177 | await shell.openExternal("https://youtube.com/@techfiddle"); 178 | }, 179 | }, 180 | { 181 | label: "Discord", 182 | click: async () => { 183 | const { shell } = require("electron"); 184 | await shell.openExternal("https://discord.gg/GAbzAGKccW"); 185 | }, 186 | }, 187 | { 188 | label: "Bento", 189 | click: async () => { 190 | const { shell } = require("electron"); 191 | await shell.openExternal("https://bento.me/techfiddle"); 192 | }, 193 | } 194 | ], 195 | }, 196 | ]; 197 | 198 | const menu = Menu.buildFromTemplate(template); 199 | Menu.setApplicationMenu(menu); 200 | --------------------------------------------------------------------------------