diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 54b2f21..f376636 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,4 +1,4 @@
-name: Build macOS Editor DMG
+name: Build macOS Editor App
on:
push:
@@ -28,10 +28,10 @@ jobs:
cd macos-editor
npm install
- - name: Build DMG
+ - name: Build React Native macOS App
run: |
cd macos-editor
- ./build.sh
+ npm run build
- name: Debug build artifacts
run: ls -la macos-editor/dist/
@@ -39,8 +39,8 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
- name: macos-editor-dmg
- path: macos-editor/dist/*.dmg
+ name: macos-editor-app
+ path: macos-editor/dist/*.app
release:
runs-on: macos-latest
@@ -56,13 +56,13 @@ jobs:
run: |
cd macos-editor
npm install
- - name: Build DMG
+ - name: Build React Native macOS App
run: |
cd macos-editor
- ./build.sh
- - name: Upload DMG to GitHub Release
+ npm run build
+ - name: Upload App to GitHub Release
uses: softprops/action-gh-release@v1
with:
- files: macos-editor/dist/*.dmg
+ files: macos-editor/dist/*.app
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/build.sh b/build.sh
old mode 100755
new mode 100644
index 936fccc..6bd4434
--- a/build.sh
+++ b/build.sh
@@ -7,7 +7,7 @@ MODE=$1
if [ -z "$MODE" ] || [ "$MODE" == "dev" ]; then
echo "Iniciando en modo de desarrollo..."
- npm run electron:dev
+ npx react-native run-macos
elif [ "$MODE" == "dmg" ]; then
echo "Generando DMG para macOS..."
@@ -20,7 +20,7 @@ elif [ "$MODE" == "dmg" ]; then
fi
# Generar el DMG
- npm run build:dmg
+ npx react-native run-macos --configuration Release
else
echo "Error: La generación de DMG solo es posible en macOS."
echo "Actualmente estás ejecutando en: $OSTYPE"
@@ -29,7 +29,7 @@ elif [ "$MODE" == "dmg" ]; then
fi
elif [ "$MODE" == "preview" ]; then
echo "Iniciando vista previa de la aplicación..."
- npm run electron:preview
+ npx react-native run-macos --configuration Release
else
echo "Uso: $0 [dev|dmg|preview]"
echo " dev : Inicia la aplicación en modo de desarrollo (por defecto)."
diff --git a/docs/dependencies/dependencies.en.md b/docs/dependencies/dependencies.en.md
index ab6c7ea..2790e1d 100644
--- a/docs/dependencies/dependencies.en.md
+++ b/docs/dependencies/dependencies.en.md
@@ -2,4 +2,4 @@
The macOS editor is built using the following dependencies:
- [Tiptap](https://github.com/ueberdosis/tiptap)
-- [Electron](https://www.electronjs.org/)
+- [React Native macOS](https://github.com/microsoft/react-native-macos)
diff --git a/docs/dependencies/dependencies.es.md b/docs/dependencies/dependencies.es.md
index 4203952..76b0373 100644
--- a/docs/dependencies/dependencies.es.md
+++ b/docs/dependencies/dependencies.es.md
@@ -2,4 +2,4 @@
El editor de macOS está construido usando las siguientes dependencias:
- [Tiptap](https://github.com/ueberdosis/tiptap)
-- [Electron](https://www.electronjs.org/)
+- [React Native macOS](https://github.com/microsoft/react-native-macos)
diff --git a/docs/installation/installation.en.md b/docs/installation/installation.en.md
index 2f75832..c534184 100644
--- a/docs/installation/installation.en.md
+++ b/docs/installation/installation.en.md
@@ -14,13 +14,9 @@
```sh
npm install
```
-3. Build the React bundle:
+3. Start the React Native macOS app:
```sh
- npx esbuild ./index.jsx --bundle --outfile=./bundle.js --format=iife
- ```
-4. Start the Electron app:
- ```sh
- npm start
+ npx react-native run-macos
```
## Build DMG for macOS
@@ -29,16 +25,10 @@
```sh
npm install
```
-2. Build the React bundle:
- ```sh
- npx esbuild ./index.jsx --bundle --outfile=./bundle.js --format=iife
- ```
-3. Build the DMG:
+2. Build the React Native macOS app:
```sh
- npm run build
- npx electron-builder --mac
+ npx react-native run-macos --configuration Release
```
- The DMG file will be in the `dist/` folder.
## Automated Script
@@ -46,7 +36,7 @@ You can use the script:
- For local development:
```sh
- ./build.sh local
+ ./build.sh dev
```
- To generate the DMG:
```sh
diff --git a/docs/installation/installation.es.md b/docs/installation/installation.es.md
index 30c70d2..0dc177f 100644
--- a/docs/installation/installation.es.md
+++ b/docs/installation/installation.es.md
@@ -14,13 +14,9 @@
```sh
npm install
```
-3. Genera el bundle de React:
+3. Inicia la aplicación React Native macOS:
```sh
- npx esbuild ./index.jsx --bundle --outfile=./bundle.js --format=iife
- ```
-4. Inicia la aplicación Electron:
- ```sh
- npm start
+ npx react-native run-macos
```
## Generar DMG para macOS
@@ -29,16 +25,10 @@
```sh
npm install
```
-2. Genera el bundle de React:
- ```sh
- npx esbuild ./index.jsx --bundle --outfile=./bundle.js --format=iife
- ```
-3. Construye el instalador DMG:
+2. Construye la aplicación React Native macOS:
```sh
- npm run build
- npx electron-builder --mac
+ npx react-native run-macos --configuration Release
```
- El archivo DMG estará en la carpeta `dist/`.
## Script automatizado
@@ -46,7 +36,7 @@ Puedes usar el script:
- Para desarrollo local:
```sh
- ./build.sh local
+ ./build.sh dev
```
- Para generar el DMG:
```sh
diff --git a/docs/project-overview/project-overview.en.md b/docs/project-overview/project-overview.en.md
index 134cc33..5a78a9c 100644
--- a/docs/project-overview/project-overview.en.md
+++ b/docs/project-overview/project-overview.en.md
@@ -5,10 +5,7 @@ This project is organized as follows:
- **macos-editor/**
- `index.html`: Main HTML file where the React app is mounted.
- `index.jsx`: React entry point. Defines the editor and toolbar using Tiptap and React.
- - `bundle.js`: Bundle generated from `index.jsx` using esbuild. Loaded by the browser/Electron.
- - `main.js`: Main Electron script. Controls the main window, splash, and app menu.
- - `renderer.js`: (Obsolete) Old editor logic, now replaced by React.
- - `splash.html`: Splash screen shown at app startup.
+ - `bundle.js`: Bundle generated from `index.jsx` using esbuild. Loaded by the browser.
- `build.sh`: Script to automate install, build, and DMG packaging.
- `package.json`: Editor-specific dependencies and scripts.
- **docs/**: Detailed documentation about installation, dependencies, build, workflows, etc.
@@ -19,5 +16,4 @@ This project is organized as follows:
- **index.html**: Defines the `
` container for React and loads the generated bundle.
- **index.jsx**: Contains the main React component, Tiptap configuration, and toolbar.
-- **main.js**: Initializes the Electron app, manages windows, splash, and menu.
- **build.sh**: Automates install and build for both development and DMG generation.
diff --git a/docs/project-overview/project-overview.es.md b/docs/project-overview/project-overview.es.md
index 337229e..0770e74 100644
--- a/docs/project-overview/project-overview.es.md
+++ b/docs/project-overview/project-overview.es.md
@@ -5,10 +5,7 @@ Este proyecto está organizado de la siguiente manera:
- **macos-editor/**
- `index.html`: Archivo HTML principal donde se monta la app React.
- `index.jsx`: Punto de entrada de React. Aquí se define el editor y la barra de herramientas usando Tiptap y React.
- - `bundle.js`: Bundle generado a partir de `index.jsx` usando esbuild. Es el archivo que carga el navegador/Electron.
- - `main.js`: Script principal de Electron. Controla la ventana principal, el splash y el menú de la app.
- - `renderer.js`: (Obsoleto) Lógica antigua del editor, ahora reemplazada por React.
- - `splash.html`: Pantalla de bienvenida (splash) mostrada al iniciar la app.
+ - `bundle.js`: Bundle generado a partir de `index.jsx` usando esbuild. Es el archivo que carga el navegador.
- `build.sh`: Script para automatizar la instalación, build y empaquetado DMG.
- `package.json`: Dependencias y scripts específicos del editor.
- **docs/**: Documentación detallada sobre instalación, dependencias, build, workflows, etc.
@@ -19,5 +16,4 @@ Este proyecto está organizado de la siguiente manera:
- **index.html**: Define el contenedor `` donde se monta la app React y carga el bundle generado.
- **index.jsx**: Contiene el componente principal de React, la configuración de Tiptap y la barra de herramientas.
-- **main.js**: Inicializa la app Electron, gestiona ventanas, splash y menú.
- **build.sh**: Permite automatizar la instalación y build tanto para desarrollo como para generar el DMG.
diff --git a/docs/splash/splash-screen.en.md b/docs/splash/splash-screen.en.md
index 7447b12..547c72c 100644
--- a/docs/splash/splash-screen.en.md
+++ b/docs/splash/splash-screen.en.md
@@ -1,66 +1,45 @@
# Splash Screen Functionality
-The `macos-editor/main.js` file includes functionality for displaying a splash screen when the macOS editor is launched. The splash screen is displayed for 3 seconds before the main window is shown. The relevant code is as follows:
+The splash screen component is implemented using React in the `src/components/splash-screen/splash-screen.tsx` file. The splash screen is displayed for a minimum of 1.5 seconds before the main application is shown. The relevant code is as follows:
-```javascript
-const { app, BrowserWindow } = require('electron');
-const path = require('path');
+```typescript
+import React, { useEffect, useState } from 'react';
+import './splash-screen.scss';
-function createSplashWindow() {
- const splashWindow = new BrowserWindow({
- width: 400,
- height: 300,
- frame: false,
- alwaysOnTop: true,
- transparent: true,
- webPreferences: {
- nodeIntegration: true,
- contextIsolation: false
- }
- });
-
- splashWindow.loadFile('splash.html');
- return splashWindow;
-}
-
-function createWindow () {
- const mainWindow = new BrowserWindow({
- width: 800,
- height: 600,
- show: false,
- webPreferences: {
- preload: path.join(__dirname, 'preload.js'),
- nodeIntegration: true,
- contextIsolation: false
- }
- });
-
- mainWindow.loadFile('index.html');
-
- mainWindow.once('ready-to-show', () => {
- setTimeout(() => {
- splashWindow.close();
- mainWindow.show();
- }, 3000); // Show splash screen for 3 seconds
- });
+interface SplashScreenProps {
+ onComplete: () => void;
+ minimumDisplayTime?: number;
}
-let splashWindow;
-
-app.on('ready', () => {
- splashWindow = createSplashWindow();
- createWindow();
-});
-
-app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit();
- }
-});
-
-app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
-});
+export const SplashScreen: React.FC = ({
+ onComplete,
+ minimumDisplayTime = 1500
+}) => {
+ const [shouldHide, setShouldHide] = useState(false);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setShouldHide(true);
+ onComplete();
+ }, minimumDisplayTime);
+
+ return () => clearTimeout(timer);
+ }, [minimumDisplayTime, onComplete]);
+
+ return (
+
+
+
+

+
+
Pora
+
+
+
+ );
+};
```
diff --git a/docs/splash/splash-screen.es.md b/docs/splash/splash-screen.es.md
index 67adaf4..53bbc20 100644
--- a/docs/splash/splash-screen.es.md
+++ b/docs/splash/splash-screen.es.md
@@ -1,66 +1,45 @@
# Funcionalidad de la pantalla de bienvenida (Splash)
-El archivo `macos-editor/main.js` incluye la funcionalidad para mostrar una pantalla de bienvenida (splash) al iniciar el editor de macOS. La pantalla de bienvenida se muestra durante 3 segundos antes de mostrar la ventana principal. El código relevante es el siguiente:
+El componente de la pantalla de bienvenida está implementado usando React en el archivo `src/components/splash-screen/splash-screen.tsx`. La pantalla de bienvenida se muestra durante un mínimo de 1.5 segundos antes de mostrar la aplicación principal. El código relevante es el siguiente:
-```javascript
-const { app, BrowserWindow } = require('electron');
-const path = require('path');
+```typescript
+import React, { useEffect, useState } from 'react';
+import './splash-screen.scss';
-function createSplashWindow() {
- const splashWindow = new BrowserWindow({
- width: 400,
- height: 300,
- frame: false,
- alwaysOnTop: true,
- transparent: true,
- webPreferences: {
- nodeIntegration: true,
- contextIsolation: false
- }
- });
-
- splashWindow.loadFile('splash.html');
- return splashWindow;
-}
-
-function createWindow () {
- const mainWindow = new BrowserWindow({
- width: 800,
- height: 600,
- show: false,
- webPreferences: {
- preload: path.join(__dirname, 'preload.js'),
- nodeIntegration: true,
- contextIsolation: false
- }
- });
-
- mainWindow.loadFile('index.html');
-
- mainWindow.once('ready-to-show', () => {
- setTimeout(() => {
- splashWindow.close();
- mainWindow.show();
- }, 3000); // Mostrar splash durante 3 segundos
- });
+interface SplashScreenProps {
+ onComplete: () => void;
+ minimumDisplayTime?: number;
}
-let splashWindow;
-
-app.on('ready', () => {
- splashWindow = createSplashWindow();
- createWindow();
-});
-
-app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit();
- }
-});
-
-app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
-});
+export const SplashScreen: React.FC = ({
+ onComplete,
+ minimumDisplayTime = 1500
+}) => {
+ const [shouldHide, setShouldHide] = useState(false);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setShouldHide(true);
+ onComplete();
+ }, minimumDisplayTime);
+
+ return () => clearTimeout(timer);
+ }, [minimumDisplayTime, onComplete]);
+
+ return (
+
+
+
+

+
+
Pora
+
+
+
+ );
+};
```
diff --git a/electron/main.js b/electron/main.js
deleted file mode 100644
index 42d4d73..0000000
--- a/electron/main.js
+++ /dev/null
@@ -1,291 +0,0 @@
-import { app, BrowserWindow, Menu, dialog, shell, ipcMain } from 'electron';
-import path from 'path';
-
-const isDev = process.env.NODE_ENV === 'development';
-const isMac = process.platform === 'darwin';
-
-// Keep a global reference of the window object to avoid garbage collection
-let mainWindow;
-let splashWindow;
-
-// Set app name for macOS menu
-app.name = 'Pora';
-
-// Create a splash window
-function createSplashWindow() {
- splashWindow = new BrowserWindow({
- width: 400,
- height: 300,
- transparent: true,
- frame: false,
- resizable: false,
- webPreferences: {
- nodeIntegration: false,
- contextIsolation: true
- },
- alwaysOnTop: true,
- show: false // Don't show window until it's ready
- });
-
- // Load a custom splash screen HTML in production
- // Or just use the main app in development (since it has the splash screen component)
- if (isDev) {
- splashWindow.loadURL('http://localhost:5173');
- } else {
- splashWindow.loadFile(path.join(__dirname, '../dist/splash.html'));
- }
-
- splashWindow.once('ready-to-show', () => {
- splashWindow.show();
- });
-
- splashWindow.on('closed', () => {
- splashWindow = null;
- });
-}
-
-function createWindow() {
- // Create the browser window
- mainWindow = new BrowserWindow({
- width: 1200,
- height: 800,
- minWidth: 800,
- minHeight: 600,
- webPreferences: {
- nodeIntegration: false,
- contextIsolation: true,
- preload: path.join(__dirname, 'preload.js')
- },
- titleBarStyle: 'hiddenInset', // macOS-style title bar
- backgroundColor: '#ffffff',
- show: false, // Don't show window until splash is done
- vibrancy: 'under-window', // macOS vibrancy effect
- visualEffectState: 'active',
- trafficLightPosition: { x: 14, y: 14 }
- });
-
- // Load the app
- if (isDev) {
- // In development, load from Vite dev server
- mainWindow.loadURL('http://localhost:5173');
- // Open DevTools
- mainWindow.webContents.openDevTools();
- } else {
- // In production, load the built app
- mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
- }
-
- // Show window when ready to avoid flickering
- mainWindow.once('ready-to-show', () => {
- if (splashWindow) {
- // Add a delay to show the splash screen for at least a minimal time
- setTimeout(() => {
- splashWindow.destroy();
- mainWindow.show();
- }, 1500);
- } else {
- mainWindow.show();
- }
- });
-
- // Set up the application menu (macOS style)
- const menuTemplate = [
- // App menu (macOS only)
- ...(isMac ? [{
- label: app.name,
- submenu: [
- { role: 'about' },
- { type: 'separator' },
- {
- label: 'Preferences...',
- accelerator: 'CmdOrCtrl+,',
- click: () => {
- // Show preferences window when implemented
- mainWindow.webContents.send('show-preferences');
- }
- },
- { type: 'separator' },
- { role: 'services' },
- { type: 'separator' },
- { role: 'hide' },
- { role: 'hideOthers' },
- { role: 'unhide' },
- { type: 'separator' },
- { role: 'quit' }
- ]
- }] : []),
- // File menu
- {
- label: 'File',
- submenu: [
- {
- label: 'New Document',
- accelerator: 'CmdOrCtrl+N',
- click: () => {
- mainWindow.webContents.send('new-document');
- }
- },
- {
- label: 'Open...',
- accelerator: 'CmdOrCtrl+O',
- click: async () => {
- const { canceled, filePaths } = await dialog.showOpenDialog(mainWindow, {
- filters: [
- { name: 'Text Documents', extensions: ['txt', 'md', 'html'] },
- { name: 'All Files', extensions: ['*'] }
- ],
- properties: ['openFile']
- });
- if (!canceled && filePaths.length > 0) {
- mainWindow.webContents.send('open-document', filePaths[0]);
- }
- }
- },
- {
- label: 'Save',
- accelerator: 'CmdOrCtrl+S',
- click: () => {
- mainWindow.webContents.send('save-document');
- }
- },
- {
- label: 'Save As...',
- accelerator: 'CmdOrCtrl+Shift+S',
- click: async () => {
- const { canceled, filePath } = await dialog.showSaveDialog(mainWindow, {
- filters: [
- { name: 'Text Documents', extensions: ['txt', 'md', 'html'] },
- { name: 'All Files', extensions: ['*'] }
- ]
- });
- if (!canceled && filePath) {
- mainWindow.webContents.send('save-document-as', filePath);
- }
- }
- },
- { type: 'separator' },
- isMac ? { role: 'close' } : { role: 'quit' }
- ]
- },
- {
- label: 'Edit',
- submenu: [
- { role: 'undo' },
- { role: 'redo' },
- { type: 'separator' },
- { role: 'cut' },
- { role: 'copy' },
- { role: 'paste' },
- { role: 'delete' },
- { type: 'separator' },
- { role: 'selectAll' }
- ]
- },
- {
- label: 'View',
- submenu: [
- { role: 'reload' },
- { role: 'forceReload' },
- { type: 'separator' },
- { role: 'resetZoom' },
- { role: 'zoomIn' },
- { role: 'zoomOut' },
- { type: 'separator' },
- { role: 'togglefullscreen' }
- ]
- },
- {
- label: 'Window',
- submenu: [
- { role: 'minimize' },
- { role: 'zoom' },
- { type: 'separator' },
- { role: 'front' },
- { type: 'separator' },
- { role: 'close' }
- ]
- },
- {
- label: 'Help',
- submenu: [
- {
- label: 'Learn More',
- click: async () => {
- await shell.openExternal('https://pora.app');
- }
- },
- {
- label: 'Documentation',
- click: async () => {
- await shell.openExternal('https://docs.pora.app');
- }
- },
- { type: 'separator' },
- {
- label: 'About Pora',
- click: () => {
- dialog.showMessageBox(mainWindow, {
- title: 'About Pora',
- message: 'Pora - Rich Text Editor',
- detail: `Version: ${app.getVersion()}\nElectron: ${process.versions.electron}\nChrome: ${process.versions.chrome}\nNode.js: ${process.versions.node}\nV8: ${process.versions.v8}`,
- buttons: ['OK'],
- icon: path.join(__dirname, '../build/icons/icon.icns')
- });
- }
- }
- ]
- }
- ];
-
- const menu = Menu.buildFromTemplate(menuTemplate);
- Menu.setApplicationMenu(menu);
-
- // Handle window close event
- mainWindow.on('closed', () => {
- mainWindow = null;
- });
-
- // Open links in default browser
- mainWindow.webContents.setWindowOpenHandler(({ url }) => {
- shell.openExternal(url);
- return { action: 'deny' };
- });
-}
-
-// Create window when Electron is ready
-app.whenReady().then(() => {
- // Show splash screen first
- createSplashWindow();
-
- // Create main window after a short delay
- setTimeout(() => {
- createWindow();
- }, 500);
-
- // On macOS, it's common to re-create a window when dock icon is clicked
- app.on('activate', () => {
- if (BrowserWindow.getAllWindows().length === 0) {
- createWindow();
- }
- });
-});
-
-// Quit when all windows are closed, except on macOS
-app.on('window-all-closed', () => {
- if (process.platform !== 'darwin') {
- app.quit();
- }
-});
-
-// Document event handlers
-ipcMain.on('check-for-changes', async (event) => {
- const choice = await dialog.showMessageBox(mainWindow, {
- type: 'question',
- buttons: ['Save', "Don't Save", 'Cancel'],
- defaultId: 0,
- title: 'Unsaved Changes',
- message: 'There are unsaved changes. Do you want to save them?'
- });
-
- event.reply('check-for-changes-response', choice.response);
-});
diff --git a/electron/preload.js b/electron/preload.js
deleted file mode 100644
index 63519f2..0000000
--- a/electron/preload.js
+++ /dev/null
@@ -1,55 +0,0 @@
-import { contextBridge, ipcRenderer } from 'electron';
-
-// Expose any needed APIs to the renderer process
-contextBridge.exposeInMainWorld('electron', {
- // Document operations
- documentOperations: {
- // Signal to save the document
- saveDocument: (callback) => {
- ipcRenderer.on('save-document', callback);
- },
- // Signal to save the document with a specific path
- saveDocumentAs: (callback) => {
- ipcRenderer.on('save-document-as', callback);
- },
- // Signal to open a document
- openDocument: (callback) => {
- ipcRenderer.on('open-document', callback);
- },
- // Signal to create a new document
- newDocument: (callback) => {
- ipcRenderer.on('new-document', callback);
- },
- // Check if there are unsaved changes
- checkForChanges: () => {
- return new Promise((resolve) => {
- ipcRenderer.once('check-for-changes-response', (_, response) => {
- resolve(response);
- });
- ipcRenderer.send('check-for-changes');
- });
- }
- },
-
- // App operations
- appOperations: {
- // Signal to show preferences
- showPreferences: (callback) => {
- ipcRenderer.on('show-preferences', callback);
- },
- // Get app version
- getVersion: () => process.versions.electron
- },
-
- // Remove listeners when they're no longer needed
- removeAllListeners: (channel) => {
- ipcRenderer.removeAllListeners(channel);
- }
-});
-
-window.addEventListener('DOMContentLoaded', () => {
- // Any initialization that needs to happen after DOM is loaded
- console.log('DOM fully loaded and parsed - Pora is running with Electron ' + process.versions.electron);
-});
-
-export default contextBridge;
diff --git a/electron/splash.html b/electron/splash.html
deleted file mode 100644
index 058473c..0000000
--- a/electron/splash.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
- Pora
-
-
-
-
-

-
Pora
-
-
-
-
diff --git a/package.json b/package.json
index 17126a7..e221b46 100644
--- a/package.json
+++ b/package.json
@@ -11,12 +11,11 @@
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint \"src/**/*.ts\"",
- "electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && NODE_ENV=development electron electron/main.js\"",
- "electron:build": "npm run build && electron-builder",
- "electron:preview": "npm run build && NODE_ENV=production electron electron/main.js",
- "build:dmg": "npm run electron:build -- --mac dmg"
+ "macos:dev": "npx react-native run-macos",
+ "macos:build": "npx react-native run-macos --configuration Release",
+ "macos:preview": "npx react-native run-macos --configuration Release"
},
- "main": "electron/main.cjs",
+ "main": "src/main.tsx",
"dependencies": {
"@floating-ui/react": "^0.27.8",
"@tiptap/extension-highlight": "^2.11.9",
@@ -33,7 +32,9 @@
"@tiptap/react": "^2.11.9",
"@tiptap/starter-kit": "^2.11.9",
"react": "^18.3.1",
- "react-dom": "^18.3.1"
+ "react-dom": "^18.3.1",
+ "react-native": "^0.71.8",
+ "react-native-macos": "^0.71.8"
},
"devDependencies": {
"@types/react": "^19.1.2",
@@ -42,63 +43,11 @@
"@typescript-eslint/parser": "^7.18.0",
"@vitejs/plugin-react": "^4.4.1",
"concurrently": "^9.1.2",
- "electron": "^36.2.1",
- "electron-builder": "^26.0.12",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"sass-embedded": "^1.87.0",
"typescript": "5.5.4",
"vite": "^6.3.5",
"wait-on": "^8.0.3"
- },
- "build": {
- "appId": "com.pora.app",
- "productName": "Pora",
- "mac": {
- "category": "public.app-category.productivity",
- "darkModeSupport": true,
- "icon": "build/icons/icon.icns",
- "target": ["dmg"],
- "hardenedRuntime": true,
- "gatekeeperAssess": false,
- "entitlements": "build/entitlements.mac.plist",
- "entitlementsInherit": "build/entitlements.mac.plist",
- "artifactName": "Pora-${version}.${ext}"
- },
- "dmg": {
- "contents": [
- {
- "x": 130,
- "y": 220
- },
- {
- "x": 410,
- "y": 220,
- "type": "link",
- "path": "/Applications"
- }
- ],
- "window": {
- "width": 540,
- "height": 380
- },
- "backgroundColor": "#f0f0f0",
- "icon": "build/icons/icon.icns",
- "title": "Pora ${version}"
- },
- "files": [
- "dist/**/*",
- "electron/**/*"
- ],
- "directories": {
- "buildResources": "build",
- "output": "release"
- },
- "protocols": [
- {
- "name": "Pora URL",
- "schemes": ["pora"]
- }
- ]
}
}
diff --git a/src/main.tsx b/src/main.tsx
index 709f857..de76f80 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -2,6 +2,8 @@ import { createRoot } from "react-dom/client"
import { useState, useEffect } from "react"
import { SimpleEditor } from "@/components/tiptap-templates/simple/simple-editor"
import { SplashScreen } from "@/components/splash-screen/splash-screen"
+import { AppRegistry } from 'react-native';
+import { name as appName } from './app.json';
const App = () => {
const [showSplashScreen, setShowSplashScreen] = useState(true);
@@ -29,4 +31,4 @@ const App = () => {
);
};
-createRoot(document.getElementById("app")!).render()
+AppRegistry.registerComponent(appName, () => App);
diff --git a/vite.config.ts b/vite.config.ts
index 8889368..97b4454 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -29,7 +29,7 @@ export default defineConfig({
}
}
],
- base: './', // Relative paths for electron compatibility
+ base: './', // Relative paths for compatibility
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
@@ -43,7 +43,6 @@ export default defineConfig({
},
},
},
- // Electron specific settings
build: {
outDir: 'dist',
assetsDir: 'assets',