diff --git a/.github/workflows/build-web.yml b/.github/workflows/build-web.yml new file mode 100644 index 0000000..ceceaba --- /dev/null +++ b/.github/workflows/build-web.yml @@ -0,0 +1,119 @@ +name: Build & Publish Web App + +on: + workflow_dispatch: + +permissions: + contents: write + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +jobs: + check-branch: + name: Validate Branch + runs-on: ubuntu-latest + steps: + - name: Assert development branch + run: | + echo "Triggered branch: ${{ github.ref_name }}" + if [ "${{ github.ref_name }}" != "development" ]; then + echo "Error: This workflow can only be manually run on the 'development' branch." + exit 1 + fi + + build-web: + name: Build Web App + needs: check-branch + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v6 + with: + token: ${{ secrets.PA_TOKEN }} + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 20 + + - name: Enable Corepack + run: corepack enable + + - name: Install Dependencies + run: yarn install --immutable + + - name: Build Web App + run: yarn build + env: + REACT_APP_GOOGLE_CLIENT_ID: ${{ secrets.REACT_APP_GOOGLE_CLIENT_ID }} + + - name: Upload Web Build Artifacts + uses: actions/upload-artifact@v7 + with: + name: web-build-frontend + path: build/ + retention-days: 1 + + release-web: + name: Release Web App + needs: build-web + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - name: Checkout Code + uses: actions/checkout@v6 + with: + token: ${{ secrets.PA_TOKEN }} + fetch-depth: 0 + + - name: Conventional Changelog Action + id: changelog + uses: TriPSs/conventional-changelog-action@latest + with: + github-token: ${{ secrets.PA_TOKEN }} + git-user-name: 'GrowBoard Bot' + output-file: false + version-file: 'package.json' + git-path: '.' + tag-prefix: 'v' + skip-on-empty: 'false' + + - name: Download Web Build Artifacts + if: ${{ steps.changelog.outputs.skipped == 'false' }} + uses: actions/download-artifact@v7 + with: + name: web-build-frontend + path: build/ + + - name: Zip Build Artifacts + if: ${{ steps.changelog.outputs.skipped == 'false' }} + run: | + cd build + zip -r ../web-build.zip . + cd .. + + - name: Create GitHub Release + uses: softprops/action-gh-release@v4 + if: ${{ steps.changelog.outputs.skipped == 'false' }} + with: + tag_name: ${{ steps.changelog.outputs.tag }} + name: ${{ steps.changelog.outputs.tag }} + body: ${{ steps.changelog.outputs.clean_changelog }} + files: web-build.zip + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.PA_TOKEN }} + + - name: 📂 Sync files + if: ${{ steps.changelog.outputs.skipped == 'false' }} + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.MAC_AMITRAIKWAR_FTP_SERVER }} + username: ${{ secrets.MAC_AMITRAIKWAR_FTP_ACCOUNT }} + password: ${{ secrets.MAC_AMITRAIKWAR_FTP_PASSWORD }} + local-dir: build/ + server-dir: ./ diff --git a/.github/workflows/ci-web.yml b/.github/workflows/ci-web.yml new file mode 100644 index 0000000..ce68202 --- /dev/null +++ b/.github/workflows/ci-web.yml @@ -0,0 +1,52 @@ +name: Web CI + +on: + push: + branches: + - development + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'yarn.lock' + - '.github/workflows/ci-web.yml' + pull_request: + branches: + - development + paths: + - 'src/**' + - 'public/**' + - 'package.json' + - 'yarn.lock' + - '.github/workflows/ci-web.yml' + +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true + +jobs: + web-ci: + name: Lint, Build and Test Web + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v6 + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 20 + + - name: Enable Corepack + run: corepack enable + + - name: Install Dependencies + run: yarn install --immutable + + - name: Lint + run: yarn lint + + - name: Build + run: yarn build + + - name: Test + run: yarn test --watchAll=false --passWithNoTests diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml deleted file mode 100644 index 7127a41..0000000 --- a/.github/workflows/deploy.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Deploy job - -on: - release: - types: [published] - -jobs: - setup_and_deploy: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - - name: Install Dependencies - run: yarn install - - name: Build - run: yarn build --if-present - - name: 📂 Sync files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 - with: - server: ${{ secrets.MAC_AMITRAIKWAR_FTP_SERVER }} - username: ${{ secrets.MAC_AMITRAIKWAR_FTP_ACCOUNT }} - password: ${{ secrets.MAC_AMITRAIKWAR_FTP_PASSWORD }} - local-dir: ./build/ - server-dir: ./ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 43c09d8..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Build - -on: - push: - branches: ['development'] - pull_request: - branches: ['development', 'production'] - -jobs: - build_test_lint: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [20.x] - steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - - name: Install Dependencies - run: yarn install - - name: Build - run: yarn build --if-present - - name: Linting - run: yarn lint - - name: Test - run: yarn test:cov - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4.0.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 51199c1..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Releases -on: - push: - branches: - - production - -permissions: - contents: write - -jobs: - release: - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v4 - with: - token: ${{ secrets.PA_TOKEN }} - - name: conventional changelog action - id: changelog - # https://github.com/TriPSs/conventional-changelog-action - uses: TriPSs/conventional-changelog-action@latest - with: - # you can also create separate token to trace action - github-token: '${{ secrets.PA_TOKEN }}' - git-user-name: 'AR mac Bot' - output-file: false - - name: create release - # https://github.com/actions/create-release - uses: softprops/action-gh-release@v1 - if: ${{steps.changelog.outputs.skipped == 'false'}} - env: - # This token is provided by Actions, you do not need to create your own token - GITHUB_TOKEN: ${{ secrets.PA_TOKEN }} - with: - tag_name: ${{ steps.changelog.outputs.tag }} - name: ${{ steps.changelog.outputs.tag }} - body: ${{steps.changelog.outputs.clean_changelog}} - draft: false - prerelease: false diff --git a/.yarnrc.yml b/.yarnrc.yml index 063ed60..9336184 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,8 +1,18 @@ approvedGitRepositories: - - "**" + - '**' + +cacheFolder: ./node_modules/.yarn/cache enableScripts: true +installStatePath: ./node_modules/.yarn/install-state.gz + nodeLinker: node-modules npmMinimalAgeGate: 0 + +patchFolder: ./node_modules/.yarn/patches + +pnpUnpluggedFolder: ./node_modules/.yarn/unplugged + +virtualFolder: ./node_modules/.yarn/__virtual__ diff --git a/jest.config.js b/jest.config.js index 2fc9b16..53ad8f6 100644 --- a/jest.config.js +++ b/jest.config.js @@ -24,8 +24,8 @@ module.exports = { moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'], moduleDirectories: ['node_modules'], moduleNameMapper: { - '@assets': '/src/assets', - '@assets/*': '/src/assets/*', + '^@assets$': '/src/assets', + '^@assets/(.*)$': '/src/assets/$1', '@router': '/src/router', '@screens': '/src/screens', '@hooks': '/src/hooks', diff --git a/package.json b/package.json index b97ade0..4f02f04 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "react-test-renderer": "^18.3.0", "ts-jest": "^29.1.2" }, + "packageManager": "yarn@4.17.0", "repository": "git@github.com:AmitRaikwar-in/MacMock.git", "author": "Amit Raikwar", "license": "MIT" diff --git a/src/assets/icons/SettingsIcons.tsx b/src/assets/icons/SettingsIcons.tsx new file mode 100644 index 0000000..37f6f98 --- /dev/null +++ b/src/assets/icons/SettingsIcons.tsx @@ -0,0 +1,677 @@ +import React from 'react'; + +// Wrapper to standardise macOS colored icon container +export const IconWrapper = ({ + color, + children, +}: { + color: string; + children: React.ReactNode; +}) => ( +
+ {children} +
+); + +export const WifiIcon = () => ( + + + + + + + + +); + +export const BluetoothIcon = () => ( + + + + + +); + +export const NetworkIcon = () => ( + + + + + + + +); + +export const BatteryIcon = () => ( + + + + + + +); + +export const GeneralIcon = () => ( + + + + + + +); + +export const AccessibilityIcon = () => ( + + + + + + +); + +export const AppearanceIcon = () => ( + + + + + + +); + +export const SiriIcon = () => ( + + + + + + +); + +export const DesktopDockIcon = () => ( + + + + + + + + +); + +export const DisplaysIcon = () => ( + + + + + + +); + +export const WallpaperIcon = () => ( + + + + + + + +); + +export const SoundIcon = () => ( + + + + + + +); + +export const AppleCareIcon = () => ( + + + +); + +export const InfoIcon = () => ( + + + + + +); + +export const SoftwareUpdateIcon = () => ( + + + +); + +export const StorageIcon = () => ( + + + + + + +); + +export const ContinuityIcon = () => ( + + + + +); + +export const AutoFillIcon = () => ( + + + + +); + +export const DateIcon = () => ( + + + + +); + +export const LanguageIcon = () => ( + + + + + +); + +export const LoginItemsIcon = () => ( + + + + +); + +export const SharingIcon = () => ( + + + + + +); + +export const ChevronIcon = () => ( + + + +); + +export const SearchIcon = () => ( + + + + +); + +export const BackIcon = ({ disabled }: { disabled: boolean }) => ( + + + +); + +export const ForwardIcon = ({ disabled }: { disabled: boolean }) => ( + + + +); + +export const NotificationsIcon = () => ( + + + + + + +); + +export const FocusIcon = () => ( + + + + + +); + +export const ScreenTimeIcon = () => ( + + + + + + + + +); + +export const LockScreenIcon = () => ( + + + + + + +); + +export const PrivacySecurityIcon = () => ( + + + + + + + + +); + +export const TouchIdPasswordIcon = () => ( + + + + + + + + + +); + +export const UsersGroupsIcon = () => ( + + + + + + + + +); + +export const InternetAccountsIcon = () => ( + + + + + + +); + +export const GameCenterIcon = () => ( + + + + + + + +); + +export const ICloudIcon = () => ( + + + + + +); + +export const WalletIcon = () => ( + + + + + + +); diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index 3057ab9..85463f5 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -20,6 +20,7 @@ export { BackIcon } from './Back'; export { RefreshIcon } from './Refresh'; export { MenuIcon } from './Menu'; export { InfoIcon } from './InfoIcon'; +export { AirDropIcon } from './AirDrop'; // Social icons export { LinkedInIcon } from './LinkedIn'; diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index c97eb03..07b57a2 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -1,4 +1,4 @@ -import { Modal, ModalContent } from '@chakra-ui/react'; +import { Box } from '@chakra-ui/react'; import { ModalProps } from './types'; import { SearchModal } from './Modals'; import { ModalID } from '@uiStore'; @@ -13,12 +13,36 @@ const ModalToShow = ({ modalID }: { modalID: ModalID }) => { }; const ModalComponent = ({ isOpen, modalID, onModalClose }: ModalProps) => { + if (!isOpen || modalID === 'none' || modalID === ('none' as any)) return null; + return ( - - + <> + {/* Custom Backdrop */} + + + {/* Custom Modal Content Container */} + - - + + ); }; diff --git a/src/components/Modal/Modals/Search/SearchModal.tsx b/src/components/Modal/Modals/Search/SearchModal.tsx index 9104753..327d46f 100644 --- a/src/components/Modal/Modals/Search/SearchModal.tsx +++ b/src/components/Modal/Modals/Search/SearchModal.tsx @@ -36,8 +36,9 @@ const SearchModal = () => { diff --git a/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap b/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap index 07a154f..e334edd 100644 --- a/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap +++ b/src/components/Modal/Modals/Search/__tests__/__snapshots__/SearchModal.test.tsx.snap @@ -11,7 +11,7 @@ exports[`SearchModal should not render component if isOpen is false 1`] = ` data-group="true" >
`; -exports[`Modal component search modal should render correctly 1`] = `
`; +exports[`Modal component search modal should render correctly 1`] = ` +
+
+
+
+
+
+ + + +
+ +
+
+
+
+
+`; diff --git a/src/components/Window/Window.tsx b/src/components/Window/Window.tsx index afc76e8..e1f9dde 100644 --- a/src/components/Window/Window.tsx +++ b/src/components/Window/Window.tsx @@ -3,7 +3,7 @@ import { WindowProps } from './types'; import { Box } from '@chakra-ui/react'; import { ResizableBox, ResizeCallbackData } from 'react-resizable'; import { useWindowDimensions } from '@hooks'; -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import './css/window.css'; import { darkModeColorSelector, @@ -21,7 +21,7 @@ import WindowCloseControl from './WindowControl'; const Window = ({ children, topBar, app }: WindowProps) => { const { windowTabBgColor } = settingsStore(useShallow(darkModeColorSelector)); const currentApp = processStore(useShallow(activeAppSelector))(app); - const { setWindowSize, updatePosition } = processStore( + const { setWindowSize, updatePosition, bringToFront } = processStore( useShallow(activeAppActionsSelector), ); @@ -37,6 +37,22 @@ const Window = ({ children, topBar, app }: WindowProps) => { }; const maximized = currentApp?.size === WindowSize.MAX ? true : false; + const [prevMaximized, setPrevMaximized] = useState(maximized); + const [isTransitioning, setIsTransitioning] = useState(false); + + if (maximized !== prevMaximized) { + setPrevMaximized(maximized); + setIsTransitioning(true); + } + + useEffect(() => { + if (isTransitioning) { + const timer = setTimeout(() => { + setIsTransitioning(false); + }, 500); + return () => clearTimeout(timer); + } + }, [isTransitioning]); const onMaximizeClick = () => { const newSize = maximized ? WindowSize.DEFAULT : WindowSize.MAX; @@ -47,67 +63,126 @@ const Window = ({ children, topBar, app }: WindowProps) => { updatePosition(app, position); }; + const handleBringToFront = () => { + bringToFront(app); + }; + + const [isOpening, setIsOpening] = useState(true); + + useEffect(() => { + const timer = setTimeout(() => { + setIsOpening(false); + }, 50); + return () => clearTimeout(timer); + }, []); + + const isMinimized = currentApp?.size === WindowSize.HIDE; + + // Bottom Center of the screen (mimicking Dock location) + const targetX = width / 2 - 400; + const targetY = height - 30; + + // Translation needed to move the window's center to the dock + const translateX = targetX; + const translateY = targetY; + + const shouldCollapse = isMinimized || isOpening; + + const minimizeStyle: React.CSSProperties = shouldCollapse + ? { + transform: `translate(${translateX}px, ${translateY}px) scale(0.01)`, + opacity: 0, + pointerEvents: 'none', + visibility: 'hidden', + zIndex: 0, + transition: + 'transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.4s ease-in-out, visibility 0.4s', + } + : { + transform: 'translate(0px, 0px) scale(1)', + opacity: 1, + pointerEvents: 'auto', + visibility: 'visible', + transition: + 'transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.2s ease-in-out, visibility 0s', + }; + return ( - - - - - - {topBar} + + + + {topBar} + + + + {children} - - {children} - - - - + + +
); }; diff --git a/src/components/Window/WindowControl.tsx b/src/components/Window/WindowControl.tsx index 46912d8..981f887 100644 --- a/src/components/Window/WindowControl.tsx +++ b/src/components/Window/WindowControl.tsx @@ -1,4 +1,4 @@ -import { Box, Text, useBoolean } from '@chakra-ui/react'; +import { Box, useBoolean } from '@chakra-ui/react'; import { ProgramType, WindowSize, @@ -7,22 +7,6 @@ import { useShallow, } from '@processStore'; -const CommonBoxProps = { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - alignContent: 'center', -}; - -const CommonTextProps = { - fontSize: 12, - fontWeight: 'bold', - _hover: { - cursor: 'pointer', - }, - transition: 'all 0.1s', -}; - const WindowControl = ({ app, onMaximizeClick, @@ -30,10 +14,15 @@ const WindowControl = ({ app: ProgramType; onMaximizeClick: () => void; }) => { - const [opacity, setOpacity] = useBoolean(false); + const [isHovered, setIsHovered] = useBoolean(false); + const { removeApp, setWindowSize } = processStore( useShallow(activeAppActionsSelector), ); + + const activeAppRunning = processStore((state) => state.ActiveApp.activeApp); + const isActive = activeAppRunning === app; + const onClose = () => { setTimeout(() => { removeApp(app); @@ -43,71 +32,143 @@ const WindowControl = ({ const onMinimize = () => { setWindowSize(app, WindowSize.HIDE); }; - const onMouseEnter = () => { - setOpacity.on(); - }; - const onMouseLeave = () => { - setOpacity.off(); - }; + // macOS Traffic Light styling + // Active Colors + const redBg = '#FF5F56'; + const redBorder = '#E0443E'; + const yellowBg = '#FFBD2E'; + const yellowBorder = '#DEA123'; + const greenBg = '#27C93F'; + const greenBorder = '#1AAB29'; + + // Inactive Colors (macOS Dark mode style since the design is dark-themed) + const inactiveBg = '#4C4C4C'; + const inactiveBorder = '#3A3A3A'; + + // Icon Stroke Colors (only visible on hover) + const redStroke = '#4C0002'; + const yellowStroke = '#5C3E00'; + const greenStroke = '#004D05'; return ( - <> + + {/* Close Button */} - - x - + + + + {/* Minimize Button */} - - - - + + + + {/* Maximize Button */} - - o - + + - + ); }; diff --git a/src/components/Window/__tests__/WindowControl.test.tsx b/src/components/Window/__tests__/WindowControl.test.tsx index 8b27255..7034bb4 100644 --- a/src/components/Window/__tests__/WindowControl.test.tsx +++ b/src/components/Window/__tests__/WindowControl.test.tsx @@ -81,11 +81,11 @@ describe('WindowControl', () => { />, ); - fireEvent.mouseEnter(screen.getByText('x')); + fireEvent.mouseEnter(screen.getByTestId('traffic-lights')); expect(container).toMatchSnapshot(); - fireEvent.mouseLeave(screen.getByText('x')); + fireEvent.mouseLeave(screen.getByTestId('traffic-lights')); expect(container).toMatchSnapshot(); }); diff --git a/src/components/Window/__tests__/Windows.test.tsx b/src/components/Window/__tests__/Windows.test.tsx index 9c2f197..2a64953 100644 --- a/src/components/Window/__tests__/Windows.test.tsx +++ b/src/components/Window/__tests__/Windows.test.tsx @@ -254,7 +254,7 @@ describe('Windows', () => { expect(capturedDraggableProps.maximized).toBe(true); expect(capturedResizableProps.resizeHandles).toEqual([]); - expect(capturedResizableProps.style.transition).toBe('all 0.2s'); + expect(capturedResizableProps.style.transition).toBe('all 0.3s cubic-bezier(0.16, 1, 0.3, 1)'); // Test toggle back to DEFAULT fireEvent.click(screen.getByLabelText('maximize')); diff --git a/src/components/Window/__tests__/__snapshots__/WindowControl.test.tsx.snap b/src/components/Window/__tests__/__snapshots__/WindowControl.test.tsx.snap index ea8ef7c..0c12be1 100644 --- a/src/components/Window/__tests__/__snapshots__/WindowControl.test.tsx.snap +++ b/src/components/Window/__tests__/__snapshots__/WindowControl.test.tsx.snap @@ -3,34 +3,70 @@ exports[`WindowControl should render correctly 1`] = `
-

- x -

-
-
-

+ + +

+
- - -

-
-
-

+ + +

+
- o -

+ + + +
`; @@ -38,34 +74,70 @@ exports[`WindowControl should render correctly 1`] = ` exports[`WindowControl should trigger mouse enter and leave event 1`] = `
-

- x -

-
-
-

+ + +

+
- - -

-
-
-

+ + +

+
- o -

+ + + +
`; @@ -73,34 +145,70 @@ exports[`WindowControl should trigger mouse enter and leave event 1`] = ` exports[`WindowControl should trigger mouse enter and leave event 2`] = `
-

- x -

-
-
-

+ + +

+
- - -

-
-
-

+ + +

+
- o -

+ + + +
`; diff --git a/src/components/Window/__tests__/__snapshots__/Windows.test.tsx.snap b/src/components/Window/__tests__/__snapshots__/Windows.test.tsx.snap index 3adcfde..c243b26 100644 --- a/src/components/Window/__tests__/__snapshots__/Windows.test.tsx.snap +++ b/src/components/Window/__tests__/__snapshots__/Windows.test.tsx.snap @@ -3,62 +3,102 @@ exports[`Windows should render for default values 1`] = `
-

- x -

-
-
-

- - -

-
-
-

+ + + +

+
+ + + +
+
+ + + +
+
+
- o -

+
+ Top bar +
+
- Top bar + Test
-
-
- Test -
-
@@ -68,56 +108,96 @@ exports[`Windows should render for default values 1`] = ` exports[`Windows should render maximized window 1`] = `
-

- x -

-
-
-

- - -

+
+ + + +
+
+ + + +
+
+ + + +
+
+
-

- o -

-
-
-
-
-
- Test +
+ Test +
@@ -129,56 +209,96 @@ exports[`Windows should render maximized window 1`] = ` exports[`Windows should toggle maximize on double click on title bar 1`] = `
-

- x -

-
-
-

- - -

+
+ + + +
+
+ + + +
+
+ + + +
+
+
-

- o -

-
-
-
-
-
- Test +
+ Test +
@@ -190,56 +310,96 @@ exports[`Windows should toggle maximize on double click on title bar 1`] = ` exports[`Windows should trigger close on close button press 1`] = `
-

- x -

-
-
-

- - -

+
+ + + +
+
+ + + +
+
+ + + +
+
+
-

- o -

-
-
-
-
-
- Test +
+ Test +
@@ -251,56 +411,96 @@ exports[`Windows should trigger close on close button press 1`] = ` exports[`Windows should trigger maximize on maximize button press 1`] = `
-

- x -

-
-
-

- - -

+
+ + + +
+
+ + + +
+
+ + + +
+
+
-

- o -

-
-
-
-
-
- Test +
+ Test +
@@ -312,56 +512,96 @@ exports[`Windows should trigger maximize on maximize button press 1`] = ` exports[`Windows should trigger minimize on minimize button press 1`] = `
-

- x -

-
-
-

- - -

+
+ + + +
+
+ + + +
+
+ + + +
+
+
-

- o -

-
-
-
-
-
- Test +
+ Test +
diff --git a/src/localization/locales/en/main.json b/src/localization/locales/en/main.json index c93ff81..e42955e 100644 --- a/src/localization/locales/en/main.json +++ b/src/localization/locales/en/main.json @@ -21,7 +21,7 @@ "loginPasswordText2": "Your password is required to enable Touch ID", "inputPlaceholder": "Enter Password", "passwordHintLabel": "Password Hint", - "passwordHint": "Your password is the same as your macOS user account password. If you've forgotten it, try entering your Apple ID password or use the Reset Password assistant. Please use - 'Amit'", + "passwordHint": "Your password is the same as your macOS user account password. If you've forgotten it, try entering your Apple ID password or use the Reset Password assistant. Please use - '1234'", "keyboard": { "type": "ABC - India", "option": { diff --git a/src/providers/draggable/DraggableProvider.tsx b/src/providers/draggable/DraggableProvider.tsx index 239d742..56b6af3 100644 --- a/src/providers/draggable/DraggableProvider.tsx +++ b/src/providers/draggable/DraggableProvider.tsx @@ -7,32 +7,30 @@ const DraggableProvider = ({ position, maximized, onPositionChange, + onStart, }: DraggableProps) => { const { width, height } = useWindowDimensions(); - const positionHandler = maximized - ? {} - : { - onStop: (e: any, data: any) => { - const { x, y } = data; - onPositionChange({ x, y }); - }, - }; + const draggableProps = { + handle: '.handle', + bounds: { left: 0, top: 0, right: width, bottom: height }, + positionOffset: { x: 0, y: 28 }, + defaultPosition: maximized ? position : { x: 0, y: 0 }, + position: !maximized ? position : { x: 0, y: 0 }, + grid: [3, 3] as [number, number], + scale: 1, + ...(maximized + ? {} + : { + onStart: onStart ? () => onStart() : undefined, + onStop: (_e: any, data: any) => { + const { x, y } = data; + onPositionChange({ x, y }); + }, + }), + } as React.ComponentProps; - return ( - - {children} - - ); + return {children}; }; export default DraggableProvider; diff --git a/src/providers/draggable/types.ts b/src/providers/draggable/types.ts index 370328c..05510d0 100644 --- a/src/providers/draggable/types.ts +++ b/src/providers/draggable/types.ts @@ -8,4 +8,6 @@ export type DraggableProps = { position: Position; maximized: boolean; onPositionChange: (position: Position) => void; + /** Called when a drag starts — use to bring window to front */ + onStart?: () => void; }; diff --git a/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap b/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap index e12659a..da96577 100644 --- a/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap +++ b/src/providers/routerProvider/__tests__/__snapshots__/RouterProvider.test.tsx.snap @@ -24,12 +24,12 @@ exports[`RouterProvider should render for lock when power is on but user logged class="css-sikaw0" >
+

+

+
@@ -1316,53 +1318,101 @@ exports[`RouterProvider should render mac for login 1`] = `
-
+
-
+ + + + +
-
+
-
-
- + +
+ +
+
+ - ⌘ X + ⌘X -

+
+ +
+
+ + -
- -
@@ -2748,16 +3051,16 @@ exports[`RouterProvider should render mac for login 1`] = ` -
- - - - - - + + @@ -3852,12 +3271,12 @@ exports[`RouterProvider should render mac for login 1`] = ` role="group" >
+
+ +
@@ -455,7 +508,7 @@ exports[`LazyHomeComponent should render correctly to match snapshot 1`] = ` tabindex="-1" > -
+
-
+ + + + +
-
+
-
-
+ + +
+ +
+
- ⌘ X + ⌘X -

+
+ +
+ + + - - - + + - - + + - - - - - - - - + + @@ -2795,12 +2212,12 @@ exports[`LazyHomeComponent should render correctly to match snapshot 1`] = ` role="group" > + + + +`; + +exports[`Home should render correctly with apps to match snapshot 1`] = ` +
+
+
+ +
+
+
+
+
-
-
- - - - - -
-
-
-
-
-
- Launchpad -
-
- Finder -
-
- Notes -
-
- Chrome -
-
- VsCode -
-
- Terminal -
-
- Spotify -
-
- Github -
-
- Settings -
-
-
- numbers -
-
- pages -
-
- xcode -
-
-
- Bin -
-
-
-
-
-
-
-`; - -exports[`Home should render correctly with apps to match snapshot 1`] = ` -
-
-
- -
-
-
-
- - -
- - -
- - - ⌘ X + ⌘X -

+
+ +
+
+ + -
- - +
+ + + + + + +
+
- - Stop Debugging - - - ⇧F5 - - - -
- -
- +

- Step Over - - +

- F10 - - -

+
- - Step Into - - - F11 - - - +

- Step Out - - +

- ⇧F11 - - -

+
- - Continue - -
+
+
+ +
+
+ + -
-
+ -

- Dark mode -

-

- Off -

-
-
- +

+ Focus +

+
+ +

- Night Shift + Display

+
+
+
+ + + +
+
+
+ +
+
+

- Off + Sound

+
+
+
+ + + + + +
+
+
+ +
-

- True Tone -

-

- Off -

-
-
- - - - - - - - @@ -7325,9 +8002,6 @@ exports[`Home should render correctly with apps to match snapshot 1`] = ` -
`; @@ -7360,12 +8034,12 @@ exports[`Home should render correctly with bin app to match snapshot 1`] = ` role="group" > + + + +
+ + + + + + - - - -
-
-
-
- Launchpad -
-
- Finder -
-
- Notes -
-
- Chrome -
-
- VsCode -
-
- Terminal -
- Spotify +
+
+
+
+

+ THURSDAY +

+

+ 14 +

+
+

+ No Events Today +

+
+
+
+

+ Pune ↗ +

+

+ 23° +

+
+
+
+ + + +

+ Mostly Cloudy +

+
+

+ H:29° L:22° +

+
+
+
+
+
+
+
+
+
+

+ Cupertino +

+

+ Yesterday +

+

+ -12:30 +

+
+
+
+
+
+

+ Tokyo +

+

+ Today +

+

+ +3:30 +

+
+
+
+
+
+

+ Sydney +

+

+ Today +

+

+ +4:30 +

+
+
+
+
+
+

+ Paris +

+

+ Yesterday +

+

+ -3:30 +

+
+
+
+
+
+
+
+

+ ▼ DOW +

+

+ 52,499 +

+
+
+

+ ▼ S&P 500 +

+

+ 7,515 +

+
+
+

+ ▲ AAPL +

+

+ 317.31 +

+
+
+
+

+ Economic Times +

+

+ US stocks today: S&P 500 and Nasdaq open lo... +

+
+
+
+
+

+ 1h 55m +

+
+
+
+

+ 60m +

+
+
+

+ 30m +

+
+
+

+ 0 +

+
+
+
+
+
+
+
+

+ 12 AM +

+

+ 6 AM +

+

+ 12 PM +

+
+
+
+
+
+ +

+ Xcode +

+
+

+ 1h 14m +

+
+
+
+ +

+ Chrome +

+
+

+ 38m +

+
+
+
+ +

+ Settings +

+
+

+ 1m +

+
+
+
+ +

+ Finder +

+
+

+ 18s +

+
+
+
+
+
+ +
+

+ ✕ +

+
+
+
+
+
+
+
+
+
Github
Settings
-
numbers
pages
- xcode + VsCode +
+
+ Terminal +
+
+ Spotify +
+
+ Github +
+
+ Settings +
+
+
+ numbers +
+
+ pages +
+
+ xcode
-
-
-
-
-
-
-
- Launchpad -
-
- Finder -
-
- Notes -
-
- Chrome -
- VsCode +
+
+
+
+

+ THURSDAY +

+

+ 14 +

+
+

+ No Events Today +

+
+
+
+

+ Pune ↗ +

+

+ 23° +

+
+
+
+ + + +

+ Mostly Cloudy +

+
+

+ H:29° L:22° +

+
+
+
+
+
+
+
+
+
+

+ Cupertino +

+

+ Yesterday +

+

+ -12:30 +

+
+
+
+
+
+

+ Tokyo +

+

+ Today +

+

+ +3:30 +

+
+
+
+
+
+

+ Sydney +

+

+ Today +

+

+ +4:30 +

+
+
+
+
+
+

+ Paris +

+

+ Yesterday +

+

+ -3:30 +

+
+
+
+
+
+
+
+

+ ▼ DOW +

+

+ 52,499 +

+
+
+

+ ▼ S&P 500 +

+

+ 7,515 +

+
+
+

+ ▲ AAPL +

+

+ 317.31 +

+
+
+
+

+ Economic Times +

+

+ US stocks today: S&P 500 and Nasdaq open lo... +

+
+
+
+
+

+ 1h 55m +

+
+
+
+

+ 60m +

+
+
+

+ 30m +

+
+
+

+ 0 +

+
+
+
+
+
+
+
+

+ 12 AM +

+

+ 6 AM +

+

+ 12 PM +

+
+
+
+
+
+ +

+ Xcode +

+
+

+ 1h 14m +

+
+
+
+ +

+ Chrome +

+
+

+ 38m +

+
+
+
+ +

+ Settings +

+
+

+ 1m +

+
+
+
+ +

+ Finder +

+
+

+ 18s +

+
+
+
+
+
+ +
+

+ ✕ +

+
+
+
+
+
+
+
+
+
Terminal
Spotify
Github
Settings
-
+ VsCode +
+
+ Terminal +
+
+ Spotify +
+
+ Github +
+
+ Settings +
+
+
-
+
+
+ + + +
+
+

+ Bluetooth +

+

+ On +

+
+
+
+
+ + + +
+
+

+ AirDrop +

+

+ Off +

+
+
+
+
+
+
+
+
+

+ Not Playing +

+
+
+
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+
+ + + + + + +
+
+ + + + +
+
+
+
+
+
+ + + + +
+
+ + + + +
+
+ + + +

+ Focus +

+
+
+
+

+ Display +

+
+
+
+ + + +
+
+
+ +
+
+
+

+ Sound +

+
+
+
+ + + + + +
+
+
+ +
+
+
+ +
+
+
+
+ -
-
-
-
-
-
-
- Launchpad -
-
- Finder -
-
- Notes -
- Chrome
-
-
- VsCode -
-
- Terminal + class="chakra-stack css-1jbmm9k" + > +
+
+
+

+ THURSDAY +

+

+ 14 +

+
+

+ No Events Today +

+
+
+
+

+ Pune ↗ +

+

+ 23° +

+
+
+
+ + + +

+ Mostly Cloudy +

+
+

+ H:29° L:22° +

+
+
+
+
+
+
+
+
+
+

+ Cupertino +

+

+ Yesterday +

+

+ -12:30 +

+
+
+
+
+
+

+ Tokyo +

+

+ Today +

+

+ +3:30 +

+
+
+
+
+
+

+ Sydney +

+

+ Today +

+

+ +4:30 +

+
+
+
+
+
+

+ Paris +

+

+ Yesterday +

+

+ -3:30 +

+
+
+
+
+
+
+
+

+ ▼ DOW +

+

+ 52,499 +

+
+
+

+ ▼ S&P 500 +

+

+ 7,515 +

+
+
+

+ ▲ AAPL +

+

+ 317.31 +

+
+
+
+

+ Economic Times +

+

+ US stocks today: S&P 500 and Nasdaq open lo... +

+
+
+
+
+

+ 1h 55m +

+
+
+
+

+ 60m +

+
+
+

+ 30m +

+
+
+

+ 0 +

+
+
+
+
+
+
+
+

+ 12 AM +

+

+ 6 AM +

+

+ 12 PM +

+
+
+
+
+
+ +

+ Xcode +

+
+

+ 1h 14m +

+
+
+
+ +

+ Chrome +

+
+

+ 38m +

+
+
+
+ +

+ Settings +

+
+

+ 1m +

+
+
+
+ +

+ Finder +

+
+

+ 18s +

+
+
+
+
+
+ +
+

+ ✕ +

+
+
+
+
+
+
+
+
+
Spotify
Github
Settings
-
numbers -
-
- pages +
+
+ VsCode +
+
+ Terminal +
+
+ Spotify +
+
+ Github +
+
+ Settings +
+
+
+ numbers +
+
+ pages
+
+
+`; + +exports[`Home should render correctly with finder app to match snapshot 1`] = ` +
+
+
+ +
+
+
+
+ + +
+ + + + + + + + - +

+ Go +

+ +
-
-
-
-
- -
-
-
-
-`; - -exports[`Home should render correctly with finder app to match snapshot 1`] = ` -
-
-
- -
-
-
-
- - + +
-
+ -