Compare commits
4 Commits
880ef9eae5
...
0328183852
| Author | SHA1 | Date |
|---|---|---|
|
|
0328183852 | |
|
|
39014708d7 | |
|
|
0b7d844753 | |
|
|
9fc9b964c2 |
|
|
@ -13,6 +13,7 @@ dist-react
|
||||||
dist-electron
|
dist-electron
|
||||||
release
|
release
|
||||||
*.local
|
*.local
|
||||||
|
release
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|
|
||||||
10
package.json
10
package.json
|
|
@ -12,7 +12,7 @@
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"transpile:electron": "tsc --project src/electron/tsconfig.json",
|
"transpile:electron": "tsc --project src/electron/tsconfig.json",
|
||||||
"dist:mac": "npm run transpile:electron && npm run build && electron-builder --mac --arm64",
|
"dist:mac": "npm run transpile:electron && npm run build && electron-builder --mac --x64 --arm64",
|
||||||
"dist:win": "npm run transpile:electron && npm run build && electron-builder --win --x64",
|
"dist:win": "npm run transpile:electron && npm run build && electron-builder --win --x64",
|
||||||
"dist:linux": "npm run transpile:electron && npm run build && electron-builder --linux --x64",
|
"dist:linux": "npm run transpile:electron && npm run build && electron-builder --linux --x64",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
|
|
@ -68,6 +68,14 @@
|
||||||
"to": "assets"
|
"to": "assets"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"mac": {
|
||||||
|
"target": ["dmg"],
|
||||||
|
"icon": "build/icon.icns",
|
||||||
|
"extendInfo": {
|
||||||
|
"LSUIElement": false,
|
||||||
|
"LSBackgroundOnly": false
|
||||||
|
}
|
||||||
|
},
|
||||||
"win": {
|
"win": {
|
||||||
"target": [
|
"target": [
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,8 @@ app.on("ready", async () => {
|
||||||
alwaysOnTop: true,
|
alwaysOnTop: true,
|
||||||
skipTaskbar: true,
|
skipTaskbar: true,
|
||||||
autoHideMenuBar: true,
|
autoHideMenuBar: true,
|
||||||
frame: process.platform === "darwin" ? false : true,
|
frame: true,
|
||||||
show: false, // speed improvement
|
show: false,
|
||||||
icon: resolveIcon(),
|
icon: resolveIcon(),
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
devTools: true,
|
devTools: true,
|
||||||
|
|
@ -105,6 +105,10 @@ app.on("ready", async () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
win.setAlwaysOnTop(true, 'screen-saver');
|
||||||
|
win.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
||||||
|
win.setFullScreenable(false);
|
||||||
|
|
||||||
mainWindow = win;
|
mainWindow = win;
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -137,11 +137,14 @@ export const getRunningAppsList = async () => {
|
||||||
thumbnailSize: { width: 150, height: 150 } // Optional: set thumbnail size
|
thumbnailSize: { width: 150, height: 150 } // Optional: set thumbnail size
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(sources, "Sources Retrieved");
|
||||||
|
|
||||||
const app = sources.map(source => ({
|
const app = sources.map(source => ({
|
||||||
name: source.name,
|
name: source.name,
|
||||||
pid: source.id,
|
pid: source.id,
|
||||||
// thumbnail: source.thumbnail // Can be used as screenshot
|
// thumbnail: source.thumbnail // Can be used as screenshot
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return app
|
return app
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return []
|
return []
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import ReactQuill from "react-quill-new";
|
||||||
|
import Quill from "quill";
|
||||||
|
// import ImageResize from "quill-image-resize-module-react";
|
||||||
|
|
||||||
|
// Quill.register("modules/imageResize", ImageResize);
|
||||||
|
|
||||||
|
export const quillModules = {
|
||||||
|
toolbar: [
|
||||||
|
[{ header: [1, 2, 3, false] }],
|
||||||
|
["bold", "italic", "underline"],
|
||||||
|
["image", "link"],
|
||||||
|
],
|
||||||
|
// imageResize: {},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// utils/timeDisplay.js
|
||||||
|
export const getDisplayTime = (project:any, trackingData:any) => {
|
||||||
|
if (!project) return "0h 0m 0s";
|
||||||
|
|
||||||
|
// If tracking is active, calculate current time based on server time + session time
|
||||||
|
if (trackingData?.isTracking && trackingData.startTime) {
|
||||||
|
const baseSeconds = parseTimeStringToSeconds(project.totalWorkTime);
|
||||||
|
const sessionSeconds = Math.floor((Date.now() - trackingData.startTime) / 1000);
|
||||||
|
const totalSeconds = baseSeconds + sessionSeconds;
|
||||||
|
return formatSecondsToTimeString(totalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not tracking, just return the server's totalWorkTime
|
||||||
|
return project.totalWorkTime;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseTimeStringToSeconds = (timeString:any) => {
|
||||||
|
if (!timeString || typeof timeString !== 'string') return 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const hourMatch = timeString.match(/(\d+)h/);
|
||||||
|
const minMatch = timeString.match(/(\d+)m/);
|
||||||
|
const secMatch = timeString.match(/(\d+)s/);
|
||||||
|
|
||||||
|
const hours = hourMatch ? parseInt(hourMatch[1]) : 0;
|
||||||
|
const minutes = minMatch ? parseInt(minMatch[1]) : 0;
|
||||||
|
const seconds = secMatch ? parseInt(secMatch[1]) : 0;
|
||||||
|
|
||||||
|
return hours * 3600 + minutes * 60 + seconds;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error parsing time string:', timeString, error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const formatSecondsToTimeString = (totalSeconds:any) => {
|
||||||
|
const hours = Math.floor(totalSeconds / 3600);
|
||||||
|
const minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||||
|
const seconds = totalSeconds % 60;
|
||||||
|
return `${hours}h ${minutes}m ${seconds}s`;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
// utils/timeParser.js
|
||||||
|
export const parseTimeStringToMs = (timeString:string) => {
|
||||||
|
if (!timeString) return 0;
|
||||||
|
|
||||||
|
const hourMatch = timeString.match(/(\d+)h/);
|
||||||
|
const minMatch = timeString.match(/(\d+)m/);
|
||||||
|
const secMatch = timeString.match(/(\d+)s/);
|
||||||
|
|
||||||
|
const hours = hourMatch ? parseInt(hourMatch[1]) : 0;
|
||||||
|
const minutes = minMatch ? parseInt(minMatch[1]) : 0;
|
||||||
|
const seconds = secMatch ? parseInt(secMatch[1]) : 0;
|
||||||
|
|
||||||
|
return (hours * 3600 + minutes * 60 + seconds) * 1000;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parseTimeStringToSeconds = (timeString:string) => {
|
||||||
|
return Math.floor(parseTimeStringToMs(timeString) / 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in New Issue