Skip to content

Commit

Permalink
🎉 Add new open-file item type
Browse files Browse the repository at this point in the history
  • Loading branch information
Schneegans committed Jan 25, 2025
1 parent 2979d64 commit a86bb30
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/common/item-action-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IMenuItem } from './index';
import { Backend, WMInfo } from '../main/backends/backend';

import { CommandItemAction } from './item-types/command-item-action';
import { FileItemAction } from './item-types/file-item-action';
import { HotkeyItemAction } from './item-types/hotkey-item-action';
import { MacroItemAction } from './item-types/macro-item-action';
import { TextItemAction } from './item-types/text-item-action';
Expand Down Expand Up @@ -68,6 +69,7 @@ export class ItemActionRegistry {
*/
private constructor() {
this.actions.set('command', new CommandItemAction());
this.actions.set('file', new FileItemAction());
this.actions.set('hotkey', new HotkeyItemAction());
this.actions.set('macro', new MacroItemAction());
this.actions.set('text', new TextItemAction());
Expand Down
2 changes: 2 additions & 0 deletions src/common/item-config-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import { IMenuItem } from '.';
import { SubmenuItemConfig } from './item-types/submenu-item-config';
import { CommandItemConfig } from './item-types/command-item-config';
import { FileItemConfig } from './item-types/file-item-config';
import { HotkeyItemConfig } from './item-types/hotkey-item-config';
import { MacroItemConfig } from './item-types/macro-item-config';
import { TextItemConfig } from './item-types/text-item-config';
Expand Down Expand Up @@ -57,6 +58,7 @@ export class ItemConfigRegistry {
*/
private constructor() {
this.configs.set('command', new CommandItemConfig());
this.configs.set('file', new FileItemConfig());
this.configs.set('hotkey', new HotkeyItemConfig());
this.configs.set('macro', new MacroItemConfig());
this.configs.set('submenu', new SubmenuItemConfig());
Expand Down
2 changes: 2 additions & 0 deletions src/common/item-type-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import { IMenuItem } from './index';

import { CommandItemType } from './item-types/command-item-type';
import { FileItemType } from './item-types/file-item-type';
import { HotkeyItemType } from './item-types/hotkey-item-type';
import { MacroItemType } from './item-types/macro-item-type';
import { SubmenuItemType } from './item-types/submenu-item-type';
Expand Down Expand Up @@ -72,6 +73,7 @@ export class ItemTypeRegistry {
*/
private constructor() {
this.types.set('command', new CommandItemType());
this.types.set('file', new FileItemType());
this.types.set('hotkey', new HotkeyItemType());
this.types.set('macro', new MacroItemType());
this.types.set('submenu', new SubmenuItemType());
Expand Down
38 changes: 38 additions & 0 deletions src/common/item-types/file-item-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//////////////////////////////////////////////////////////////////////////////////////////
// _ _ ____ _ _ ___ ____ //
// |_/ |__| |\ | | \ | | This file belongs to Kando, the cross-platform //
// | \_ | | | \| |__/ |__| pie menu. Read more on github.com/menu/kando //
// //
//////////////////////////////////////////////////////////////////////////////////////////

// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
// SPDX-License-Identifier: MIT

import { IMenuItem } from '../index';
import { IItemAction } from '../item-action-registry';
import { DeepReadonly } from '../../main/settings';
import { IItemData } from './file-item-type';
import { shell } from 'electron';

/** This action opens files with the default application. */
export class FileItemAction implements IItemAction {
/**
* Files are opened immediately.
*
* @returns False
*/
delayedExecution() {
return false;
}

/**
* Opens a file with the default application.
*
* @param item The item for which the action should be executed.
* @returns A promise which resolves when the file has been opened.
*/
async execute(item: DeepReadonly<IMenuItem>) {
await shell.openPath((item.data as IItemData).path);
return;
}
}
48 changes: 48 additions & 0 deletions src/common/item-types/file-item-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//////////////////////////////////////////////////////////////////////////////////////////
// _ _ ____ _ _ ___ ____ //
// |_/ |__| |\ | | \ | | This file belongs to Kando, the cross-platform //
// | \_ | | | \| |__/ |__| pie menu. Read more on github.com/menu/kando //
// //
//////////////////////////////////////////////////////////////////////////////////////////

// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
// SPDX-License-Identifier: MIT

import i18next from 'i18next';

import { IMenuItem } from '..';
import { IItemConfig } from '../item-config-registry';
import { IItemData } from './file-item-type';
import * as utils from './utils';

/** This class provides the configuration widgets for file items. */
export class FileItemConfig implements IItemConfig {
/** @inheritdoc */
public getTipOfTheDay(): string {
const tips = [i18next.t('items.file.tip-1')];

return tips[Math.floor(Math.random() * tips.length)];
}

/** @inheritdoc */
public getConfigWidget(item: IMenuItem): DocumentFragment | null {
const fragment = utils.renderTemplate(
require('../../renderer/editor/properties/templates/text-option.hbs'),
{
placeholder: i18next.t('items.common.not-configured'),
label: i18next.t('items.file.file'),
}
);

// Get the input element and set the current value.
const input = fragment.querySelector('input');
input.value = (item.data as IItemData).path || '';

// Listen for changes and update the item.
input.addEventListener('input', () => {
(item.data as IItemData).path = input.value;
});

return fragment;
}
}
55 changes: 55 additions & 0 deletions src/common/item-types/file-item-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//////////////////////////////////////////////////////////////////////////////////////////
// _ _ ____ _ _ ___ ____ //
// |_/ |__| |\ | | \ | | This file belongs to Kando, the cross-platform //
// | \_ | | | \| |__/ |__| pie menu. Read more on github.com/menu/kando //
// //
//////////////////////////////////////////////////////////////////////////////////////////

// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
// SPDX-License-Identifier: MIT

import i18next from 'i18next';

import { IMenuItem } from '../index';
import { IItemType } from '../item-type-registry';

/**
* For this type of menu items, the user can configure a path that will be opened when the
* item is clicked.
*/
export interface IItemData {
path: string;
}

/** This class provides meta information for menu items that open a file. */
export class FileItemType implements IItemType {
get hasChildren(): boolean {
return false;
}

get defaultName(): string {
return i18next.t('items.file.name');
}

get defaultIcon(): string {
return 'folder_open';
}

get defaultIconTheme(): string {
return 'material-symbols-rounded';
}

get defaultData(): IItemData {
return {
path: '',
};
}

get genericDescription(): string {
return i18next.t('items.file.description');
}

getDescription(item: IMenuItem): string {
return (item.data as IItemData).path || i18next.t('items.common.not-configured');
}
}

0 comments on commit a86bb30

Please sign in to comment.