Skip to content

Commit

Permalink
feat: migrate to ts components (#6603)
Browse files Browse the repository at this point in the history
* feat: migrate to ts components

* fixes

* working changes

* fix type errors

* fix react import

* Migrate to TS

* CR Fixes

* CR Fixes

* CR Fixes

* fix tests

* remove coverage test

* CR Changes

---------

Co-authored-by: Amir Ghezelbash <thisisamir98@gmail.com>
  • Loading branch information
phoenixhdd and thisisamir98 committed May 9, 2023
1 parent cfaf952 commit 8e646eb
Show file tree
Hide file tree
Showing 48 changed files with 612 additions and 319 deletions.
15 changes: 14 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@
"rules": {
"import/no-default-export": "off",
"no-magic-numbers": "off",
"no-undef": "off"
"no-undef": "off",
"jest/expect-expect": [
"error",
{
"assertFunctionNames": ["expect", "fc.assert", "assert"]
}
]
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}
2 changes: 1 addition & 1 deletion babel.config.js → babel.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const buildPresets = ({debug = false, modules = false}) => {
},
];

return ['@babel/preset-react', '@babel/preset-typescript', browserEnvPreset];
return [['@babel/preset-react', {runtime: 'automatic'}], '@babel/preset-typescript', browserEnvPreset];
};

/** @type {import('@babel/core').TransformOptions} */
Expand Down
7 changes: 0 additions & 7 deletions bin/build-tools/build-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,6 @@ import {buildMacOSConfig, buildMacOSWrapper} from './lib/build-macos';
import {buildWindowsConfig, buildWindowsWrapper} from './lib/build-windows';
import {buildWindowsInstaller, buildWindowsInstallerConfig} from './lib/build-windows-installer';

interface CommanderData {
envFile: string;
manualSign?: boolean;
packageJson: string;
wireJson: string;
}

const toolName = path.basename(__filename).replace('.ts', '');
const logger = LogFactory.getLogger(toolName, {forceEnable: true, namespace: '@wireapp/build-tools'});
const appSource = path.join(__dirname, '../../');
Expand Down
4 changes: 2 additions & 2 deletions electron/renderer/src/actions/AccountAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*
*/

import {EVENT_TYPE} from '../../../dist/lib/eventType';
import {config} from '../../../dist/settings/config';
import {EVENT_TYPE} from '../../../src/lib/eventType';
import {config} from '../../../src/settings/config';
import {AccountSelector} from '../selector/AccountSelector';

import {ActionType, initiateSSO} from './';
Expand Down
2 changes: 1 addition & 1 deletion electron/renderer/src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const deleteAccount = id => ({
type: ActionType.DELETE_ACCOUNT,
});

export const resetIdentity = (id = true) => ({
export const resetIdentity = id => ({
id,
type: ActionType.RESET_IDENTITY,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@
*
*/

import React from 'react';

import PropTypes from 'prop-types';

import './AccountIcon.css';

import {colorFromId} from '../lib/accentColor';
import {colorFromId} from '../../lib/accentColor';
import {Account} from '../../types/account';

const AccountIcon = ({account, ...props}) => {
interface AccountIconProps {
account: Account;
}

export const AccountIcon = ({account, ...props}: AccountIconProps) => {
const accountType = () => {
if (!account.name) {
return 'new';
Expand All @@ -49,6 +50,7 @@ const AccountIcon = ({account, ...props}) => {
style={{borderColor: colorFromId(account.accentID)}}
/>
)}

<div className="AccountIcon-inner">
{account.picture ? (
<img src={account.picture} alt="Account Icon" />
Expand All @@ -59,9 +61,3 @@ const AccountIcon = ({account, ...props}) => {
</div>
);
};

AccountIcon.propTypes = {
account: PropTypes.object.isRequired,
};

export default AccountIcon;
20 changes: 20 additions & 0 deletions electron/renderer/src/components/AccountIcon/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

export * from './AccountIcon';
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,19 @@
*
*/

import React from 'react';

import {connect} from 'react-redux';

import {StyledApp} from '@wireapp/react-ui-kit';

import IsOnline from './IsOnline';
import Sidebar from './Sidebar';
import WebviewList from './WebviewList';
import {StyledApp, THEME_ID} from '@wireapp/react-ui-kit';

import actionRoot from '../actions';
import {AccountSelector} from '../selector/AccountSelector';
import actionRoot from '../../actions';
import {AccountSelector} from '../../selector/AccountSelector';
import {IsOnline} from '../IsOnline';
import Sidebar from '../Sidebar/Sidebar';
import WebviewList from '../WebViewList/WebviewList';

const App = () => {
return (
<StyledApp style={{height: '100%'}}>
<StyledApp style={{height: '100%'}} themeId={THEME_ID.DEFAULT}>
<IsOnline>
<div style={{display: 'flex', height: '100%', width: '100%'}}>
<Sidebar />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
*
*/

import React, {useEffect, useState} from 'react';
import {useEffect, useState, ReactElement} from 'react';

import {Text, ContainerSM} from '@wireapp/react-ui-kit';

import {getText} from '../lib/locale';
import {getText} from '../../lib/locale';

const IsOnline = ({children}) => {
interface IsOnlineProps {
children: ReactElement;
}

export const IsOnline = ({children}: IsOnlineProps) => {
const [isOnline, setIsOnline] = useState(navigator.onLine);

useEffect(() => {
Expand All @@ -46,5 +50,3 @@ const IsOnline = ({children}) => {
</div>
);
};

export default IsOnline;
20 changes: 20 additions & 0 deletions electron/renderer/src/components/IsOnline/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

export * from './IsOnline';
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,22 @@
*
*/

import React, {useEffect, useState} from 'react';
import {useEffect, useState, MutableRefObject} from 'react';

import {FlexBox, Loading, COLOR} from '@wireapp/react-ui-kit';

import './LoadingSpinner.css';

type WebviewTag = Electron.WebviewTag;

const TRANSITION_GRACE_PERIOD_MS = 500;

const LoadingSpinner = ({visible, webviewRef}) => {
interface LoadingSpinnerProps {
visible: boolean;
webviewRef: MutableRefObject<WebviewTag | null>;
}

export const LoadingSpinner = ({visible, webviewRef}: LoadingSpinnerProps) => {
const [isLoading, setIsLoading] = useState(true);
const [isFinished, setIsFinished] = useState(false);

Expand All @@ -39,11 +46,13 @@ const LoadingSpinner = ({visible, webviewRef}) => {
webview.removeEventListener('did-finish-load', setLoading);
};
}

return () => undefined;
});

useEffect(() => {
if (!isLoading) {
let timeout = setTimeout(() => {
let timeout: NodeJS.Timeout | null = setTimeout(() => {
timeout = null;
setIsFinished(true);
}, TRANSITION_GRACE_PERIOD_MS);
Expand All @@ -54,6 +63,8 @@ const LoadingSpinner = ({visible, webviewRef}) => {
}
};
}

return () => undefined;
}, [isLoading]);

if (!visible || isFinished) {
Expand All @@ -75,5 +86,3 @@ const LoadingSpinner = ({visible, webviewRef}) => {
</div>
);
};

export default LoadingSpinner;
20 changes: 20 additions & 0 deletions electron/renderer/src/components/LoadingSpinner/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Wire
* Copyright (C) 2023 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

export * from './LoadingSpinner';
Original file line number Diff line number Diff line change
Expand Up @@ -21,36 +21,57 @@ import React from 'react';

import {connect} from 'react-redux';

import AccountIcon from './AccountIcon';
import AddAccountTrigger from './context/AddAccountTrigger';
import EditAccountMenu from './context/EditAccountMenu';
import './Sidebar.css';

import {EVENT_TYPE} from '../../../dist/lib/eventType';
import {addAccountWithSession, setAccountContextHidden, toggleEditAccountMenuVisibility} from '../actions';
import {colorFromId} from '../lib/accentColor';
import {isEnterKey} from '../lib/keyboardUtil';
import {preventFocus} from '../lib/util';
import {AccountSelector} from '../selector/AccountSelector';
import {ContextMenuSelector} from '../selector/ContextMenuSelector';
import {EVENT_TYPE} from '../../../../src/lib/eventType';
import {addAccountWithSession, setAccountContextHidden, toggleEditAccountMenuVisibility} from '../../actions';
import {colorFromId} from '../../lib/accentColor';
import {isEnterKey} from '../../lib/keyboardUtil';
import {preventFocus} from '../../lib/util';
import {AccountSelector} from '../../selector/AccountSelector';
import {ContextMenuSelector} from '../../selector/ContextMenuSelector';
import {Account} from '../../types/account';
import {AccountIcon} from '../AccountIcon';
import AddAccountTrigger from '../context/AddAccountTrigger';
import EditAccountMenu from '../context/EditAccountMenu';

const centerOfEventTarget = event => {
const centerOfEventTarget = (event: React.MouseEvent<Element, MouseEvent>) => {
const clientRectangle = event.currentTarget.getBoundingClientRect();
const centerX = clientRectangle.left + clientRectangle.width / 2;
const centerY = clientRectangle.top + clientRectangle.height / 2;
return {centerX, centerY};
};

const getClassName = account => {
const getClassName = (account: Account) => {
const showIconBadge = account.badgeCount > 0 ? ' Sidebar-icon-badge' : '';
const showIconCursor = account.visible ? '' : ' Sidebar-icon-cursor';
return `Sidebar-icon${showIconBadge}${showIconCursor}`;
};

const handleSwitchAccount = accountIndex => {
const handleSwitchAccount = (accountIndex: number) => {
window.dispatchEvent(new CustomEvent(EVENT_TYPE.ACTION.SWITCH_ACCOUNT, {detail: {accountIndex: accountIndex}}));
};

interface SidebarProps {
accounts: Account[];
currentAccentID: number;
hasCreatedAccount: boolean;
hasReachedLimitOfAccounts: boolean;
isAddingAccount: boolean;
isDarkMode: boolean;
isEditAccountMenuVisible: boolean;
setAccountContextHidden: () => void;
toggleEditAccountMenuVisibility: (
centerX: number,
centerY: number,
accountId: string,
sessionID: string,
lifecycle: string,
isAtLeastAdmin: boolean,
) => void;
addAccountWithSession: () => void;
}

const Sidebar = ({
accounts,
currentAccentID,
Expand All @@ -60,18 +81,22 @@ const Sidebar = ({
isAddingAccount,
isEditAccountMenuVisible,
...connected
}) => (
}: SidebarProps) => (
<div
role="button"
tabIndex={0}
className={`${isDarkMode ? 'Sidebar theme-dark' : 'Sidebar theme-light'}`}
style={!hasCreatedAccount ? {display: 'none'} : {}}
onMouseDown={preventFocus()}
onKeyDown={connected.setAccountContextHidden}
onClick={connected.setAccountContextHidden}
>
{accounts.map(account => {
const accountIndex = accounts.indexOf(account);
return (
<div className="Sidebar-cell" key={account.id}>
<div
role="button"
style={{color: colorFromId(currentAccentID)}}
className={getClassName(account)}
tabIndex={0}
Expand All @@ -81,7 +106,7 @@ const Sidebar = ({
handleSwitchAccount(accountIndex);
}
}}
onContextMenu={preventFocus(event => {
onContextMenu={preventFocus((event: React.MouseEvent<Element, MouseEvent>) => {
const isAtLeastAdmin =
account.teamRole === 'z.team.TeamRole.ROLE.OWNER' || account.teamRole === 'z.team.TeamRole.ROLE.ADMIN';
const {centerX, centerY} = centerOfEventTarget(event);
Expand All @@ -101,6 +126,7 @@ const Sidebar = ({
</div>
);
})}

{!isAddingAccount && !hasReachedLimitOfAccounts && (
<AddAccountTrigger id="account" onClick={connected.addAccountWithSession} />
)}
Expand Down
Loading

0 comments on commit 8e646eb

Please sign in to comment.