Skip to content

Commit

Permalink
refactor(weg): weg implementation part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
eythaann committed Dec 24, 2024
1 parent 5024ac7 commit e982b06
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 337 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### refactor
- move dock state to the background.
- remove pin sub-menu on dock.

### fix
- slu-service was being closed on exit code 1.
Expand Down
140 changes: 1 addition & 139 deletions src/apps/seelenweg/modules/bar/menu.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { SeelenCommand } from '@seelen-ui/lib';
import { invoke } from '@tauri-apps/api/core';
import { Menu, MenuProps, Popover } from 'antd';
import { ItemType } from 'antd/es/menu/interface';
import { TFunction } from 'i18next';

import { BackgroundByLayersV2 } from '../../components/BackgroundByLayers/infra';
import { store } from '../shared/store/infra';
import { dialog } from 'src/apps/settings/modules/shared/tauri/infra';

import { isPinnedApp, isTemporalApp, RootActions } from '../shared/store/app';

import { AppsSides, PinnedWegItem, TemporalWegItem } from '../shared/store/domain';
import { RootActions } from '../shared/store/app';

import { Icon } from '../../../shared/components/Icon';
import { savePinnedItems } from '../shared/store/storeApi';

export function getSeelenWegMenu(t: TFunction): ItemType[] {
return [
Expand Down Expand Up @@ -89,136 +84,3 @@ export function getSeelenWegMenu(t: TFunction): ItemType[] {
},
];
}

export function getMenuForItem(
t: TFunction,
item: PinnedWegItem | TemporalWegItem,
devTools: boolean,
): ItemType[] {
const isPinned = isPinnedApp(item);

const pin = (side: AppsSides) => {
if (isTemporalApp(item)) {
store.dispatch(RootActions.pinApp({ app: item, side }));
savePinnedItems();
}
};

const menu: MenuProps['items'] = [];

if (isPinned) {
menu.push({
label: t('app_menu.unpin'),
key: 'weg_unpin_app',
icon: <Icon iconName="RiUnpinLine" />,
onClick: () => {
store.dispatch(RootActions.unPinApp(item));
savePinnedItems();
},
});
} else {
menu.push({
key: 'weg_pin_app',
icon: <Icon iconName="RiPushpinLine" />,
label: (
<Popover
trigger={['hover']}
placement="rightBottom"
arrow={false}
content={
<BackgroundByLayersV2 className="weg-context-menu-container" prefix="menu">
<Menu
className="weg-context-menu"
items={[
{
key: 'weg_pin_app_left',
label: t('app_menu.pin_to_left'),
icon: <Icon iconName="RxPinLeft" />,
onClick: () => pin(AppsSides.Left),
},
{
key: 'weg_pin_app_center',
label: t('app_menu.pin_to_center'),
icon: <Icon iconName="RiPushpinLine" />,
onClick: () => pin(AppsSides.Center),
},
{
key: 'weg_pin_app_right',
label: t('app_menu.pin_to_right'),
icon: <Icon iconName="RxPinRight" />,
onClick: () => pin(AppsSides.Right),
},
]}
/>
</BackgroundByLayersV2>
}
>
<div style={{ width: '100%', height: '100%', margin: '-10px', padding: '10px' }}>
{t('app_menu.pin')}
</div>
</Popover>
),
});
}

menu.push(
{
type: 'divider',
},
{
key: 'weg_select_file_on_explorer',
label: t('app_menu.open_file_location'),
icon: <Icon iconName="MdOutlineMyLocation" />,
onClick: () => invoke(SeelenCommand.SelectFileOnExplorer, { path: item.path }),
},
{
key: 'weg_runas',
label: t('app_menu.run_as'),
icon: <Icon iconName="MdOutlineAdminPanelSettings" />,
onClick: () => invoke(SeelenCommand.RunAsAdmin, { path: item.execution_command }),
},
);

if (!item.windows.length) {
return menu;
}

if (devTools) {
menu.push({
key: 'weg_copy_hwnd',
label: t('app_menu.copy_handles'),
icon: <Icon iconName="AiOutlineCopy" />,
onClick: () =>
navigator.clipboard.writeText(JSON.stringify(item.windows.map((window) => window.handle.toString(16)))),
});
}

menu.push({
key: 'weg_close_app',
label: item.windows.length > 1 ? t('app_menu.close_multiple') : t('app_menu.close'),
icon: <Icon iconName="BiWindowClose" />,
onClick() {
item.windows.forEach((window) => {
invoke(SeelenCommand.WegCloseApp, { hwnd: window.handle });
});
},
danger: true,
});

if (devTools) {
menu.push({
key: 'weg_kill_app',
label: item.windows.length > 1 ? t('app_menu.kill_multiple') : t('app_menu.kill'),
icon: <Icon iconName="MdOutlineDangerous" size={18} />,
onClick() {
item.windows.forEach((window) => {
// todo replace by enum
invoke(SeelenCommand.WegKillApp, { hwnd: window.handle });
});
},
danger: true,
});
}

return menu;
}
9 changes: 4 additions & 5 deletions src/apps/seelenweg/modules/item/infra/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { RootActions } from '../../shared/store/app';
import { SwItem } from '../../shared/store/domain';

import { Icon } from '../../../../shared/components/Icon';
import { savePinnedItems } from '../../shared/store/storeApi';

export function getMenuForItem(t: TFunction, item: SwItem): ItemType[] {
if (item.type === WegItemType.Media) {
Expand All @@ -20,7 +19,7 @@ export function getMenuForItem(t: TFunction, item: SwItem): ItemType[] {
label: t('media_menu.remove'),
icon: <Icon iconName="CgExtensionRemove" />,
onClick() {
store.dispatch(RootActions.removeMediaModule());
store.dispatch(RootActions.remove(item.id));
},
},
];
Expand All @@ -33,21 +32,21 @@ export function getMenuForItem(t: TFunction, item: SwItem): ItemType[] {
label: t('start_menu.remove'),
icon: <Icon iconName="CgExtensionRemove" />,
onClick() {
store.dispatch(RootActions.removeStartModule());
store.dispatch(RootActions.remove(item.id));
},
},
];
}

// File or Folder pinned items
if (item.type === WegItemType.Pinned) {
return [
{
key: 'remove',
label: t('app_menu.unpin'),
icon: <Icon iconName="RiUnpinLine" />,
onClick() {
store.dispatch(RootActions.unpin(item));
savePinnedItems();
store.dispatch(RootActions.remove(item.id));
},
},
{
Expand Down
52 changes: 31 additions & 21 deletions src/apps/seelenweg/modules/item/infra/UserApplication.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
import { SeelenCommand, SeelenWegSide } from '@seelen-ui/lib';
import { invoke } from '@tauri-apps/api/core';
import { convertFileSrc, invoke } from '@tauri-apps/api/core';
import { Popover } from 'antd';
import moment from 'moment';
import { memo, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';

import { BackgroundByLayersV2 } from '../../../components/BackgroundByLayers/infra';
import { updatePreviews } from '../../shared/utils/infra';
import { LAZY_CONSTANTS, updatePreviews } from '../../shared/utils/infra';

import { Selectors } from '../../shared/store/app';
import { useWindowFocusChange } from 'src/apps/shared/hooks';
import { useIcon, useWindowFocusChange } from 'src/apps/shared/hooks';

import {
PinnedWegItem,
RootState,
TemporalWegItem,
} from '../../shared/store/domain';
import { PinnedWegItem, RootState, TemporalWegItem } from '../../shared/store/domain';

import { cx } from '../../../../shared/styles';
import { WithContextMenu } from '../../../components/WithContextMenu';
import { getMenuForItem } from '../../bar/menu';
import { DraggableItem } from './DraggableItem';
import { getUserApplicationContextMenu } from './UserApplicationContextMenu';
import { UserApplicationPreview } from './UserApplicationPreview';

interface Props {
Expand All @@ -32,7 +28,8 @@ interface Props {

export const UserApplication = memo(({ item, onAssociatedViewOpenChanged }: Props) => {
const isFocused = useSelector(
(state: RootState) => state.focusedApp && item.windows.some((w) => w.handle === state.focusedApp!.hwnd),
(state: RootState) =>
state.focusedApp && item.windows.some((w) => w.handle === state.focusedApp!.hwnd),
);

const [openPreview, setOpenPreview] = useState(false);
Expand All @@ -42,6 +39,9 @@ export const UserApplication = memo(({ item, onAssociatedViewOpenChanged }: Prop
const devTools = useSelector(Selectors.devTools);
const settings = useSelector(Selectors.settings);

const iconSrc =
useIcon(item.execution_command) || convertFileSrc(LAZY_CONSTANTS.MISSING_ICON_PATH);

const { t } = useTranslation();
const calculatePlacement = (position: any) => {
switch (position) {
Expand Down Expand Up @@ -90,23 +90,33 @@ export const UserApplication = memo(({ item, onAssociatedViewOpenChanged }: Prop
}, [openPreview || openContextMenu]);

return (
<DraggableItem item={item} className={cx({ 'associated-view-open': openPreview || openContextMenu })}>
<WithContextMenu items={getMenuForItem(t, item, devTools) || []} onOpenChange={(isOpen) => {
setOpenContextMenu(isOpen);
if (openPreview && isOpen) {
setOpenPreview(false);
}
}}>
<DraggableItem
item={item}
className={cx({ 'associated-view-open': openPreview || openContextMenu })}
>
<WithContextMenu
items={getUserApplicationContextMenu(t, item, devTools) || []}
onOpenChange={(isOpen) => {
setOpenContextMenu(isOpen);
if (openPreview && isOpen) {
setOpenPreview(false);
}
}}
>
<Popover
open={openPreview}
mouseEnterDelay={0.4}
placement={calculatePlacement(settings.position)}
onOpenChange={(open) => setOpenPreview(open && !openContextMenu && !!item.windows.length && moment(new Date()) > blockUntil)}
onOpenChange={(open) =>
setOpenPreview(
open && !openContextMenu && !!item.windows.length && moment(new Date()) > blockUntil,
)
}
trigger="hover"
arrow={false}
content={
<BackgroundByLayersV2
className={ cx('weg-item-preview-container', settings.position.toLowerCase()) }
className={cx('weg-item-preview-container', settings.position.toLowerCase())}
onMouseMoveCapture={(e) => e.stopPropagation()}
onContextMenu={(e) => {
e.stopPropagation();
Expand All @@ -116,7 +126,7 @@ export const UserApplication = memo(({ item, onAssociatedViewOpenChanged }: Prop
>
<div className="weg-item-preview-scrollbar">
{item.windows.map((window) => (
<UserApplicationPreview key={window.handle} hwnd={window.handle} />
<UserApplicationPreview key={window.handle} title={window.title} hwnd={window.handle} />
))}
</div>
</BackgroundByLayersV2>
Expand Down Expand Up @@ -145,7 +155,7 @@ export const UserApplication = memo(({ item, onAssociatedViewOpenChanged }: Prop
onContextMenu={(e) => e.stopPropagation()}
>
<BackgroundByLayersV2 prefix="item" />
<img className="weg-item-icon" src={'item.icon'} draggable={false} />
<img className="weg-item-icon" src={iconSrc} draggable={false} />
<div
className={cx('weg-item-open-sign', {
'weg-item-open-sign-active': !!item.windows.length,
Expand Down
Loading

0 comments on commit e982b06

Please sign in to comment.