Skip to content

Commit 56282b3

Browse files
committed
final working commit
1 parent 0a5f01a commit 56282b3

35 files changed

+22905
-0
lines changed

client/README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Available Scripts
2+
3+
In the project directory, you can run:
4+
5+
### `npm start`
6+
7+
Runs the app in the development mode.\
8+
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
9+
10+
The page will reload when you make changes.\
11+
You may also see any lint errors in the console.
12+
13+
### Deployment

client/package-lock.json

+21,577
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "clip-sync",
3+
"productName": "Clipboard Sync",
4+
"version": "1.0.0",
5+
"author": "Black Crow",
6+
"description": "An App to Synchronize Clipboard",
7+
"main": "public/electron.js",
8+
"homepage": "./",
9+
"private": true,
10+
"dependencies": {
11+
"@electron/remote": "^2.0.9",
12+
"@testing-library/jest-dom": "^5.16.5",
13+
"@testing-library/react": "^13.4.0",
14+
"@testing-library/user-event": "^13.5.0",
15+
"axios": "^1.4.0",
16+
"clipboard-event": "^1.6.0",
17+
"electron-browser-storage": "^1.0.7",
18+
"electron-devtools-installer": "^3.2.0",
19+
"electron-is-dev": "^2.0.0",
20+
"electron-store": "^8.1.0",
21+
"react": "^18.2.0",
22+
"react-dom": "^18.2.0",
23+
"react-router-dom": "^6.10.0",
24+
"react-scripts": "5.0.1",
25+
"socket.io": "^4.6.2",
26+
"socket.io-client": "^4.6.2",
27+
"web-vitals": "^2.1.4"
28+
},
29+
"scripts": {
30+
"start": "react-scripts start",
31+
"build": "react-scripts build",
32+
"test": "react-scripts test",
33+
"eject": "react-scripts eject",
34+
"dev": "concurrently -k \"cross-env BROWSER=none PORT=3001 npm start\" \"wait-on http://127.0.0.1:3001/ --timeout 45000 && npm run electron\"",
35+
"electron": "electronmon .",
36+
"electron-pack": "electron-builder -c.extraMetadata.main=build/electron.js -mwl",
37+
"preelectron-pack": "react-scripts build",
38+
"build-electron": "mkdir build/src && robocopy electron build/electron /S & robocopy src/shared build/src/shared /S"
39+
},
40+
"eslintConfig": {
41+
"extends": [
42+
"react-app",
43+
"react-app/jest"
44+
]
45+
},
46+
"browserslist": {
47+
"production": [
48+
">0.2%",
49+
"not dead",
50+
"not op_mini all"
51+
],
52+
"development": [
53+
"last 1 chrome version",
54+
"last 1 firefox version",
55+
"last 1 safari version"
56+
]
57+
},
58+
"devDependencies": {
59+
"concurrently": "^8.0.1",
60+
"cross-env": "^7.0.3",
61+
"electron": "^23.2.0",
62+
"electron-builder": "^24.4.0",
63+
"electron-react-devtools": "^0.5.3",
64+
"electronmon": "^2.0.2",
65+
"wait-on": "^7.0.1"
66+
}
67+
}

client/public/appicon.ico

16.6 KB
Binary file not shown.

client/public/electron.js

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
const { app, BrowserWindow, clipboard, ipcMain, Tray, Menu } = require('electron')
2+
const clipboardListener = require('clipboard-event');
3+
require('@electron/remote/main').initialize();
4+
const Store = require('electron-store');
5+
const path = require('path');
6+
// const isDev = require('electron-is-dev');
7+
8+
//contants
9+
const { COPIED_TEXT } = require("../src/utils/constants");
10+
11+
const store = new Store();
12+
13+
//create tray element
14+
let win = null;
15+
let tray = null;
16+
17+
function createWindow() {
18+
// Create the browser window.
19+
win = new BrowserWindow({
20+
width: 800,
21+
height: 600,
22+
webPreferences: {
23+
enableRemoteModule: true,
24+
nodeIntegration: true,
25+
contextIsolation: false
26+
}
27+
})
28+
29+
//load the index.html from a url when the user is not logged in else load '/clipboard'
30+
if (store.get('userInfo') === undefined) {
31+
win.loadURL('http://localhost:3001');
32+
console.log("user info: ", store.get('userInfo'));
33+
console.log("login");
34+
}
35+
else {
36+
win.loadURL('http://localhost:3001/clipboard');
37+
console.log("user info: ", store.get('userInfo'));
38+
console.log("clipboard");
39+
40+
}
41+
42+
43+
// Open the DevTools.
44+
// win.webContents.openDevTools();
45+
46+
//stores the remote copied text send from renderer
47+
let remote_copied_text;
48+
49+
//recieves the text copied on remote platform via the renderer
50+
ipcMain.on("remote_copied_text", (evt, data) => {
51+
console.log("this is the copied text from remote devices: ", data.message);
52+
53+
//sets remote_copied_text
54+
remote_copied_text = data.message;
55+
56+
//saves the recieve copied text to clipboard
57+
clipboard.writeText(data.message);
58+
});
59+
60+
61+
//recieves the user data from renderer and stores it in application
62+
ipcMain.on("user-data", (evt, data) => {
63+
console.log("this is user data from renderer: ", data.id, 'data name:', data.name);
64+
65+
store.set('userInfo', { name: data.name, id: data.id });
66+
console.log(store.get('userInfo'));
67+
});
68+
69+
//handle logout and remove user data from electron store
70+
ipcMain.on("remove_user", (evt, data) => {
71+
console.log("this is user data from renderer: ", data);
72+
73+
store.delete('userInfo');
74+
console.log('userdelete!');
75+
win.loadURL('http://localhost:3001');
76+
});
77+
78+
79+
// To start listening
80+
clipboardListener.startListening();
81+
82+
//when text is copied i.e. the event occurs [also caused by clipboard.writeText() fn]
83+
clipboardListener.on('change', () => {
84+
const text = clipboard.readText();
85+
86+
//check if the message copied same as the one just saved in clipboard
87+
//to prevent copy and paste infinite loop
88+
if (remote_copied_text !== text) {
89+
//sends message to the renderer
90+
win.webContents.send(COPIED_TEXT, text);
91+
console.log(text);
92+
} else {
93+
console.log("same as latest copied element");
94+
}
95+
});
96+
97+
//set up tray element
98+
try {
99+
const iconPath = path.join(__dirname, 'icon.png');
100+
101+
tray = new Tray(iconPath);
102+
const contextMenu = Menu.buildFromTemplate([
103+
{
104+
label: 'Quit',
105+
click: () => {
106+
tray.destroy();
107+
app.exit();
108+
}
109+
}
110+
]);
111+
112+
//show text on hover on tray icon
113+
tray.setToolTip('Clipboard Sync');
114+
115+
// Call this again for Linux because we modified the context menu
116+
tray.setContextMenu(contextMenu)
117+
118+
tray.on('click', () => {
119+
win.isVisible() ? win.hide() : win.show();
120+
});
121+
122+
} catch (error) {
123+
console.log(error)
124+
}
125+
126+
//hides the window instead of closing
127+
win.on('close', (event) => {
128+
// Prevent the window from closing
129+
event.preventDefault();
130+
// Hide the window instead
131+
win.hide();
132+
});
133+
134+
}
135+
136+
// This method will be called when Electron has finished
137+
// initialization and is ready to create browser windows.
138+
// Some APIs can only be used after this event occurs.
139+
app.whenReady().then(createWindow)
140+
141+
// Quit when all windows are closed, except on macOS. There, it's common
142+
// for applications and their menu bar to stay active until the user quits
143+
// explicitly with Cmd + Q.
144+
app.on('window-all-closed', () => {
145+
146+
if (process.platform !== 'darwin') {
147+
app.quit();
148+
}
149+
150+
});
151+
152+
153+
app.on('activate', () => {
154+
// On macOS it's common to re-create a window in the app when the
155+
// dock icon is clicked and there are no other windows open.
156+
if (BrowserWindow.getAllWindows().length === 0) {
157+
createWindow()
158+
}
159+
})
160+
161+
// In this file you can include the rest of your app's specific main process
162+
// code. You can also put them in separate files and require them here.

client/public/favicon.ico

1.12 KB
Binary file not shown.

client/public/icon.png

2.37 KB
Loading

client/public/[email protected]

3.3 KB
Loading

client/public/[email protected]

6.88 KB
Loading

client/public/index.html

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8" />
6+
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1" />
8+
<meta name="theme-color" content="#000000" />
9+
<meta name="description" content="Web site to sync copied data across multiple devices" />
10+
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
11+
<!--
12+
manifest.json provides metadata used when your web app is installed on a
13+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
14+
-->
15+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
16+
<!--
17+
Notice the use of %PUBLIC_URL% in the tags above.
18+
It will be replaced with the URL of the `public` folder during the build.
19+
Only files inside the `public` folder can be referenced from the HTML.
20+
21+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
22+
work correctly both with client-side routing and a non-root public URL.
23+
Learn how to configure a non-root public URL by running `npm run build`.
24+
-->
25+
<link rel="preconnect" href="https://fonts.googleapis.com">
26+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
27+
<link
28+
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@100;200;300&family=Roboto+Mono:wght@300;400&display=swap"
29+
rel="stylesheet">
30+
<title>React App</title>
31+
</head>
32+
33+
<body>
34+
<noscript>You need to enable JavaScript to run this app.</noscript>
35+
<div id="root"></div>
36+
<!--
37+
This HTML file is a template.
38+
If you open it directly in the browser, you will see an empty page.
39+
40+
You can add webfonts, meta tags, or analytics to this file.
41+
The build step will place the bundled scripts into the <body> tag.
42+
43+
To begin the development, run `npm start` or `yarn start`.
44+
To create a production bundle, use `npm run build` or `yarn build`.
45+
-->
46+
</body>
47+
48+
</html>

client/src/App.css

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
body {
2+
margin: 0;
3+
font-family: 'JetBrains Mono', monospace;
4+
}
5+
6+
body {
7+
height: 100vh;
8+
width: 100vw;
9+
}
10+
11+
body::-webkit-scrollbar {
12+
display: none;
13+
}
14+
15+
#root {
16+
height: 100%;
17+
}

client/src/App.jsx

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
import { Routes, Route } from 'react-router-dom';
3+
import './App.css';
4+
import Signup from './components/signup';
5+
import ClipB from './components/clipboard';
6+
7+
function App() {
8+
return (
9+
<Routes>
10+
<Route exact path='/' element={<Signup />} />
11+
<Route path='/login' element={<Signup />} />
12+
<Route path='/clipboard' element={<ClipB />} />
13+
</Routes>
14+
);
15+
}
16+
17+
export default App;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
83 KB
Loading
8.44 KB
Loading
19.6 KB
Loading
483 Bytes
Loading
44.7 KB
Loading
95.1 KB
Loading
535 Bytes
Loading

0 commit comments

Comments
 (0)