Skip to content

Commit

Permalink
enh(icons): improve icon quality and extration of files
Browse files Browse the repository at this point in the history
  • Loading branch information
eythaann committed Sep 6, 2024
1 parent e23b7c2 commit a368126
Show file tree
Hide file tree
Showing 28 changed files with 540 additions and 436 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ lazy_static = "1.4.0"
parking_lot = "0.12.1"
log = "0.4"
uuid = "1.8.0"
image = "0.25.0"
image = { version = "0.25.1", features = ["ico"] }
widestring = "1.0.2"
itertools = "0.12.1"
clap = { version = "4.5.4", features = ["derive", "string"] }
Expand Down Expand Up @@ -97,6 +97,7 @@ features = [
"Wdk_System_SystemServices", # required to get system info (PROCESS_EXTENDED_BASIC_INFORMATION)
"Win32_System_Power", # required for power management (battery - AC)
"Win32_System_Shutdown", # required for power management (shutdown)
"Win32_Storage_FileSystem", # PKEYS and Devices/Storage/etc
"Win32_Storage_EnhancedStorage", # PKEYS and Devices/Storage/etc
"Win32_Storage_Packaging_Appx", # UWP apps
"Win32_Media_Audio_Endpoints", # required for audio module
Expand Down
6 changes: 6 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
- make the dock/taskbar solid when hide mode is `never`.
- add app launcher (rofi for windows).

### enhancements
- improve quality icons from all app/files items.

### fix
- missing icons for files with a different extension than `exe`.

## [1.10.4]
### enhancements
- clean weg items on load to remove duped items and apps/files that don't exist.
Expand Down
3 changes: 2 additions & 1 deletion lib/src/handlers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { listen } from '@tauri-apps/api/event';

export enum InvokeHandler {
GetSystemColors = 'get_system_colors',
StateGetSettings = 'state_get_settings',
GetSettings = 'state_get_settings',
GetLauncherApps = 'launcher_get_apps',
}

export enum EventHandler {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/state/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export enum SeelenWegSide {
}

export class Settings extends Obtainable<Settings>(
InvokeHandler.StateGetSettings,
InvokeHandler.GetSettings,
EventHandler.Settings,
) {
fancyToolbar: FancyToolbarSettings = new FancyToolbarSettings();
Expand Down
3 changes: 2 additions & 1 deletion src/apps/seelen_rofi/App.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useDarkMode } from '../shared/styles';
import { Selectors } from './reducer';
import { ConfigProvider, theme } from 'antd';
import { useSelector } from 'react-redux';

import { Launcher } from './modules/launcher/infra';

import { Selectors } from './modules/shared/store/app';

export function App() {
const isDarkMode = useDarkMode();
const colors = useSelector(Selectors.colors);
Expand Down
3 changes: 2 additions & 1 deletion src/apps/seelen_rofi/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { getRootContainer } from '../shared';
import { wrapConsole } from '../shared/ConsoleWrapper';
import { App } from './App';
import { registerDocumentEvents } from './events';
import { initStore, store } from './store';
import { createRoot } from 'react-dom/client';
import { Provider } from 'react-redux';
import { declareDocumentAsLayeredHitbox } from 'seelen-core';

import { initStore, store } from './modules/shared/store/infra';

import './styles/reset.css';
import './styles/colors.css';

Expand Down
60 changes: 40 additions & 20 deletions src/apps/seelen_rofi/modules/launcher/infra.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,58 @@
import { invoke } from '@tauri-apps/api/core';
import { convertFileSrc, invoke } from '@tauri-apps/api/core';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { AutoComplete, Checkbox, Select, Tooltip } from 'antd';
import { AutoComplete, Checkbox, Dropdown, Menu, Select, Tooltip } from 'antd';
import { motion } from 'framer-motion';
import { KeyboardEventHandler, useRef, useState } from 'react';
import { useSelector } from 'react-redux';
import { useWindowFocusChange } from 'seelen-core';

import { Selectors } from '../shared/store/app';
import { OverflowTooltip } from 'src/apps/shared/components/OverflowTooltip';

interface Item {
label: string;
icon: string;
path: string;
executionPath: string;
}

export function Item(props: { item: Item }) {
const {
item: { label, icon, path },
item: { label, icon, executionPath, path },
} = props;

function onClick() {
invoke('open_file', { path });
invoke('open_file', { executionPath });
getCurrentWindow().hide();
}

let shortPath = executionPath.slice(executionPath.indexOf('\\Programs\\') + 10);
return (
<button className="launcher-item" onClick={onClick}>
<img className="launcher-item-icon" src={icon} />
<span className="launcher-item-label">{label}</span>
<span className="launcher-item-path">({path})</span>
</button>
<Dropdown
trigger={['contextMenu']}
dropdownRender={() => (
<Menu
items={[
{
label: 'Open File Location',
key: 'open',
onClick() {
invoke('select_file_on_explorer', { path });
},
},
]}
/>
)}
>
<button className="launcher-item" onClick={onClick}>
<img className="launcher-item-icon" src={convertFileSrc(icon)} />
<OverflowTooltip className="launcher-item-label" text={label} />
<OverflowTooltip className="launcher-item-path" text={shortPath} />
</button>
</Dropdown>
);
}

const mockedItems = Array.from({ length: 40 }, (_, i) => ({
label: `Item ${i}`,
icon: 'https://via.placeholder.com/256',
path: `item-${i}`,
}));

enum Runner {
Run = 'run',
Command = 'command',
Expand All @@ -51,11 +69,16 @@ export function Launcher() {
const [command, setCommand] = useState('');
const [runner, setRunner] = useState(Runner.Run);

const apps = useSelector(Selectors.apps);

const input = useRef<HTMLInputElement>(null);

useWindowFocusChange((focused) => {
if (focused) {
input.current?.focus();
} else {
setCommand('');
getCurrentWindow().hide();
}
});

Expand All @@ -71,9 +94,7 @@ export function Launcher() {
}))
.filter((option) => option.label.toLowerCase().includes(command.toLowerCase()));

const items = mockedItems.filter((item) =>
item.label.toLowerCase().includes(command.toLowerCase()),
);
const items = apps.filter((item) => item.label.toLowerCase().includes(command.toLowerCase()));

const onKeyDown: KeyboardEventHandler<HTMLInputElement> = (e) => {
if (e.ctrlKey && e.key === 'Tab') {
Expand All @@ -94,7 +115,6 @@ export function Launcher() {
if (!showHistory || matchingHistory.length === 0) {
if (e.key === 'Enter') {
invoke('open_file', { path: command });
setCommand('');
getCurrentWindow().hide();
return;
}
Expand Down Expand Up @@ -135,7 +155,7 @@ export function Launcher() {
</div>
<div className="launcher-body">
{items.map((item) => (
<Item key={item.path} item={item} />
<Item key={item.executionPath} item={item} />
))}
</div>
<div className="launcher-footer">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { IRootState } from '../../shared.interfaces';
import { StateBuilder } from '../shared/StateBuilder';
import { StateBuilder } from '../../../../shared/StateBuilder';
import { createSlice } from '@reduxjs/toolkit';
import { UIColors } from 'seelen-core';

interface RootState extends IRootState<{}> {}
import { LauncherState } from './domain';

const initialState: RootState = {
const initialState: LauncherState = {
colors: UIColors.default(),
apps: [],
settings: {},
};

Expand Down
5 changes: 5 additions & 0 deletions src/apps/seelen_rofi/modules/shared/store/domain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { IRootState } from 'src/shared.interfaces';

export interface LauncherState extends IRootState<{}> {
apps: any[];
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { StartThemingTool } from '../shared/styles';
import { RootActions, RootSlice } from './reducer';
import { StartThemingTool } from '../../../../shared/styles';
import { configureStore } from '@reduxjs/toolkit';
import { UIColors } from 'seelen-core';
import { invoke } from '@tauri-apps/api/core';
import { InvokeHandler, UIColors } from 'seelen-core';

import { RootActions, RootSlice } from './app';

export const store = configureStore({
reducer: RootSlice.reducer,
Expand All @@ -17,6 +19,8 @@ async function initUIColors() {
}

export async function initStore() {
store.dispatch(RootActions.setApps(await invoke(InvokeHandler.GetLauncherApps)));

await initUIColors();
await StartThemingTool();
}
51 changes: 23 additions & 28 deletions src/apps/seelenweg/modules/item/app/PinnedApp.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
import { SavedPinnedApp } from '../../../../shared/schemas/SeelenWegItems';
import { convertFileSrc, invoke } from '@tauri-apps/api/core';

import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra';

import { SpecialItemType, SwPinnedApp } from '../../shared/store/domain';

export class SwPinnedAppUtils {
static async fromSaved(item: SavedPinnedApp): Promise<SwPinnedApp> {
let icon = '';
let icon_path = await invoke<string | null>('get_icon', { path: item.exe }) || LAZY_CONSTANTS.MISSING_ICON_PATH;

try {
icon = await getImageBase64FromUrl(convertFileSrc(icon_path));
} catch {
icon = convertFileSrc(icon_path);
}

return {
type: SpecialItemType.PinnedApp,
icon,
exe: item.exe,
execution_path: item.execution_path,
title: '',
opens: [],
};
}
}
import { SavedPinnedApp } from '../../../../shared/schemas/SeelenWegItems';
import { convertFileSrc, invoke } from '@tauri-apps/api/core';

import { LAZY_CONSTANTS } from '../../shared/utils/infra';

import { SpecialItemType, SwPinnedApp } from '../../shared/store/domain';

export class SwPinnedAppUtils {
static async fromSaved(item: SavedPinnedApp): Promise<SwPinnedApp> {
let icon_path =
(await invoke<string | null>('get_icon', { path: item.exe })) ||
LAZY_CONSTANTS.MISSING_ICON_PATH;

return {
type: SpecialItemType.PinnedApp,
icon: convertFileSrc(icon_path),
exe: item.exe,
execution_path: item.execution_path,
title: '',
opens: [],
};
}
}
59 changes: 27 additions & 32 deletions src/apps/seelenweg/modules/item/app/TemporalApp.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
import { convertFileSrc } from '@tauri-apps/api/core';

import { fs } from '../../../../settings/modules/shared/tauri/infra';
import { getImageBase64FromUrl, LAZY_CONSTANTS } from '../../shared/utils/infra';

import { AppFromBackground, SpecialItemType, SwTemporalApp } from '../../shared/store/domain';

export class SwTemporalAppUtils {
static async clean(item: AppFromBackground): Promise<AppFromBackground> {
if (!(await fs.exists(item.icon_path))) {
item.icon_path = LAZY_CONSTANTS.MISSING_ICON_PATH;
}

try {
item.icon = await getImageBase64FromUrl(convertFileSrc(item.icon_path));
} catch {
item.icon = convertFileSrc(item.icon_path);
}
return item;
}

static fromBackground(item: AppFromBackground): SwTemporalApp {
return {
type: SpecialItemType.TemporalApp,
icon: item.icon || '',
exe: item.exe,
execution_path: item.execution_path,
title: item.exe.split('\\').at(-1) || 'Unknown',
opens: [item.hwnd],
};
}
}
import { convertFileSrc } from '@tauri-apps/api/core';

import { fs } from '../../../../settings/modules/shared/tauri/infra';
import { LAZY_CONSTANTS } from '../../shared/utils/infra';

import { AppFromBackground, SpecialItemType, SwTemporalApp } from '../../shared/store/domain';

export class SwTemporalAppUtils {
static async clean(item: AppFromBackground): Promise<AppFromBackground> {
if (!(await fs.exists(item.icon_path))) {
item.icon_path = LAZY_CONSTANTS.MISSING_ICON_PATH;
}
item.icon = convertFileSrc(item.icon_path);
return item;
}

static fromBackground(item: AppFromBackground): SwTemporalApp {
return {
type: SpecialItemType.TemporalApp,
icon: item.icon || '',
exe: item.exe,
execution_path: item.execution_path,
title: item.exe.split('\\').at(-1) || 'Unknown',
opens: [item.hwnd],
};
}
}
Loading

0 comments on commit a368126

Please sign in to comment.